查找
查找表按照操作方式来分有两大种:静态查找表和动态查找表。静态查找表只作查找操作的查找表。动态查找表在查找过程中同时插入查找表中不存在的数据元素, 或者从查找表中删除已经存在的某个数据元素。
顺序表查找(查找O(N)、增删快)
int sequence(int* a,int n,int key){
int i;
a[0]=key;//设置哨兵
i=n;
while(a[i]!=key)//从尾部开始查找
i--;
}
return i;//返回0表明查找失败
}
有序表查找(查找O(logN)、增删慢)
二分查找:前提是关键码有序,顺序存储。
思想:取中间记录作为比较对象。若key小于中间值,则在左半区继续查找;否则,在右半区查找。
循环
int Binary_Search(int* a,int n,int key){
int low=0,high=n-1,mid;//左右都闭
while(low<=high){
mid=(low+high)/2;//二分查找
if(key<a[mid])
high=mid-1;//key小于中间,左部分查找
else if(key>a[mid])
low=mid+1;//key大于中间,在右半区查找
else{
return mid;//找到
}
}
return -1;// 没找到
}
递归
int binary_search(int *arr, int left, int right, int key)
{
assert(arr != NULL);
if (left <= right)
{
int mid = left + ((right - left) >> 1);
if (key > arr[mid])
{
return binary_search(arr, mid+1, right, key);
}
else if (key < arr[mid])
{
return binary_search(arr, left, mid-1, key);
}
else
{
return mid;
}
}
else
{
return -1;
}
}
注意:
1. low<=high 最终low和high 会指向同一个数值。
如果target不一定存在的话,就要用low <= high,最终low大于high导致循环退出,说明target不存在。
如果我们要找的target一定存在的话,那用low < high
2. 如果不mid+1 mid-1 会死循环 严重注意:high=mid没关系,但low=mid有可能导致死循环。因为low=high-1时low=mid,如果又进入low=mid分支相当于搜索区间没缩小。但high一定大于mid,所以不会造成死循环。
动态查找:二叉排序树(查找和增删速度快)

左子树小于父节点,右子树大于父节点的二叉树就是二叉排序树。对其中序遍历,必为升序。
二叉排序树以链接方式存储,插入删除操作时,不用移动元素,只要找到合适位置,只需修改链接指针即可。
二叉树的二叉链表节点结构
struct BiTNode{
int data;
BiTNode* lchild,*rchild;
};//BitNode为结构体
// 二叉树节点生成
BiTNode* T,p;//T是结构体指针
// 查找(查找结果给p)
SearchBST(T,93,NULL,&p);//需要对p进行修改,索引用二重指针,指针的指针。
// 插入
InsertBST(&T,50);//需要对T进行修改,索引用二重指针,指针的指针。
// 删除
DeeteBST(&T,50);//需要对T进行修改
查找(递归)
//使用
BiTNode* T,p;//T是结构体指针
SearchBST(T,93,NULL,&p);//需要对p进行修改,索引用二重指针,指针的指针。
Status SearchBST(BiTNode* T,int key,BiTNode* f,BiTNode** p){//T是二叉排序树指针、f指向T的双亲,p为返回查找成功节点,二重指针
if(T==NULL){//叶节点,没找到
*p=f;
return FALSE;
}
else if(key==T->data){//查找成功
*p=T;
return TRUE;
}
else if(key<T->data){//左子树继续查
return SearchBST(T->lchild,key,T,p);//T->lchild指针
}
else{//右子树继续查
return SearchBST(T->rchild,key,T,p);
}
}
插入
- 先调用查找操作将要插入的关键字进行比较
- 如果在原有的二叉排序树中没有要插入的关键字,则将关键字与查找的结点p(在查找操作中返回的结点)的值进行比较
- 若p为空,则插入关键字赋值给该节点;
- 若小于结点p的值,则插入关键字作为结点p的左子树;
- 若大于结点p的值,则插入关键字作为结点p的右子树;
int InsertBST(BiTNode** T, int key){//这里的T是二重指针,修改时用*T即可。
BiTNode* p,s;//指针
if (!SearchBST( *T, key, NULL, &p)) { // 没找到key,p返回查找路径上最后一个节点
s = (BiTree)malloc(sizeof(BiTNode));
s->data = key;
s->lchild = s->rchild = NULL;
if (!p)//p为NULL时,第一个节点作为根节点
*T =

本文介绍了查找算法,包括静态查找表、动态查找表中的二分查找和二叉排序树。详细讨论了二叉排序树的插入、删除操作,以及平衡二叉树AVL树的概念和调整策略。同时,提到了红黑树的特点和插入操作的三种情况,最后概述了哈希表的查找效率和散列函数构造方法。
最低0.47元/天 解锁文章
5390

被折叠的 条评论
为什么被折叠?



