7.1 概述
7.1.1 查找的基本概念
关键码 : 可以标志一个记录的某个数据项。
查找
查找结果
静态查找、动态查找 : 不涉及插入和删除操作的查找;涉及插入和删除操作的查找。
查找结构
7.1.2 查找算法的性能
7.2 线性表的查找技术
7.2.1 顺序查找
1 顺序表的顺序查找
伪代码:
1、 设置哨兵;
2、 初始化查找的起始下标i=n;
3、 若人r[i]与k相等,则返回当前i的值;否则,继续比较前一个记录;
顺序表的顺序查找算法SeqSearch1
Int SeqSearch1(int r[],int n,int k)
{
R[0]=k;
I=n;
While(r[i]!=k)
i--;
return I;
}
2、单链表的顺序查找
顺序表的顺序查找算法SeqSearch
Int SeqSearch2(Node<int>*first,int k)
{
P=first->next;count=1;
While(p!=NULL&&p->data!=k)
{
P=p->next;
J++;
}
If(p->data==k)return j;
Else return0;
}
7.2.2 折半查找
1、执行过程
伪代码
1)设置初始查找区间:low=1;high=n;
2)测试查找区间[low,high]是否存在,若不存在,则查找失败;否则
3)取中间位置密道(low+high)/2;比较k与r[mid],有以下三种情况:
3.1 若k<r[mid],则high=mid-1;查找在左半区进行,转第二步;
3.2 若k>r[mid],则low=mid+1;查找在右半区进行,转第2步;
3.3 若k=r[mid],则查找成功,返回记录在表中位置mid.
2、非递归算法
折半查找递归算法BinSearch1
Int BinSearch1(int r[ ],int n,int k)
{
Low=1;high=n;
While(low<=high)
{
Mid=(low+high)/2;
If(k<r[mid])high=mid-1;
Else if(k>r[mid]) low=mid+1;
Else return mid;
}
Return 0;
}
3、递归算法
折半查找递归算法BinSearch2
Int BinSearch2(int r[ ],int low,int high,int k)
{
If(low>high) return 0;
Else
{
Mid=(low +high)/2;
If(k<r[mid])return BinSearch2(r,low,mid-1,k);
Else if(k>r[mid]) return BinSearch2(r,mid+1,high,k);
Else return mid;
}
}
4、 性能分析
设有序表的长度为n,判定树的构造方法:
1) 当n=0时,判定树为空;
2) 当n>0时,判定树的根结点是有序表中序号为mid=(1+n)/2的记录,根结点的左子树是与有序表r[1]~r[mid-1]相对应的判定树,根结点的右子树是与有序表r[mid+1]~r[n]相对应的判定树。
折半查找判定树的性质:
1) 任意两棵折半查找判定树,若它们的结点个数相同,则它们的结构完全相同;
2) 具有n个结点的折半查找判定树的深度为[log2n]+1;
3) 任意两个叶子所处的层数最多相差1.
7.3 树表的查找技术
7.3.1 二叉排序树
性质:
1) 若其左子树不空,则左子树所有结点的值均小于根结点的值;
2) 若其右子树不空,则右子树所有结点的值均大于根结点的值
3) 他的左右子树也是二叉排序树
1、 二叉树排序树的插入
伪代码
1) 若root是空树,则将结点s作为根结点插入;
2) 否则,若s->data小于root->data,则把结点s插入到root的左子树中;
3) 否则把结点s插入到root的右子树中;
二叉排序树插入算法InsertBST
Void BiSortTree::InsertBST(BiNode<int>*root,BiNode<int>*s)
{
If(root==NULL) root=s;
Else if(s->data<root->data) InsertBST(root->lchild,s);
Else InsertBST(root->rchild,s)
}
2、 二叉排序树的构造
伪代码:
1) 依次取每一个记录r[i],执行下述操作:
1.1申请一个数据域为r[i]的结点s,令结点s的左右指针域为空;
1.2 调用算法InsertBST,将结点s插入到二叉排序树中
算法BiSortTree
BiSorTree::BiSortTree(int r[ ],int n)
{
For (i=0;i<n;i++)
{
S=new BiNode;
s->lchild=s->rchild=NULL;
InsertBST(root, s);
}
}
3、 二叉排序树的删除
算法DeleteBST
Void BiSorTree::DeleteBSTz(BiNode<int> *p,BiNode<int> *f)
{
If((p->lchild==NULL)&&(p->rchild==NULL))
{
f->lchild=NULL;
delete p;
}
}
Else if (p->rchild==NULL)
{
f->lchild=p->lchild;
delete p;
}
Else if(p->lchild==NULL)
{
f->lchild=p->rchild;
delete p;
}
Else
{
Par=p;s=p->rchild;
While(s->lchild!=NULL)
{
Par=s;
S=s->lchild;
}
p->data=s->data;
if(par==p) par->rchild=s->rchild;
else par->lchild=s->rchild;
delete s;
}
}
4、 二叉排序树的查找及性能分析
算法SearchBST
BiNode<int>*BiSorTree::SearchBST(BiNode<int>*root,int k)
{
If(root==NULL) return NULL;
Else if (root->data==K)return root;
Else if(root->data<k)return SearchBST(root->lchild,k);
Else return SearchBST(root->rchild,k);
}
7.3.2 平衡二叉树
性质:
1) 根结点的左子树和右子树的深度最多相差1
2) 根结点的左子树和右子树也都是平衡二叉树。
平衡因子:
该结点的左子树的深度与右子树的深度之差。
平衡调整的四种方法:
第一种:LL型
第二种:RR型
第三种:LR型
第四种:RL型
7.4 散列表的查找技术
算法HashSearch1
int HashSearch1(int ht[],int m,int k)
{
j=H(k);
if(ht[j]==k)return j;
else if(ht[j]==Empty){ht[j]=k;return 0;}
i=(j+1)%m;
while(ht[i]!=Empty&&i!=j)
{
if(ht[i]==k) return i;
else i=(i+1)%m;
}
if(i==j)throw"溢出";
else{ht[i]=k; return 0;}
}
当从闭散列表中删除一个记录时,有两点需要考虑:
1) 删除一个记录一定不能影响以后的查找;
2) 删除记录后的存储单元应该能够为将来的插入使用。
开散列表的查找算法HashSearch2
Node<int>*HashSearch2(Node<int>*ht[],int m,int k)
{
J=H(k);
P=ht[j];
While((p!=NULL)&&(p->data!=k))
P=p->next;
If(p->data==k)return p;
Else
{
Q=new Node;q->data=k;
q->next=ht[j];ht[j]=q;
}
}
本章总结: