一、折半(二分)查找
参考书:《数据结构(C语言)》–严蔚敏等编著,清华大学出版社。
1、三种静态查找
在有序表的顺序查找中,它的平均ASL为,是三种静态查找方法(顺序查找-折半查找-分块查找
)中最大,他们之间的比较如下:
\ | 顺序查找 | 折半查找 | 分块查找 |
ASL | 最大 | 最小 | 中间 |
表结构 | 有序、无序表 | 有序表 | 分块有序 |
存储结构 | 顺序、链表 | 顺序表 | 顺序、链表 |
优缺点也很明显,其中折半查找的优缺点为:
优点:效率比顺序查找高;
缺点:只适用于有序表,且仅限于顺序存储结构,对线性链表使用时无法有效的查找;
折半查找的最大特点是:每次将待查找记录区间缩小一半区域,减少比较的次数
;
2、判定树
这个查找过程可以利用二叉树来描述。其中每个节点表示一个记录,把这样的树称为判定树;其中判定树需满足一下特点
:
存储:大的在右,小的在左;
查找:大的向右找,小的向左找;
特别:0号元素空出,从1号开始存储,便于返回值
可以看出:
查找记录在第几层,就会比较几次,但是如果查找不成功(无此记录)的情况下,只会出现在第3、4层,因为只有这两层会有NULL空
出现表示不存在的节点;
查找成功的平均ASL长度
计算如下:节点个数x层数/n
ASL=
查找不成功的平均ASL长度
计算如下:空节点个数x层数/n
ASL=
相关代码:
#include "stdio.h"
#include "stdlib.h"
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define OVERFLOW -2
#define MAXSIZE 100
typedef int Status;
typedef int KeyType;
typedef struct {
KeyType key;
} ElemType;
typedef struct {
ElemType *elem;
int length;
} SSTable;
int order[MAXSIZE]; //全局变量,记录比较的数值
Status InitTable(SSTable &ST,int n);
Status InitTable(SSTable &ST,int n) {
ST.elem = (ElemType*)malloc(MAXSIZE*sizeof(ElemType));
if(!ST.elem) exit(OVERFLOW);
ST.length = 0;
for(int i=1; i<=n; i++) {
int num;
scanf("%d",&num);
ST.elem[i].key = num;
ST.length++;
}
return OK;
}
Status Search_Bin(SSTable &ST,KeyType key);
//折半查找
Status Search_Bin(SSTable &ST,KeyType key) {
int low=1,high=ST.length,i=0;
while(low <= high) {
int mid = (low + high)/2;
if(key == ST.elem[mid].key) {
order[i] = ST.elem[mid].key; //存比较的数(路径)
return mid;
}
else if(key > ST.elem[mid].key) {
order[i] = ST.elem[mid].key;
low = mid + 1;
}
else {
order[i] = ST.elem[mid].key;
high = mid - 1;
}
i++;
}
}
int main(void) {
SSTable ST;
int i,n;
int key;
printf("请输入列表项个数: ");
scanf("%d",&n);
printf("请输入列表项: ");
InitTable(ST,n);
printf("请输入查找关键字: ");
scanf("%d",&key);
i = Search_Bin(ST,key);
printf("比较的数依次为:");
for(int j=0; order[j] != 0; j++)
printf("%d->",order[j]);
putchar('\n');
if(i != 0)
printf("该关键字的位置为: %d\n",i);
else
printf("查无此项\n");
return 0;
}
/*
测试输入:
5
8 10 12 15 33
20
预期输出:
12-15-33- //比较数
查无此项
预期输出:
9
12 15 33 42 45 77 78 80 89
12
预期输出:
45-15-12- //比较数
1
*/