查找函数集合

1.顺序表查找方法的优化:把关键值赋值给数组第一个元素即a[0]=key,保证了数组下标永远不会越界

函数实现:

int SequentialSearch1(int *a, int n, int x)

{
int i;
a[0] = x;   //哨兵
i = n;
while (a[i] != x)
{
i--;
}
return i;

}

2.有序表查找方法:

折半查找法(也称为二分查找法):要查找的线性表必须已经排好序,可以把折半查找法想象成一个尺子,你要在尺子上找到一个数可以采用下面步骤

基本步骤:

步骤一:记载数组第一个数为low,最后一个数为high,中间值mid=(low+high)/2,用low的值与关键值key作比较;

步骤二:如果大于key值就在尺子的左边区域查找同时令high=mid-1,继续步骤一,直到查找成功;

步骤三:如果小于key值就在尺子的右边区域查找同时令low=mid+1,继续步骤一,直到查找成功;

函数实现:

int BinSearch(int *a, int len, int x)
{
int mid, low=0, high=len-1;
while (low <= high)
{
mid = (low + high) / 2;
if (x < a[mid])
{
high = mid - 1;
}
else if (x>a[mid])
{
low = mid + 1;
}
else
{
return mid;
}
}
return -1;

}

二叉查找树(也称二叉排序树)的性质:

1.若左子树不为空,那么左子树上所有结点小于根结点的值;

2.若右子树不为空,那么右子树上所有结点大于根结点的值;

3.左右子树也分别为二叉排序数。

二叉查找树的优点:查找和插入函数很方便,但删除函数很复杂。

二叉树的查找采用的是递归函数调用,步骤:

步骤一:定义一个指针作为它的双亲结点并使其为NULL;

步骤二:定义一个指针记录访问的最后一个结点并返回true或false,如果找到就是true否则是flase。

实现代码:

typedef struct node
{
int data;
struct node *lchild;
struct node *rchild;

}BSTnode,*BSTtree;

int BSTsearch(BSTtree T, int key,BSTtree f,BSTtree *p)  p作为二级指针,因为要改变p的地址
{
if (T == NULL)
{
*p = f;
return -1;
}
else if ((T->data) == key)
{
*p = T;
return 0;
}
else if (T->data > key)
{
BSTsearch(T->lchild, key,T,p);
}
else{
BSTsearch(T->rchild, key,T,p);
}
}

二叉树的插入:步骤:

步骤一:判断要插入的数据在二叉查找树中是否已经存在,若存在,则不能插入,若不存在,就直接插入

步骤二:如果根结点不存在,该结点作为新的根结点;

步骤三:如果根结点存在,将关键值与该结点的数进行比较如果关键值小于该结点的值插到左孩子,否则插到右孩子

代码实现:

int BSTInsert(BSTtree *T,int key)
{
BSTtree p,s;
if (BSTsearch(*T, key,NULL,&p)== -1)
{
s = (BSTnode*)malloc(sizeof(BSTnode));
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 0;
}
else{
return -1;
}

}

二叉查找树的删除

步骤一:如果删除的结点为叶子结点,直接删除,不会对树的结构产生影响

步骤二:删除的结点有左孩子或右孩子,该结点删除后把它的左孩子或者右孩子连接在该结点上

步骤三:删除的结点既有左孩子又有右孩子,简单点就是指向该结点的左孩子结点,左孩子结点再指向它的右孩子结点,一直指向右孩子结点直到最后一个右孩子结点,把最后一个右孩子结点的值赋值给要删除的结点。

代码实现:

int Delete(BSTtree *p)
{
BSTtree q, s;
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 0;
}
int BSTdelete(BSTtree *T, int key)
{
if (!(*T))
{
return -1;
}
else{
if (key == (*T)->data)
{
int  n = Delete(T);
return n;
}
else if (key < (*T)->data)
{
BSTdelete(&(*T)->lchild, key);
}
else {
BSTdelete(&(*T)->rchild, key);
}
}

}

以上就是我的理解有的讲的不好希望大家不要介意,大家也可以给我提意见大家一起进步!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值