数据结构——查找,顺序查找,折半查找

合集下载

查找排序

查找排序
Low指向待查元素 所在区间的下界 mid指向待查元素所在 区间的中间位臵 high指向待查元素所 在区间的上界
解:① 先设定3个辅助标志: low,high,mid, 显然有:mid= (low+high)/2 ② 运算步骤:
(1) low =1,high =11 ,故mid =6 ,待查范围是 [1,11]; (2) 若 S[mid] < key,说明 key[ mid+1,high] , 则令:low =mid+1;重算 mid= (low+high)/2;. (3) 若 S[mid] > key,说明key[low ,mid-1], 则令:high =mid–1;重算 mid ; (4)若 S[ mid ] = key,说明查找成功,元素序号=mid; 结束条件: (1)查找成功 : S[mid] = key (2)查找不成功 : high<low (意即区间长度小于0)
while(low<=high)
{ mid=(low+high)/2; if(ST[mid].key= = key) return (mid); /*查找成功*/
else if( key< ST[mid].key) high=mid-1; /*在前半区间继续查找*/ else } return (0); /*查找不成功*/
4 5 6 7
0
1
2
90
10
(c)
20
40
K=90
80
30
60
Hale Waihona Puke 25(return i=0 )
6
讨论:怎样衡量查找效率?
——用平均查找长度(ASL)衡量。
如何计算ASL?

c语言数据结构查找算法大全

c语言数据结构查找算法大全

printf("This number does not exist in this array.\n");
else
printf("a[%d]=%d\n",p,x);
}
9.2.2 折半查找(二分查找)
使用折半查找必须具备两个前提条件:
(1)要求查找表中的记录按关键字有序(设,从小到大有序) (2)只能适用于顺序存储结构
}
※折半查找算法性能分析:
在折半查找的过程中,每经过一次比较,查找范围都要缩小一半,所 以折半查找的最大查找长度为
MSL=[log2 n]+1
当n足够大时,可近似的表示为log2(n)。可见在查找速度上,折半查找 比顺序查找速度要快的多,这是它的主要优点。
结论:折半查找要求查找表按关键字有序,而排序是一 种很费时的运算;另外,折半查找要求表是顺序存储的,为 保持表的有序性,在进行插入和删除操作时,都必须移动大 量记录。因此,折半查找的高查找效率是以牺牲排序为代价 的,它特别适合于一经建立就很少移动、而又经常需要查找 的线性表。
查找技术分为: 1 静态查找表技术 顺序查找、折半查找、索引顺序查找 2 动态查找表技术 二叉查找树 3哈希表技术 哈希表技术
※查找算法的衡量指标
在查找一个记录时所做的主要操作是关键字的比较, 所以通常把查找过程中对关键字的平均比较次数作为衡量 一个查找算法效率优劣的标准,并称平均比较次数为平均 查找长度(Average Search Length)。平均查找长度的 定义为:
high2=N-1;
/*N为查找表的长度,high2为块在表中的末地址*/
else
high2=ID[low1+1].addr-1;

数据结构第九章--查找-习题及答案

数据结构第九章--查找-习题及答案

第九章查找一、选择题1•若查找每个记录的概率均等,则在具有n 个记录的连续顺序文件中采用顺序查找法查找一个记录,其平均查找长度ASL 为()。

A .(n-1)/2B.n/2C.(n+1)/2D.n 2. 下面关于二分查找的叙述正确的是()A. 表必须有序,表可以顺序方式存储,也可以链表方式存储C.表必须有序,而且只能从小到大排列B. 表必须有序且表中数据必须是整型,实型或字符型D.表必须有序,且表只 能以顺序方式存储3. 用二分(对半)查找表的元素的速度比用顺序法() A. 必然快B.必然慢C.相等D.不能确定4. 具有12个关键字的有序表,折半查找的平均查找长度()A.3.1B.4C.2.5D.55.当采用分块查找时,数据的组织方式为()A. 数据分成若干块,每块内数据有序B. 数据分成若干块,每块内数据不必有序,但块间必须有序,每块内最大(或最小)的数据组成索引块C. 数据分成若干块,每块内数据有序,每块内最大(或最小)的数据组成索引块D. 数据分成若干块,每块(除最后一块外)中数据个数需相同6. 二叉查找树的查找效率与二叉树的((1))有关,在((2))时其查找效率最低(1) :A.高度B.结点的多少C.树型D.结点的位置(2) :A.结点太多B.完全二叉树C.呈单枝树D.结点太复杂。

7. 对大小均为n 的有序表和无序表分别进行顺序查找,在等概率查找的情况下,对于查找失败,它们的平均查找长度是((1)),对于查找成功,他们的平均查找长度是((2))供选择的答案:A.相同的B.不同的9.分别以下列序列构造二叉排序树,与用其它三个序列所构造的结果不同的是()A .(100,80,90,60,120,110,130)B.(100,120,110,130,80,60,90) C. (100,60,80,90,120,110,130)D.(100,80,60,90,120,130,110)10. 在平衡二叉树中插入一个结点后造成了不平衡,设最低的不平衡结点为A,并已知A 的左孩子的平衡因子为0右孩子的平衡因子为1,则应作()型调整以使其平衡。

数据结构资料 ppt课件

数据结构资料  ppt课件

5 13 19 21 37 56 64
high 8 9 10 11 75 80 88 92
low
mid
high
1 2 3 4 5 6 7 8 9 10 11
5 13 19 21 37 56 64 75 80 88 92
low mid high
直至low>high时,查找失败
1 2 3 4 5 6 7 8 9 10 11 5 13 19 21 37 56 64 75 80 88 92
if (L.elem[i]==e) return i+1; return 0;}
改进:把待查关键字key存入表头(“哨兵”), 从后向前逐个比较,可免去查找过程中每一步都要 检测是否查找完毕,加快速度。
int Search_Seq( SSTable ST , KeyType key ){ //若成功返回其位置信息,否则返回0 ST.R[0].key =key;
for( i=ST.length; ST.R[ i ].key!=key; - - i ); //不用for(i=n; i>0; - -i) 或 for(i=1; i<=n; i++) return i;
}
顺序查找的性能分析
• 空间复杂度:一个辅助空间。 • 时间复杂度: 1) 查找成功时的平均查找长度
n个数存在一维数组A[1..n]中,在进行顺序查找时, 这n个数的排列有序或无序其平均查找长度ASL不同。
查找概率相等时,ASL相同; 查找概率不等时,如果从前向后查找,则按查找概率 由大到小排列的有序表其ASL要比无序表ASL小。
折半查找
123456 5 13 19 21 37 56
若k==R[mid].key,查找成功 若k<R[mid].key,则high=mid-1 若k>R[mid].key,则low=mid+1

考研数据结构复习

考研数据结构复习

路径长度:从一个结点到另一个结点路径上的分支数目;
结点的路径长度:从根到该结点的路径长度;
树的路径长度:树中所有叶子结点的路径长度之和;记为PL.
在结点数相同的条件下,完全二叉树是路径最短的二叉树
1
1
2
4
5
3 6
2
4
5
3 67
7
8
8
非完全二叉树 PL=10
完全二叉树PL=9
(路径最短的二叉树不唯一,不是完全二叉树,也可能路径长度最短)
a1
a2
ai-1 ai ai+1
an
头指针:存放线性链表中第一个结点的存储地址; 头结点:链表的第一个元素结点前的附加结点;
带头结点的线性链表:第一个元素结点前增加一个附加 结点的线性链表称为 带头结点的线性链表;
head是头指针
head
a1
a2
头结点
线性链表的每个结点中只有一个指针域
故也称为单链表
ai-
ai
ai+1
ann
1
空指针
例1、设一单向链表的头指针为head,链表的记录中 包含着整数类型的key域,试设计算法,将此链表的记录 按照key递增的次序进行就地排序。(不允许使用数组 做辅助存储)或将最小的数据移到链表的最前面。
例2、将单链表L1拆成二个链表,其中以L1为头的 链表保持原来向后的链接,另一个链表的头为L2, 其链接方向与L1相反,L1包含原链表的奇数序号的 节点,L2包含原链表的偶数序号的节点。
中序遍历序列: D,B,G,E,A,C,F
后序遍历(L R T)
若二叉树非空 (1)后序遍历左子树 (2)后序遍历右子树
(3)访问根结点

