第九章 查找

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

9.4.3 冲突处理方法
• 1.开放地址法 • 开放定址法解决冲突的基本思想为:当冲突发生 时,使用某种探查(或称探测)技术在散列表中 产生一个探查(测)序列,沿此序列逐个存储单 元地查找,直到找到给定的关键字、或者碰到一 个开放的地址(即该地址单元为空)为止。可用公 式表示如下: • Hi(key)=(H (key)+di) mod m (i=1,2, …,m)
9.4 散列查找
• 9.4.1 基本概念 • 散列表是利用散列存储方法建立的一种查 找表。散列存储是通过对记录的关键字进 行某种计算来确定该记录的存储位置。每 个关键字和结构中唯一的存储位置相对应, 这样查找时只需对记录的关键字进行某种 运算就能确定记录在表中的位置。因此散 列法的平均比较次数和表中所含记录的个 数无关。
• 4.平均查找长度 • 对于不同的数据结构,有不同的查找方法, 也有不同的查找效率。而在查找中,要衡 量一种查找算法的优劣,主要是看要查找 的值与关键字的比较次数。因此,通常把 查找过程中对关键字的比较次数作为衡量 一个查找算法效率优劣的标准,并称平均 比较次数为平均查找长度。其计算公式定 n 义为: ASL P C
• • • • • •
【算法9.6】 二叉排序树中插入结点的递归算法。 NODE * insert(NODE *p,NODE *root) //在根指针为root的二叉排序树中插入结点p { if(root==NULL) return(p) ; if(p->data<root->data) root->lchild=insert(p,root ->lchild); • else root->rchild=insert(p,root->rchild); • return root; • }

