顺序查找和折半查找
数据结构——查找,顺序查找,折半查找
实验五查找的应用一、实验目的: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的数据元素。
数据结构_查找原理及典型的查找算法
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)定义 二叉排序树或者是一棵空树,或是具有下列性质的二叉树:
若左子树非空,则左子树上所有结点的值均小于它的 根结点的值。
若右子树非空,则右子树上所有结点的值均大于它的 根结点的值。
有序/无序表 有序表
顺序/链式存 储
顺序存储
分块查找 介于二者之间 表中元素逐段有序 顺序/链式存储
查找也叫检索
排序n个记录的文件最多需要n-1趟冒泡排序。
25 25 25 25 11 11 11
56 49 49 11 25 25 25
49 56 11 49 41 36 36
78 11 56 41 36 41
11 65 41 36 49
65 41 36 56
41 36 65
36 78
初
第
第
第
第
第
第
始
一
二
三
四
[ 15 27 36 42 53 69 ]
测试3(06年初赛试题)
将5个数的序列排序,不论原先的顺序如何,最少都可以 通过( B )次比较,完成从小到大的排序。
A. 6 B. 7 C. 8 D. 9
2 4 3 5 1 1次 2 4 3 5 1 2次 2 3 4 5 1 2次 2 3 4 5 1 2次
end.
测试4(06年初赛试题)
将数组{32,74,25,53,28,43,86,47}中的元素按从小到 大的顺序排列,每次可以交换任意两个元素,最少需要交 换__5_次。
用直接选择排序实现: 25,74,32,53,28,43,86,47 25,28,32,53,74,43,86,47 25,28,32,53,74,43,86,47 25,28,32,43,74,53,86,47 25,28,32,43,47,53,86,74 25,28,32,43,47,53,86,74 25,28,32,43,47,53,74,86
待排元素序列:[53] 27 36 15 69 42 第一次排序: [27 53] 36 15 69 42 第二次排序: [27 36 53] 15 69 42 第三次排序: [15 27 36 53] 69 42 第四次排序: [15 27 36 53 69] 42 第五次排序: [15 27 36 42 53 69]
大学数据结构课件--第9章 查找
二叉排序树既有类似于折半查找的特性,又采用了链表存储,它是动态 查找表的一种适宜表示。
注:若数据元素的输入顺序不同,则得到的二叉排序树形态 也不同!
17
二、二叉树的插入和删除操作
1、二叉排序树的插入和查找操作
例:输入待查找的关键字序列=(45,24,53,12,90)
折半查找举例:
已知如下11个元素的有序表:
(05 13 19 21 37 56 64 75 80 88 92), 请查找关键字为21和85的数据元素。
Low指向待查元 素所在区间的下 界
mid指向待查元素所在 high指向待查元素所
区间的中间位置
在区间的上界
8
9.1.2 折半查找(又称二分查找或对分查找)
balance。这样,可以得到AVL树的其它性质:
❖ 任一结点的平衡因子只能取:-1、0 或 1;如果树中任 意一个结点的平衡因子的绝对值大于1,则这棵二叉树 就失去平衡,不再是AVL树;
24
三、平衡二叉树
例:判断下列二叉树是否AVL树?
-1
1
-1
0
0
1
0
(a) 平衡树
2
-1
0
0
1
0
(b) 不是平衡树
(1)p为叶子结点,只需修改p双亲f的指针f->lchild=NULL或 f->rchild=NULL
(2)P只有左子树或右子树 ❖ P只有左子树,用P的左孩子代替P ❖ P只有右子树,用P的右孩子代替P
(3)P左、右子树均非空 (P左子树的根C的右子树分支找到S,S的右子树为空) ❖ P的左子树成为双亲f的左子树,P的右子树成为S的右子树 ❖ S的左子树成为S的双亲Q的右子树,用S取代p; 若C无右子树,用C取代p
数据结构中的查找算法总结
数据结构中的查找算法总结静态查找是数据集合稳定不需要添加删除元素的查找包括: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; 折半查找判定数中的结点都是查找成功的情况,将每个结点的空指针指向⼀个实际上不存在的结点——外结点,所有外界点都是查找不成功的情况,如图所⽰。
基本查找方法
分块查找算法
int blksearch (sqlist r,index idx,int k,bn) /*bn为块的个数*/ {
int i,high=bn,low=1,mid,j,find=0; while (low<=high&& !find) { /*二分查找索引表*/
mid=(low+high)/2; if(k<idx[mid].key)
查找
图8.1 线性表与索引表
查找
索引表的定义
struct indexterm {
keytype key; int low,high; }; typedef struct indexterm index[MAXITEM]; 这里的keytype可以是任何相应的数据类型, 如int、float、或char等,在算法中,我们规 定keytype缺省是int类型。
查找
二分查找算法
int binsearch(sqlist r,int k,n) {
int i,low=1,high=n,m,find=0; /*low和high分别表示查找范围的起始单元下标和终止
单元下标,find为查找成功的标志变量*/ while (low<=high && !find) {
m=(low+high)/2; if(k<r[m].key)
数据结构
1.1 顺序查找
顺序查找(Sequential search)也称为线性查找, 是采用线性表作为数据的存储结构,对数据 在表中存放的先后次序没有任何要求。
顺序查找是最简单的查找方法,它的基本思 想是:查找从线性表的一端开始,顺序将各 单元的关键字与给定值k进行比较,直至找 到与k相等的关键字,则查找成功,返回该 单元的位置序号;如果进行到表的另一端, 仍未找到与k相等的关键字,则查找不成功, 返回0作为查找失败的信息。
数据结构顺序查找与折半查找
数据结构顺序查找与折半查找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,平均情况下⽐顺序查找效率⾼⼀些。
数据结构DS教程(07查找)
M
H
图7-2 查找K=53时指针变化示意图
7.3 动态查找
7.3.1
二叉排序树
7.3.2
7.3.3 7.3.4 7.3.5
二叉排序树的查找
二叉排序树的插入 二叉排序树的删除 二叉排序树的应用举例
7.3.1 二叉排序树
二叉排序树的递归定义:
二叉排序树要么是一棵空树,要么是具有下列性 质的二叉树:
第7章 查找
7.1
查找概述
7.2
7.3 7.4
静态查找
动态查找 哈希表
7.1 基本概念
查找
也叫检索,是数据处理中常用的一种操作。
在计算机应用中,查找是指在数据元素集合中查 找满足某种条件的数据元素的过程。
查找表
用于查找的数据元素集合
查找表的操作
(1)在查找表中查看某个特定的数据元素是否在 查找表中; (2)检索某个特定元素的各种属性; (3)在查找表中插入一个数据元素; (4)从查找表中删除某个数据元素。
图7-4 二分查找判定树
47
21
60
11
30
51
68
42
100
(a)
图7-3 二分查找判定树
7.3.3 二叉排序树的插入
插入特点:
二叉排序树是一种动态树表,是在查找过程中动 态生成的,即当二叉树中不存在关键字等于给定 值的结点时便将该结点插入到二叉树中。新插入 的结点一定是一个新添加的叶子结点,并且是查 找不成功时,查找路径上访问的最后一个结点的 左孩子或右孩子结点。
(e)插入关键字77
各种查找算法的性能比较测试(顺序查找、二分查找)
算法设计与分析各种查找算法的性能测试目录摘要 (2)第一章:简介(Introduction) (3)1.1 算法背景 (3)第二章:算法定义(Algorithm Specification) (4)2.1 数据结构 (4)2.2顺序查找法的伪代码 (4)2.3 二分查找(递归)法的伪代码 (5)2.4 二分查找(非递归)法的伪代码 (6)第三章:测试结果(Testing Results) (8)3.1 测试案例表 (8)3.2 散点图 (9)第四章:分析和讨论 (11)4.1 顺序查找 (11)4.1.1 基本原理 (11)4.2.2 时间复杂度分析 (11)4.2.3优缺点 (11)4.2.4该进的方法 (12)4.2 二分查找(递归与非递归) (12)4.2.1 基本原理 (12)4.2.2 时间复杂度分析 (13)4.2.3优缺点 (13)4.2.4 改进的方法 (13)附录:源代码(基于C语言的) (15)摘要在计算机许多应用领域中,查找操作都是十分重要的研究技术。
查找效率的好坏直接影响应用软件的性能,而查找算法又分静态查找和动态查找。
我们设置待查找表的元素为整数,用不同的测试数据做测试比较,长度取固定的三种,对象由随机数生成,无需人工干预来选择或者输入数据。
比较的指标为关键字的查找次数。
经过比较可以看到,当规模不断增加时,各种算法之间的差别是很大的。
这三种查找方法中,顺序查找是一次从序列开始从头到尾逐个检查,是最简单的查找方法,但比较次数最多,虽说二分查找的效率比顺序查找高,但二分查找只适用于有序表,且限于顺序存储结构。
关键字:顺序查找、二分查找(递归与非递归)第一章:简介(Introduction)1.1 算法背景查找问题就是在给定的集合(或者是多重集,它允许多个元素具有相同的值)中找寻一个给定的值,我们称之为查找键。
对于查找问题来说,没有一种算法在任何情况下是都是最优的。
有些算法速度比其他算法快,但是需要较多的存储空间;有些算法速度非常快,但仅适用于有序数组。
计算机数据结构知识点梳理 顺序查找法、折半查找法
typedef struct node{ int A[m];
//每个结点含有m个整数,本例m为5 struct node *next;
}LNode, *LinkList; typedef struct{
int j; //正整数在结点内的序号 LNode *s; //结点的指针 }rcd;
}
[题2]顺序存储的某线性表共有123个元素,按分块查找的要求等分为3块。若对索引 表采用顺序查找方法来确定子块,且在确定的子块中也采用顺序查找方法,则在等 概率的情况下,分块查找成功的平均查找长度为( )。
A.21
B. 23
C. 41
D. 62
分析:分块查找成功的平均查找长度为ASL=(s2+s+n)/2s。在本题中,n=123, s=123/3=41,故平均查找长度为23。
对表中每个数据元素的查找过程,可用二叉树来描述,称这个描述折半查找过 程的二叉树为判定树,表的中间结点是二叉树的根,左子表相当于左子树, 右子表相当于右子树。折半查找的过程是从根结点到待查找结点的过程,不 论查找成功或失败,查找长度均不超过树的高度,因此,如果有序表的长度 为n,那么在查找成功时与给定值进行比较的关键字个数至多为[㏒2n] +1。
4 、分块查找法
分块查找法要求将列表组织成以下索引顺序结构: (1)首先将列表分成若干个块(子表)。一般情况下,块的长度均匀, 最后一块 可以不满。每块中元素任意排列,即块内无序,但块与块之间有序。 (2)构造一个索引表。其中每个索引项对应一个块并记录每块的起始位置,以及每 块中的最大关键字(或最小关键字)。索引表按关键字有序排列。
假定将长度为n的表分成b块,且每块含s个元素,则b=n/s。又假定表中每个元素的查 找概率相等,则每个索引项的查找概率为1/b,块中每个元素的查找概率为1/s。
顺序查找直接查找折半查找算法
顺序查找直接查找折半查找算法一、顺序查找算法顺序查找也被称为线性查找,是一种简单直观的算法。
其基本原理是逐个遍历数据集中的元素,直到找到目标值为止。
算法步骤如下:1.从数据集的第一个元素开始顺序遍历。
2.如果当前元素与目标值相同,返回元素的索引。
3.如果遍历到数据集的最后一个元素仍未找到目标值,返回失败。
顺序查找算法的时间复杂度为O(n),其中n为数据集的大小。
由于需要遍历整个数据集,这种算法适用于小型数据集。
二、直接查找算法直接查找算法也被称为线性查找优化算法,其思想是在遍历数据集时,通过跳跃一定步长快速确定目标值所在的范围,然后在该范围内进行顺序查找。
算法步骤如下:1.设定步长为k。
2.从数据集的第一个元素开始,每次跳跃k个元素。
3.如果当前元素大于目标值,将步长减半并继续跳跃,直到找到目标值或步长变为1为止。
4.在跳跃范围内进行顺序查找,找到目标值则返回索引,否则返回失败。
直接查找算法的时间复杂度为O(n/k),其中n为数据集的大小,k为步长。
通过调整步长,可以在时间和空间之间取得平衡。
折半查找算法是一种效率较高的算法,也被称为二分查找。
其基本原理是将数据集分为两半,通过比较目标值与中间元素的大小关系来确定目标值所在的范围,然后在该范围内进行递归查找。
算法步骤如下:1.将数据集按升序或降序排列。
2.初始化左右指针,分别指向数据集的第一个和最后一个元素。
3.计算中间元素的索引。
4.如果中间元素等于目标值,则返回索引。
5.如果中间元素大于目标值,则更新右指针为中间元素的前一个元素,重复步骤36.如果中间元素小于目标值,则更新左指针为中间元素的后一个元素,重复步骤37.当左指针大于右指针时,返回失败。
折半查找算法的时间复杂度为O(logn),其中n为数据集的大小。
由于每次都将数据集分为两半,因此效率较高。
但是该算法要求数据集必须有序。
综上所述,顺序查找、直接查找和折半查找算法都是常用的算法,适用于不同规模和有序性的数据集。
实现顺序查找和折半查找的算法
实现顺序查找和折半查找的算法顺序查找和折半查找(也称为二分查找)是两种常见的查找算法。
以下是它们的Python实现:1. 顺序查找:```pythondef sequential_search(list, item):pos = 0found = Falsewhile pos < len(list) and not found:if list[pos] == item:found = Trueelse:pos = pos+1return found```这个函数会检查列表中的每个元素,直到找到匹配的元素或者遍历完整个列表。
如果找到匹配的元素,函数会返回True,否则返回False。
2. 折半查找:```pythondef binary_search(list, item):low = 0high = len(list) - 1mid = 0found = Falsewhile low <= high and not found:mid = (high + low) // 2if list[mid] == item:found = Trueelif list[mid] < item:low = mid + 1else:high = mid - 1return found```这个函数使用二分查找算法,每次比较列表中间的元素和目标元素。
如果中间元素等于目标元素,函数返回True。
如果中间元素小于目标元素,函数在列表的右半部分继续查找。
如果中间元素大于目标元素,函数在列表的左半部分继续查找。
如果函数遍历完整个列表都没有找到目标元素,那么返回False。
常用的查找算法
树表查找
树表查找
B和B+树的区别在于,B+树的非叶子结点只包含导航信息,不包含实际的值, 所有的叶子结点和相连的节点使用链表相连,便于区间查找和遍历。 B+ 树的优点在于: 由于B+树在内部节点上不好含数据信息,因此在内存页中能够存放更多的key。 数据存放的更加紧密,具有更好的空间局部性。因此访问叶子几点上关联的 数据也具有更好的缓存命中率。 B+树的叶子结点都是相链的,因此对整棵树的便利只需要一次线性遍历叶子 结点即可。而且由于数据顺序排列并且相连,所以便于区间查找和搜索。而B 树则需要进行每一层的递归遍历。相邻的元素可能在内存中不相邻,所以缓 存命中性没有B+树好。B+树更适合做文件系统。 但是B树也有优点,其优点在于,由于B树的每一个节点都包含key和value, 因此经常访问的元素可能离根节点更近,因此访问也更迅速。
二分查找
注意事项:折半查找的前提条件是需要有序表顺序存储,对于静态查 找表,一次排序后不再变化,折半查找能得到不错的效率。但对于需 要频繁执行插入或删除操作的数据集来说,维护有序的排序会带来不 小的工作量,那就不建议使用。
插值查找
在介绍插值查找之前,首先考虑一个新问题,为什么上述算法一定要 是折半,而不是折四分之一或者折更多呢? 打个比方,在英文字典里面查“apple”,你下意识翻开字典是翻前 面的书页还是后面的书页呢?如果再让你查“zoo”,你又怎么查? 很显然,这里你绝对不会是从中间开始查起,而是有一定目的的往前 或往后翻。< 同样的,比如要在取值范围1 ~ 10000 之间 100 个元素从小到大均 匀分布的数组中查找5, 我们自然会考虑从数组下标较小的开始查找。
查找算法
数据结构50:二分查找法(折半查找法)
数据结构50:⼆分查找法(折半查找法)折半查找,也称⼆分查找,在某些情况下相⽐于顺序查找,使⽤折半查找算法的效率更⾼。
但是该算法的使⽤的前提是静态查找表中的数据必须是有序的。
例如,在{5,21,13,19,37,75,56,64,88 ,80,92}这个查找表使⽤折半查找算法查找数据之前,需要⾸先对该表中的数据按照所查的关键字进⾏排序:{5,13,19,21,37,56,64,75,80,88,92}。
在折半查找之前对查找表按照所查的关键字进⾏排序的意思是:若查找表中存储的数据元素含有多个关键字时,使⽤哪种关键字做折半查找,就需要提前以该关键字对所有数据进⾏排序。
折半查找算法对静态查找表{5,13,19,21,37,56,64,75,80,88,92}采⽤折半查找算法查找关键字为 21 的过程为:图 1 折半查找的过程(a)如上图 1 所⽰,指针 low 和 high 分别指向查找表的第⼀个关键字和最后⼀个关键字,指针 mid 指向处于 low 和 high 指针中间位置的关键字。
在查找的过程中每次都同 mid 指向的关键字进⾏⽐较,由于整个表中的数据是有序的,因此在⽐较之后就可以知道要查找的关键字的⼤致位置。
例如在查找关键字 21 时,⾸先同 56 作⽐较,由于21 < 56,⽽且这个查找表是按照升序进⾏排序的,所以可以判定如果静态查找表中有 21这个关键字,就⼀定存在于 low 和 mid 指向的区域中间。
因此,再次遍历时需要更新 high 指针和 mid 指针的位置,令 high 指针移动到 mid 指针的左侧⼀个位置上,同时令 mid 重新指向 low 指针和 high 指针的中间位置。
如图 2 所⽰:图 2 折半查找的过程(b)同样,⽤ 21 同 mid 指针指向的 19 作⽐较,19 < 21,所以可以判定 21 如果存在,肯定处于 mid 和 high 指向的区域中。
所以令 low 指向 mid 右侧⼀个位置上,同时更新 mid 的位置。
排序方法
三种查找算法:顺序查找,二分法查找(折半查找),分块查找,散列表(以后谈)一、顺序查找的基本思想:从表的一端开始,顺序扫描表,依次将扫描到的结点关键字和给定值(假定为a)相比较,若当前结点关键字与a相等,则查找成功;若扫描结束后,仍未找到关键字等于a的结点,则查找失败。
说白了就是,从头到尾,一个一个地比,找着相同的就成功,找不到就失败。
很明显的缺点就是查找效率低。
适用于线性表的顺序存储结构和链式存储结构。
计算平均查找长度。
例如上表,查找1,需要1次,查找2需要2次,依次往下推,可知查找16需要16次,可以看出,我们只要将这些查找次数求和(我们初中学的,上底加下底乘以高除以2),然后除以结点数,即为平均查找长度。
设n=节点数平均查找长度=(n+1)/2二、二分法查找(折半查找)的基本思想:前提:(1)确定该区间的中点位置:mid=(low+high)/2min代表区间中间的结点的位置,low代表区间最左结点位置,high代表区间最右结点位置(2)将待查a值与结点mid的关键字(下面用R[mid].key)比较,若相等,则查找成功,否则确定新的查找区间:如果R[mid].key>a,则由表的有序性可知,R[mid].key右侧的值都大于a,所以等于a的关键字如果存在,必然在R[mid].key左边的表中。
这时high=mid-1如果R[mid].key<a,则等于a的关键字如果存在,必然在R[mid].key右边的表中。
这时low=mid如果R[mid].key=a,则查找成功。
(3)下一次查找针对新的查找区间,重复步骤(1)和(2)(4)在查找过程中,low逐步增加,high逐步减少,如果high<low,则查找失败。
平均查找长度=Log2(n+1)-1注:虽然二分法查找的效率高,但是要将表按关键字排序。
而排序本身是一种很费时的运算,所以二分法比较适用于顺序存储结构。
为保持表的有序性,在顺序结构中插入和删除都必须移动大量的结点。
C语言程序设计100例之(21):折半查找
C语言程序设计100例之(21):折半查找例21 折半查找问题描述顺序查找是一种最简单和最基本的检索方法。
其基本思想是:从检索表的一端(如表中第一个记录或最后一个记录)开始,逐个进行记录的关键字和给定值的比较。
若某个记录的关键字和给定值比较相等,则查找成功;否则,若直至检索表的另一端(如最后一个记录或第一个记录),其关键字和给定值比较都不等,则表明表中没有待查记录,查找不成功。
顺序查找可以写成一个简单的一重循环,循环中依次将检索表(不妨设为数组a)中的元素与给定值比较,若相等,用break退出循环。
算法描述为:for (i=0; i< n;i++)if (a[i]==x) break;这样,循环结束后,若循环控制变量i小于数组元素个数n,则查找成功;否则,查找失败。
顺序查找实现简单,但效率不高。
当待查找序列有序时,即各检索表中元素的次序是按其记录的关键字值的大小顺序存储的。
此时采用折半查找会大幅提高查找效率。
折半查找的基本思想是先确定待查数据的范围(区间),然后逐步缩小范围直到找到或找不到该记录为止。
具体做法是:先取数组中间位置的数据元素与给定值比较。
若相等,则查找成功;否则,若给定值比该数据元素的值小(或大),则给定值必在数组的前半部分(或后半部分),然后在新的查找范围内进行同样的查找。
如此反复进行,直到找到数组元素值与给定值相等的元素或确定数组中没有待查找的数据为止。
因此,折半查找每查找一次,或成功,或使查找数组中元素的个数减少一半,当查找数组中不再有数据元素时,查找失败。
输入一个整数,在给定的有序数组中查找该整数是否存在,若存在,给出其数组的下标;若不存在,输出查找不成功信息。
输入格式第一行是一个正整数N (1 ≤N ≤100000),代表数组中元素的个数。
第二行有N个整数,这N个整数从小到大排列好了。
第三行是一个整数M,代表待查找元素的个数。
接下来的M行,每行有一个整数x,表示每个待查找的元素。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
return i;
}
return -1;
}
int binsearch(datatype x[],int key,int n)
{int low,mid,hig;
datatype y[MAXLEN];
low=0;
{ int i;
for(i=0;i<n;i++)
printf("%d\t",x[i]);
printf("\n");
}
#include<stdio.h>
#define MAXLEN 50
typedef struct{
int key;
char dasort(datatype x[]);
int seqsearch(datatype x[],int key,int n);
printf("\n没有给定值记录!\n");
else
printf("\n查找的结果为表中的第%d条记录!\n",i+1);
}
else
printf("选择错误选择!\n");
printf("请输入选择的查找方法:1---顺序查找 2---折半查找 3---退出查找\nyour choice=");
int binsearch(datatype x[],int key,int n);
void insertsort(datatype x[],int n);
void print(datatype x[],int n);
void main()
{ int sel,n,s,key,i;
datatype x[MAXLEN];
for(i=1;i<n;i++)
{ temp=x[i];
j=i-1;
while(j>-1&&temp.key<x[i].key)
{ x[j+1]=x[j];
j--;
}
x[j+1]=temp;
}
}
void print(datatype x[],int n)
hig=n-1;
for(int i=0;i<n;i++)
y[i]=x[i];
insertsort(y,n);
printf("\n排序后关键字序列为:");
print(y,n);
while(low<=hig)
{ mid=(low+hig)/2;
if(key==y[mid].key)
if(i==-1)
printf("\n没有给定值记录!\n");
else
printf("\n查找的结果为表中的第%d条记录!\n",i+1);
}
else if(s==2)
{ i=binsearch(x,key,n);
if(i==-1)
while(x[i].key!=-1)
{ i++;
scanf("%d",&x[i].key);
}
return i;
}
int seqsearch(datatype x[],int key,int n)
{ int i;
for(i=0;i<n;i++)
scanf("%d",&s);
}
printf("请输入你的选择:1---开始 其他选择为退出\nyour choice=");
scanf("%d",&sel);
}
}
int getsort(datatype x[])
{ int i=0;
scanf("%d",&x[i].key);
scanf("%d",&s);
while(s!=3)
{ printf("请输入查找关键字给定值=");
scanf("%d",&key);
if(s==1)
{ printf("\n原关键字序列为:");
print(x,n);
i=seqsearch(x,key,n);
printf("请输入你的选择:1---开始 其他选择为退出\nyour choice=");
scanf("%d",&sel);
while(sel==1)
{ printf("输入关键字序号,以-1结束输入:");
n=getsort(x);
printf("请输入选择的查找方法:1---顺序查找 2---折半查找 3---退出查找\nyour choice=");
return mid;
else if(key>y[mid].key)
low=mid+1;
else
hig=mid-1;
}
return -1;
}
void insertsort(datatype x[],int n)
{ int i,j;
datatype temp;