【数据结构】查找
查找的基本概念
查找表:由同一类型的数据元素(或记录)构成的集合
静态查找表:查找的同时对查找表不做修改操作(如插入和删除)
动态查找表:查找的同时对查找表具体修改操作
关键字:记录中某个数据项的值,可用来识别一个记录
主关键字:唯一标识数据元素
次关键字:可以表示若干个数据元素
平均查找长度:关键字的平均比较次数,也成平均搜索长度
线性表的查找
顺序查找
● 应用范围:顺序表或线性链表表示的静态查找表
表内元素之间无序
● 顺序表的表示:
typedef struct{
ElemType *R; //表基址
int length; //表长
}SSTable;
● 顺序查找的性能分析:
空间复杂度:一个辅助空间
时间复杂度:
1)查找成功时的平均查找长度设表中各记录查找概率相等 ASLs(n)=(1+2+……+n)/n=(n+1)/2
2)查找不成功的平均查找长度 ASLf=n+1
● 顺序查找算法特点:
①算法简单,对表结构无任何要求(顺序和链式)
②n很大时查找效率较低
③改进措施:非等概论查找时,可按照查找概率进行排序
折半查找
● 算法描述:
int Search_Bin(SSTable ST,int key)
{ //在有序表ST中折半查找其关键字等于key的数据元素。若找到,则函数值为该元素在表中的位置,否则为0
low=1;
high=ST.length;//置查找区间初值
while(low<=high)
{
mid=(low+high)/2;
if(key==ST.R[mid].key)
return mid;//找到待查元素
else if (key<ST.R[mid].key)
high=mid-1;//继续在前一字表进行查找
else
low=mid+1;//继续在后一字表进行查找
}//while
return 0;//表中不存在待查元素
}
● 折半查找的性能分析:
查找过程:每次将待查记录所在区间缩小一半,比顺序查找效率高,时间复杂度为O(log2n)
适用条件:采用顺序存储结构的有序表,不宜用于链式结构
● 折半查找算法特点:
优点:比较次数少,查找效率高
缺点:对表结构要求高,只能用于顺序存储的有序表
分块查找
分块查找(块间有序,块内无须)
● 分块查找算法特点:
优点:在表中插入或删除数据元素时,只要找到该元素对应的块,就可以在该块内进行插入和删除运算。由于块内无序,故插入和删除比较容易,无需进行大量移动
缺点:要增加一个索引表的存储空间并对初始索引表进行排序运算
树表的查找
二叉排序树
● 二叉排序树的定义
二叉排序树或者是一颗空树,或者是具有以下性质的二叉树:
(1)若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
(2)若它的右子树不空,则左子树上所有结点的值均大于它的根结点的值;
(3)它的左右子树也分别为二叉排序树。
● 二叉排序树的重要性质
中序遍历一棵二叉树时可以得到一个结点值递增的有序序列
● 二叉排序树的二叉链表存储表示
typedef struct ElemType{
char key; //关键字项
}ElemType; //每个结点的数据域的类型
typedef struct BSTNode{
ElemType data; //结点数据域
BSTNode *lchild,*rchild; //左右孩子指针
}BSTNode,*BSTree;
● 二叉排序树的递归查找算法:
//算法7.4 二叉排序树的递归查找
BSTree SearchBST(BSTree T,char key)
{
//在根指针T所指二叉排序树中递归地查找某关键字等于key的数据元素
//若查找成功,则返回指向该数据元素结点的指针,否则返回空指针
if((!T)||key==T->data.key)
return T;
else if(key<T->data.key)
return SearchBST(T->lchild,key);
else
return SearchBST(T->rchild,key);
}
● 二叉排序树的插入算法
//算法7.5 二叉排序树的插入
void InsertBST(BSTree &T,ElemType e ) {
//当二叉排序树T中不存在关键字等于e.key的数据元素时,则插入该元素
if(!T) { //找到插入位置,递归结束
BSTree S = new BSTNode; //生成新结点*S
S->data = e; //新结点*S的数据域置为e
S->lchild = S->rchild = NULL; //新结点*S作为叶子结点
T =S; //把新结点*S链接到已找到的插入位置
}
else if (e.key< T->data.key)
InsertBST(T->lchild, e ); //将*S插入左子树
else if (e.key> T->data.key)
InsertBST(T->rchild, e); //将*S插入右子树
}// InsertBST
● 二叉排序树的创建算法
//算法7.6 二叉排序树的创建
void CreateBST(BSTree &T ){
//依次读入一个关键字为key的结点,将此结点插入二叉排序树T中
T=NULL;
ElemType e;
cin>>e.key;
while(e.key!=ENDFLAG)
{
InsertBST(T,e);
cin>>e.key;
}
}