i 1
i
i
9.2线性表的查找
• 9.2.1 顺序查找 • 顺序查找是一种最简单也是最基本的查找 方法,它的基本思想是:从表的一端开始, 顺序扫描线性表,依次将扫描到的结点关 键字和给定值K进行比较,若当前扫描到的 结点关键字与K相等,则查找成功;若扫描 结束后,仍未找到关键字等于K的结点,则 查找失败 。
• 2. 二叉排序树的查找 • 根据二叉排序树的性质,在二叉排序树中进行查 找,将要查找的值从树根开始比较,若与根的关 键值相等,则查找成功;若比根的关键值小,则 到左子树找;若比根的关键值大,则到右子树找; 直到查找成功或查找子树空(查找失败)。若查 找成功,则返回查找到结点的地址;若查找失败, 则返回空指针。这里使用二叉链表作为二叉树的 存储结构。
• 3.除留余数法 • 除留余数法不要求事先知道全部关键字。 其作法为:选择一个不大于散列表长度的 正整数p,以关键字除以p所得的余数作为 散列地址,即令散列函数F为: • F(key)=key mod p
• 4.平均取中法 • 这是一种较为常用的构造散列函数的方法, 这个方法是先取关键字的平方,然后根据 可使用空间的大小,选取平方数的中间几 位为散列地址。散列函数为: • F(key)=“key2的中间几位”
• 【例9.4】 设线性表的关键字集合key={32,13,49,55,22,39, 20},选取散列函数为“除留取余法H(key)=key% 7”,解决冲突方 法为“二次探查法”,构建散列表及求出该表的平均查找长度ASL。 • 解:依题意,采用的散列函数为:H(key)=key % 7 • 所以有: • H(32)=32 % 7=4 H(13)=13 % 7=6 • H(49)=49 % 7=0 H(55)=55 % 7=6(冲突) • H(55)=(6+1)% 8=7 H(22)=22 % 7=1 • H(39)=39 % 7=4(冲突) H(39)=(4+1) % 8=5 • H(20)=20 % 7=6(冲突) • H(20)=(6+1) % 8=7(仍冲突) • H(20)=(6-1) % 8=5(仍冲突) • H(20)=(6+4) % 8=2
• 【算法9.4】 二叉排序树的查找递归算法。 • NODE *search(int x, NODE *root) • //在根指针为 root 的二叉排序树中找键值为x的 结点的地址 • { if ((root ==NULL)||(root->data==x)) return(root ); • if (root->data<x) return(search( x,root- >rchild )); • else return(search( x, root->lchild )); • }
• • • • • • • •
顺序查找的线性表结构定义如下: #define MAXITEM 100 typedef struct { keytype key; DataType data; } NodeType; typedef NodeType SeqList[MAXITEM];
• • • • • • • • •
9.3 树上的查找
• 1. 二叉排序树的定义 • 二叉排序树又称为二叉查找树,它是一 种特殊结构的二叉树,其定义为:二叉 排序树或者是一棵空树,或者是具有如 下性质的二叉树: • 1) 它的左子树非空,则左子树上所有结 点的值均小于根结点的值; • 2) 它的右子树非空,则右子树上所有结 点的值均大于根结点的值; • 3) 左、右子树本身又各是一棵二叉排序 树。
第九章 查找
知识教学目标
• 查找的有关概念,平均查找长度 • 顺序查找、二分查找、分块查找、二叉排 序树上的查找 • 散列表的有关概念和查找运算
能力培养目标
• • • • 平均查找长度的概念和求解分析 顺序查找、二分查找和分块查找的运算 二叉排序树的查找、插入和删除操作 散列函数的构造方法及冲突的处理方法
• • • • • • • • • • • • • • • •
【算法9.2】 二分查找。 int BinSearch(SeqList r,Datatype k) { int low=1,high=n; while ( low<high ) { int mid=(low+high)/2; //取区间中点 if (r[mid].key==k) return mid; //查找成功 else if (r[mid].key>k) high=mid-1; else low=mid+1; } returb 0; }
• 2.链地址法 • 链地址法解决冲突的做法是:将所有关键 字为同义词的结点链接在同一个单链表中。 若选定的散列表长度为m,则可将散列表 定义为一个由m个头指针组成的指针数组T, 凡是散列地址为i的结点,均插入到T[i]为头 结点的单链表中。T中各分量的初值均应为 空。
9.4.4 散列查找及分析
9.5本章小结



• •

查找又称为检索、查询,是一种经常用到的运算,即从一批记录的集合中, 按照某个关键字查找特定的记录过程。 顺序查找对记录在表中存放的次序没有任何要求,查找的基本思想是从表的 一端开始,顺序将各个单元数据与给定值进行比较,直至找到与给定值相同 者,则查找成功,返回记录在表中的位置序号,若进行到表的另一端仍为找 到与之相等的数据,则查找失败,返回0。 二分查找比顺序查找速度快,但它要求表中数据有序,这是一个递归的过程, 每次以查找范围中间的元素与给定值进行比较,这样即使此次没有查找到, 也把下一步查找范围缩小了一半。 分块查找是在顺序表基础上建立一个索引表,查找时,首先用给定值在索引 表中查找,因为索引表是按关键字有序排列的,可以采用二分查找或顺序查 找以确定待查记录在哪一块中,然后在已确定的块中进行顺序查找。 散列查找是将每条记录的地址与该记录的关键字之间建立某种函数关系,可 直接由关键字查找到该记录,不仅查找速度快而且查找时间与记录条数无关。 不同关键字计算出相同地址的情况称为产生了冲突。处理冲突的方法这样有 开放地址法和链接表法。 在实际应用中,应根据各种查找方法的优缺点并结合具体情况来选择合适的 查找方法。
• 查找效率不受散列表长度的影响,查找效率是由 产生冲突的多少决定的,若冲突多则效率低,分 之,效率就高。具体影响冲突的因素由: • 1) 散列函数值的分布是否均匀。 • 2) 处理冲突的方法。 • 3) 散列表的装填因子(=表中的记录数/表的长度) 的大小,装填因子值大,则散列表满,发生冲突 的可能性就大。
【算法9.1】 顺序查找。 int SeqSearch( SeqList r,int k,int n) { i=1; while(r[i].key!=k && i<=n) i++; if(i>n) i=0; return (i); }
9.2.2 二分查找
• 二分查找又称为折半查找,它是一种效率 较高的查找方法。但二分查找有一定的条 件限制:要求线性表必须采用顺序存储结 构,且表中元素必须按关键字有序(升序 或降序均可)。
• 5.折叠法 • 折叠法是将关键字分割成位数相等的几部 分(最后一部分的位数可以不同),然后 对这几部分叠加求和,将所求的和舍去进 位后作为散列地址。
• 6.基数转换法 • 基数转换法就是首先将关键字看成另一种 进制的数再转换成原来进制的数,然后选 其中几位作为散列地址。
• 7.随机数法 • 选择一个随机函数random,以关键字在该 函数下的值作为它的散列地址,即: • F(key)= random (key) • 通常,当关键字长度不等时采用此法构造 散列函数较好。
9.2.3 分块查找
• 分块查找又称为索引顺序查找,它是一种性能介于顺序查 找和二分查找之间的查找方法。分块查找必须先建立索引 表,其索引表是一个有序表,故可以用二分查找来代替顺 序查找实现索引表的快速查找。 • 具体实现如下:将一个含有n个元素的主表分成m个子表, 但要求子表之间元素是按关键字有序排列的,而子表中元 素可以是无序的,然后建立索引表,索引表中索引域的值 用每个子表最大关键字代替,则可以按索引查找思想找到 表中的元素。
• 1.直接定址法 • 当关键字为整型数时,直接取关键字本身 或者关键字的某个线性函数值作为散列地 址,即F(key)=key或F(key)=a×key+b(a, b为常数),这种方法为直接定址法。
• 2.数字分析法 • 数字分析法又称为数字选择法,适用于下述 场合:事先知道所有可能出现的关键字, 并且关键字的位数比散列地址的位数多。 在这种情况下可以对关键字的各位进行分Байду номын сангаас析,选择分布较均匀的若干位组成散列地址。
9.4.2 散列函数的构造方法
• 散列函数的选择有两条标准:简单和均匀。 前者是指散列函数运算要尽可能简单;后 者指对于关键字集合中的任一关键字,散 列函数能以等概率将其映射到表空间的任 何一个位置上,也就是说,散列函数能将 子集K均匀地分别在表的地址集{0,1,…, m-1}上,以使冲突最小化。
9.1 基本概念
• • • • 1.查找表 由同一类型的数据元素(或记录)构成的集合称为查找表。 2.关键字 数据元素(或记录)中某个数据项的值,用它可以标识数据元素(或 记录)。若此关键字可以唯一地标识一个记录,则称此关键字为主关 键字;反之,把可以标识若干记录的关键字为次关键字。当数据元素 只有一个数据项时,其关键字即为该数据元素的值。 • 3.查找 • 查找是指在查找表中查找一个其关键字值等于某一给定值的数据元素 (或记录)。若表中存在这样一个数据元素(或记录),则称查找成 功;若表中不存在关键字值等于给定值的数据元素(或记录),则称 查找失败,此时查找的结果可能给出一个“空”记录或“空”指针。
相关文档
最新文档