顺序查找
顺序查找又叫线性查找,是最基本的查找技术,它的查找过程是:从表中第一个记录开始,逐个进行记录的关键字和给定值比较,若某个记录的关键字和给定值相等,则查找成功,找到所查的记录;如果知道最后一个记录,其关键字和给定值比较都不等时,则表中没有所查的记录,查找不成功。
顺序查找算法实现代码如下:
/*顺序查找,a为数组,n为要查找的数组个数,key为要查找的关键字*/
int Sequential_Search(int *a,int n,int key)
{
int i;
for(i=1;i<=n;i++)
{
if(a[i] == key)
return i;
}
return 0;
}
代码很简单,就是在数组a中查看有没有关键字(key),当你需要查找复杂表结构的记录时,只需要把数组a与关键字key定义成你需要的表结构和数据类型即可。
这里并不够完美,因为每次循环时都需要对i是否越界做判断,事实上,还可以有更好一点的办法,设置一个哨兵,可以解决不需要每次让i与n做判断,实现代码如下:
int Sequential_Search(int *a,int n,int key)
{
int i;
a[0] = key;/*设置a[0]为关键字值,我们称之为‘哨兵’*/
i = n; /*循环从尾部开始*/
while(a[i] != key)
{
i--;
}
return i;
}
此时代码是从尾部开始查找,由于a[0]=key,也就是说,如果a[i]中有key则返回i,查找成功。否则一定在最终的a[0]处等于key,此时返回0,即说明a[1]~a[n]中没有关键字key,查找失败。
折半查找
折半查找(Binary Search)技术,又称为二分查找。它的前提线性表中的记录必须是关键码有序,线性表必须采用顺序存储。折半查找的基本思想是:在有序表中,取中间记录作为比较对象,若给定值与中间记录的关键字相等,则查找成功;若给定值小于中间记录的关键字,则在中间记录的左半区继续查找;若给定值大于中间记录的关键字,则在中间记录的右半区继续查找,不断重复上面过程,知道查找成功,或所有查找区域无记录,查找失败为止。实现代码如下:
int Sequential_Search(int *a,int n,int key)
{
int low,high,mid;
low = 1;
high = n;
while(low <=high)
{
mid = (low+high)/2;
if(key < a[mid])
high = mid - 1;
else if(key >a[mid])
low = mid + 1;
else
return mid;
}
return 0;
}
二叉排序树(Binary Sort Tree),又称为二叉查找树,它或者是一颗空树,或者具有下列性质的二叉树。
若它的左子树不为空,则左子树所有结点的值均小于它的根结点的值。
若它的右子树不为空,则右子树上所有结点的值均不大于根结点的值。
它的左,右子树也分别为二叉树。
二叉树的结构:
typedef struct BiTNode
{
int data;
struct BiTNode *lchild, *rchild;
} BiTNode , *BiTree;
二叉排序树的查找实现过程代码如下:
/**递归查找二叉树T中是否存在key,
指针f指向T的双亲,其初始调用值为NULL
若查找成功,则指针p指向数据元素结点,并返回TRUE,
否则指针p指向查找路径上访问的最后一个结点并返回FALSE
*/
Status SearchBST(BiTree T ,int key, BiTree f, BiTree *p)
{
if(!T)
{
*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);
else return SearchBST(T->rchild,key,T,p);
}
二叉排序树的插入操作
代码如下:
/**当二叉排序树T中不存在关键字等于key的数据元素时,
插入key并返回TRUE,否则返回FALSE
*/
Status InsertBST(BiTree *T,int key)
{
BiTree p,s;
if(!SearchBST(*T,key,NULL,&p))
{
s = (BiTree)malloc(sizeof(BiTNode));
s->data = key;
s->lchild = s->rchild = NULL;
if(!p)
{
*T = s;
}
else if(key < p->data)
p->lchild = s;
else
p->rchild = s;
return TRUE;
}
else
return FALSE;
}
二叉树的删除操作:
对二叉树结点的删除分三种情况:
叶子结点
仅有左或右子树
左右子树都有的结点。
我们来看代码,下面这个算法是递归方式对二叉树排序树T查找key,查找到并删除代码:
/**若二叉树T中存在关键字等于key的数据元素时,则删除该数据元素结点,
并返回TRUE,否则返回FALSE
*/
Status DeleteBST(BiTree *T,int key)
{
if(!*T)
return FALSE;
else
{
if(key == (*T)->data)
return Delete(T);
else if(key < (*T)->data)
return DeleteBST(&(*T)->lchild,key);
else
return DeleteBST(&(*T)->rchild,key);
}
}
Status Delete(BiTree *p)
{
BiTree q,p;
if((*p)->rchild == NULL)
{
q=*p;*p=(*p)->lchild;free(q);
}
else if((*p)->lchild == NULL)
{
q = *p; *p = (*p)->rchild;free(q);
}
else
{
q = *p;s = (*p)->lchild;
while(s->rchild)
{
q = s;s = s->rchild;
}
(*p)->data = s->data;
if(q!=*p)
q->rchild = s->lchild;
else
q->lchild = s->lchild;
free(s);
}
return TRUE;
}