数据结构_查找原理及典型的查找算法

数据结构_查找原理及典型的查找算法
无法实现!因全部元素的定位只能从头指针head开 始,是一种非随机存取结构。
3.对非线性(树)结构如何进行折半查找? 可借助二叉排序树来查找(属动态查找表形式)。
9.1.2 有序表的查找
折半查找过程可以描述为一棵二叉树
折半查找的判定树 如:(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11)
总之:
二叉排序树既有类似于折半查找的特性,又采用了链 表存储,它是动态查找表的一种适宜表示。
一、二叉排序树
(3)构造过程: 例:输入序列{45,12,37,3,53,100,24}
45
12
53
3
37
100
24
一、二叉排序树
(2)非递归查找过程 BiTree SearchBST(BiTree T,KeyType key){
CH9 查找
查找的基本概念 9.1 静态查找表
9.1.1 顺序查找 9.1.2 有序表的查找 9.1.3 索引顺序表的查找
9.2 动态查找表
9.2.1 二叉排序树和平衡二叉树 9.2.2 B-和B+树
9.3 哈希表
查找的基本概念
1.查找表 2.查找
关键字 主关键字 次关键字
}
9.2.1 二叉排序树和平衡二叉树
一、二叉排序树 二、平衡二叉树
一、二叉排序树
1.定义、特点、构造过程
(1)定义 二叉排序树或者是一棵空树,或是具有下列性质的二叉树:
若左子树非空,则左子树上所有结点的值均小于它的 根结点的值。
若右子树非空,则右子树上所有结点的值均大于它的 根结点的值。
有序/无序表 有序表
顺序/链式存 储
顺序存储
分块查找 介于二者之间 表中元素逐段有序 顺序/链式存储

数据结构中的查找算法总结

数据结构中的查找算法总结

数据结构中的查找算法总结静态查找是数据集合稳定不需要添加删除元素的查找包括:1. 顺序查找2. 折半查找3. Fibonacci4. 分块查找静态查找可以⽤线性表结构组织数据,这样可以使⽤顺序查找算法,再对关键字进⾏排序就可以使⽤折半查找或斐波那契查找等算法提⾼查找效率,平均查找长度:折半查找最⼩,分块次之,顺序查找最⼤。

顺序查找对有序⽆序表均适⽤,折半查找适⽤于有序表,分块查找要求表中元素是块与块之间的记录按关键字有序动态查找是数据集合需要添加删除元素的查找包括: 1. ⼆叉排序树 2. 平衡⼆叉树 3. 散列表 顺序查找适合于存储结构为顺序存储或链接存储的线性表。

顺序查找属于⽆序查找算法。

从数据结构线形表的⼀端开始,顺序扫描,依次将扫描到的结点关键字与给定值k相⽐较,若相等则表⽰查找成功 查找成功时的平均查找长度为: ASL = 1/n(1+2+3+…+n) = (n+1)/2 ; 顺序查找的时间复杂度为O(n)。

元素必须是有序的,如果是⽆序的则要先进⾏排序操作。

⼆分查找即折半查找,属于有序查找算法。

⽤给定值value与中间结点mid的关键字⽐较,若相等则查找成功;若不相等,再根据value 与该中间结点关键字的⽐较结果确定下⼀步查找的⼦表 将数组的查找过程绘制成⼀棵⼆叉树排序树,如果查找的关键字不是中间记录的话,折半查找等于是把静态有序查找表分成了两棵⼦树,即查找结果只需要找其中的⼀半数据记录即可,等于⼯作量少了⼀半,然后继续折半查找,效率⾼。

根据⼆叉树的性质,具有n个结点的完全⼆叉树的深度为[log2n]+1。

尽管折半查找判定⼆叉树并不是完全⼆叉树,但同样相同的推导可以得出,最坏情况是查找到关键字或查找失败的次数为[log2n]+1,最好的情况是1次。

时间复杂度为O(log2n); 折半计算mid的公式 mid = (low+high)/2;if(a[mid]==value)return mid;if(a[mid]>value)high = mid-1;if(a[mid]<value)low = mid+1; 折半查找判定数中的结点都是查找成功的情况,将每个结点的空指针指向⼀个实际上不存在的结点——外结点,所有外界点都是查找不成功的情况,如图所⽰。

数据结构顺序查找与折半查找

数据结构顺序查找与折半查找

数据结构顺序查找与折半查找1,顺序查找顺序查找⼜称线性查找,它对顺序表和链表都适⽤。

(1)以下给出相关函数1 typedef struct{2 ElemType *elem; //元素存储空间地址,建表时按实际长度分配,0号单元留空3int TableLen; //表的长度4 }SSTable;5int Search_Seq(SSTable ST,ElemType key)6 {7 ST.elem[0]=key; //把要查找的关键字放在0号位置,称“哨兵”8for(int i=ST.TableLen;ST.elem!=key;i--) //从后往前找9 {10return i; //若表中不存在关键字为key的元素,将查找i=0时退出循环11 }12 }在上述算法中,将ST.elem[0]称为“哨兵”。

引⼊它的⽬的是使得Search_Seq内的循环不必判断数组是否会越界。

因为满⾜i=0时,循环⼀定会跳出。

除此之外,引⼊“哨兵”可以避免很多不必要的判断语句,从⽽提⾼算法的执⾏效率。

(2)算法效率分析当每个元素查找概率相同时,平均查找长度ASL=(n+1)/2, 查找不成功时,需要⽐较整个顺序表,所以⽐较次数时(n+1)次,从⽽顺序查找不成功的平均查找长度为(n+1)。

2.有序表的顺序查找(假设从⼩到⼤排列)有序表的顺序查找成功的平均查找长度与⼀般的线性表⼀样,即(n+1)/2.当查找失败时,待查找的元素为key,当查找第i个元素时,发现第i个元素的对应的关键字⼩于key,但第i+1个元素对应的关键字⼤于key,这时就可以返回查找失败的信息。

查找失败的平均查找长度为ASL=n/2+n/(n+1).3.折半查找前提:折半查找仅适⽤于有序的顺序表。

折半查找原理:将给定的key与中间元素⽐较,直到查到要找的元素。

以下是相关函数1int Binary_Search(SeqList L,ElemType key){2int low=0,high=L.TableLen-1,mid;//low指向表头,high指向表尾,mid中间值3while(low<=high)4 {5 mid=(low+high)/2;6if(L.elem[mid]==key) //中间值等于要查找元素7return mid;8else if(L.elem[mid]<key) //要查找元素在中间值右边9 low=mid+1;10else11 hign=mid-1; //要查找元素在中间值左边12 }13 }查找成功的时间复杂度为log2n,平均情况下⽐顺序查找效率⾼⼀些。

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

实验五查找的应用一、实验目的:1、掌握各种查找方法及适用场合,并能在解决实际问题时灵活应用。

2、增强上机编程调试能力。

二、问题描述1.分别利用顺序查找和折半查找方法完成查找。

有序表(3,4,5,7,24,30,42,54,63,72,87,95)输入示例:请输入查找元素:52输出示例:顺序查找:第一次比较元素95第二次比较元素87 ……..查找成功,i=**/查找失败折半查找:第一次比较元素30第二次比较元素63 …..2.利用序列(12,7,17,11,16,2,13,9,21,4)建立二叉排序树,并完成指定元素的查询。

输入输出示例同题1的要求。

三、数据结构设计(选用的数据逻辑结构和存储结构实现形式说明)(1)逻辑结构设计顺序查找和折半查找采用线性表的结构,二叉排序树的查找则是建立一棵二叉树,采用的非线性逻辑结构。

(2)存储结构设计采用顺序存储的结构,开辟一块空间用于存放元素。

(3)存储结构形式说明分别建立查找关键字,顺序表数据和二叉树数据的结构体进行存储数据四、算法设计(1)算法列表(说明各个函数的名称,作用,完成什么操作)序号 名称 函数表示符 操作说明1 顺序查找 Search_Seq 在顺序表中顺序查找关键字的数据元素2 折半查找 Search_Bin 在顺序表中折半查找关键字的数据元素3 初始化 Init 对顺序表进行初始化,并输入元素4 树初始化 CreateBST 创建一棵二叉排序树5 插入 InsertBST 将输入元素插入到二叉排序树中6 查找 SearchBST在根指针所指二叉排序树中递归查找关键字数据元素 (2)各函数间调用关系(画出函数之间调用关系)typedef struct { ElemType *R; int length;}SSTable;typedef struct BSTNode{Elem data; //结点数据域 BSTNode *lchild,*rchild; //左右孩子指针}BSTNode,*BSTree; typedef struct Elem{ int key; }Elem;typedef struct {int key;//关键字域}ElemType;(3)算法描述int Search_Seq(SSTable ST, int key){//在顺序表ST中顺序查找其关键字等于key的数据元素。

若找到,则函数值为//该元素在表中的位置,否则为0int c=1,i;for (i=ST.length; i>=0; --i){printf("第%d次比较元素%d\n",c++,ST.R[i-1].key);if (ST.R[i-1].key==key)//从后往前找return i;}return 0;}// Search_Seqint Search_Bin(SSTable ST,int key){// 在有序表ST中折半查找其关键字等于key的数据元素。

若找到,则函数值为// 该元素在表中的位置,否则为0int low=0,high=ST.length,i=1; //置查找区间初值int mid;while(low<=high){mid=(low+high) / 2;printf("......第%d次比较元素%d\n",i++,ST.R[mid].key);if (key==ST.R[mid].key)return mid; //找到待查元素else if (key<ST.R[mid].key)high = mid -1; //继续在前一子表进行查找else low =mid +1; //继续在后一子表进行查找 }return 0; //表中不存在待查元素}//初始化顺序表void Init(SSTable &W){int i=0,max;W.R=(ElemType *)malloc(100*sizeof(ElemType));printf("有序表3,4,5,7,24,30,42,54,63,72,87,95\n");printf("输入顺序表元素个数:\n");scanf("%d",&max);printf("依次输入顺序表元素\n");while(i!=max){i++;scanf("%d",&W.R[i-1].key);}W.length=max;}//*************************************插入二叉排序树T中void InsertBST(BSTree &T,int e){if(T==NULL){T=new BSTNode;T->data.key=e;T->lchild=NULL;T->rchild=NULL;}else if(T->data.key>e){InsertBST(T->lchild,e);}elseInsertBST(T->rchild,e);}//**********************二叉排序树的创建void CreateBST(BSTree &T ){//依次读入一个关键字为key的结点,将此结点插入二叉排序树T中T=NULL;int e,i=1,max;printf("输入的个数为:");scanf("%d",&max);while(i<=max){printf("输入第%d个数:",i++);scanf("%d" ,&e);InsertBST(T, e); //将此结点插入二叉排序树T中}//while}//CreatBST//*********************二叉排序树的递归查找BSTree SearchBST(BSTree T,char key){//在根指针T所指二叉排序树中递归地查找某关键字等于key的数据元素//若查找成功,则返回指向该数据元素结点的指针,否则返回空指针if(T)printf("第%d次查询:%d\n",N++,T->data.key);if((!T)|| key==T->data.key)return T; //查找结束else if(key<T->data.key)return SearchBST(T->lchild,key); //在左子树中继续查找elsereturn SearchBST(T->rchild,key); //在右子树中继续查找}五、调试记录(调试过程中遇到的主要问题,是如何解决的,对设计和编码的回顾讨论和分析;改进设想等)调试中出现了几次程序查找失败的情况,究其原因,是奇数个元素的时候,二分查找未定义好,在后续改进之后,程序能实现预期的效果六、运行说明(列出测试结果,包括输入和输出。

这里的测试数据应该完整和严格,最好多于示例中所列数据)以下附上源代码:#include<stdio.h>#include<stdlib.h>#include<string.h>int N;typedef struct{int key;//关键字域}ElemType;typedef struct Elem{int key;}Elem;typedef struct BSTNode{Elem data; //结点数据域BSTNode *lchild,*rchild; //左右孩子指针}BSTNode,*BSTree;typedef struct{ElemType *R;int length;}SSTable;int Search_Seq(SSTable ST, int key){//在顺序表ST中顺序查找其关键字等于key的数据元素。

若找到,则函数值为//该元素在表中的位置,否则为0int c=1,i;for (i=ST.length; i>=0; --i){printf("第%d次比较元素%d\n",c++,ST.R[i-1].key);if (ST.R[i-1].key==key)//从后往前找return i;}return 0;}// Search_Seqint Search_Bin(SSTable ST,int key){// 在有序表ST中折半查找其关键字等于key的数据元素。

若找到,则函数值为// 该元素在表中的位置,否则为0int low=0,high=ST.length,i=1; //置查找区间初值int mid;while(low<=high){mid=(low+high) / 2;printf("......第%d次比较元素%d\n",i++,ST.R[mid].key);if (key==ST.R[mid].key)return mid; //找到待查元素else if (key<ST.R[mid].key)high = mid -1; //继续在前一子表进行查找else low =mid +1; //继续在后一子表进行查找 }return 0; //表中不存在待查元素}//初始化顺序表void Init(SSTable &W){int i=0,max;W.R=(ElemType *)malloc(100*sizeof(ElemType));printf("有序表3,4,5,7,24,30,42,54,63,72,87,95\n");printf("输入顺序表元素个数:\n");scanf("%d",&max);printf("依次输入顺序表元素\n");while(i!=max){i++;scanf("%d",&W.R[i-1].key);}W.length=max;}//*************************************插入二叉排序树T中void InsertBST(BSTree &T,int e){if(T==NULL){T=new BSTNode;T->data.key=e;T->lchild=NULL;T->rchild=NULL;}else if(T->data.key>e){InsertBST(T->lchild,e);}elseInsertBST(T->rchild,e);}// **********************二叉排序树的创建void CreateBST(BSTree &T ){//依次读入一个关键字为key的结点,将此结点插入二叉排序树T中T=NULL;int e,i=1,max;printf("输入的个数为:");scanf("%d",&max);while(i<=max){printf("输入第%d个数:",i++);scanf("%d" ,&e);InsertBST(T, e); //将此结点插入二叉排序树T中}//while}//CreatBST//*********************二叉排序树的递归查找BSTree SearchBST(BSTree T,char key){//在根指针T所指二叉排序树中递归地查找某关键字等于key的数据元素//若查找成功,则返回指向该数据元素结点的指针,否则返回空指针if(T)printf("第%d次查询:%d\n",++N,T->data.key);if((!T)|| key==T->data.key)return T; //查找结束else if(key<T->data.key)return SearchBST(T->lchild,key); //在左子树中继续查找elsereturn SearchBST(T->rchild,key); //在右子树中继续查找}void main(){int N=1;printf("****************查找实验*****************\n");SSTable W;int t,i,a;while(1){printf("*****功能:1--顺序、二分查找 2--二分查找\n");scanf("%d",&a);switch(a){case 1:Init(W);printf("****************有序表的顺序查找*****************\n");printf("请输入查找元素\n");scanf("%d",&t);if(i=Search_Seq(W, t))printf("位置在第 %d位\n",i);elseprintf("不存在\n");printf("****************有序表的二分查找*****************\n");if(i=Search_Bin(W,t)+1)printf("位置在第%d位\n",i);elseprintf("不存在\n");break;case 2:printf("***利用序列(12,7,17,11,16,2,13,9,21,4)建立二叉排序树,并完成指定元素的查询***********\n");BSTree T ;int x;CreateBST(T);printf("输入查询元素:");scanf("%d",&x);if(SearchBST(T,x) )printf("查询成功");else printf("查询失败");break;}}}。

相关文档
最新文档