实现查找的几种方法!
顺序查找 、二分查找、分块查找、二叉排序树查找
整理的比较乱,不要介意!
先整理一下最为重要的二分查找!
- <span style="font-size:18px;">/**
- * 二分发查找方法的实现
- * @param a 要查找的目标整型数组
- * @param num 要查找的(整)数
- * @return 查找到的结果(整数)
- */
- public int binarySearch(int[] a, int num) {
- Arrays.sort(a); //一定要排序后才能实现二分法查找
- int start = 0; //开始元素的索引
- int end = a.length - 1; //结束元素的索引(数组内元素的索引是当前长度小一位)
- int mid = (start + end) / 2; //中间元素的索引=(开始元素的索引+结束元素的索引)/2,这是死的所以写死没关系
- while(num!=a[mid]){ //用while循环判断当要找的数字不是当前数组的中间元素时,继续查找
- if(num<a[mid]){ //如果要找的数字小于当前数组的中间元素,即以中间索引的元素为分界
- end=mid-1; //当前数组中的结束元素索引递减1
- }else{ //如果要找的数字大于当前数组的中间元素
- start=mid+1; //当前数组中的开始元素索引递增1
- }
- mid=(start + end) / 2; //上面的田间判断完后,重新计算中间元素的索引
- }
- return a[mid]; //到这一步说明要找的数字已经找到了,所以返回这个数字
- /*总结:
- * 将要查找的数组排序,将数组以中间元素为分隔成两组元素,如果中间元素就是要找的数则返回,
- * 如果不是则判断是否比中间元素大,大则分到右手边的数组,小则分到左手边的数组,
- * 分完后要以当前数组为主,重新分配开始索引,中间索引和结束索引,
- * 以此类推以循环为条件最终得到要查找的数。
- * */
- }
- </span>
说明:顺序查找适合于存储结构为顺序存储或链接存储的线性表。
int SequelSearch(elemtype s[],keytype Key,int n)
/*在s[0]-s[n-1]中顺序查找关键字为Key的记录*/
/*查找成功时返回该记录的下标序号;失败时返回-1*/
{
int i;
i=0;
while(i<n&&s[i].Key!=Key)i++;
if(s[i].Key==Key)return i;
else return -1;
}
----------------------------
二分查找
1、递归方法实现:
int BSearch(elemtype a[],elemtype x,int low,int high)
/*在下届为low,上界为high的数组a中折半查找数据元素x*/
{
int mid;
if(low>high) return -1;
mid=(low+high)/2;
if(x==a[mid]) return mid;
if(x<a[mid]) return(BSearch(a,x,low,mid-1));
else return(BSearch(a,x,mid+1,high));
}
2、非递归方法实现:
int BSearch(elemtype a[],keytype key,int n)
{
int low,high,mid;
low=0;high=n-1;
while(low<=high)
{
mid=(low+high)/2;
if(a[mid].key==key) return mid;
else if(a[mid].key<key) low=mid+1;
else high=mid-1;
}
return -1;
}
--------------------------
分块查找
typedef int keytype;
typedef struct
{
keytype Key;
}elemtype;
typedef struct
{
keytype Key;
int Link;
}indextype;
int IndexSequelSearch(indextype ls[],elemtypes[],int m,int l,keytype Key)
/*分块查找关键字为Key的记录。索引表为ls[0]-ls[m-1]*/
/*顺序表为s,块长为l*/
{
int i,j;
/*在索引表中顺序查找*/
i=0;
while(i<m&&Key>ls[i].Key)i++;
if(i>=m)return -1;
else
{
/*在顺序表中顺序查找*/
j=ls[i].Links;
while(Key!=s[j].Key&&j-ls[i].Link<l)j++;
if(Key==s[j].Key)return j;
else return -1;
}
}
----------------------------
二叉排序树查找
1、二叉排序树查找算法:
a、非递归算法:
btree *search(btree *b,int x)
/*在二叉树b中查找x的过程*/
{
if(b=NULL) return(NULL);
else
{
if(b->data==x) return(b);
if(x<b->data) return(search(b->left));
else return(search(b->right));
}
}
b、递归算法:
bsnodetype *Search(bsnodetype *bt,keytype Key)
/*在二叉树bt中查找元素为Key的元素*/
{
bsnodetype *p;
if(bt==NULL) return(bt);
p=bt;
while(p->Key!=Key)
{
if(Key<p->Key) p=p->Lchild;
else p=p->Rchild;
if(p==NULL)break;
}
return(p);
}
2、二叉树的生成
a、向一个二叉树b中插入一个结点s的函数如下:
void insert(b,s)
btree *b,*s;
{
if(b==NULL) b=s;
else if(s->data==b->data)
return();
else if(s->data<b->data)
insert(b->left,s);
else if(s->data>b->data)
insert(b->right,s);
}
b、生成二叉树
void create(btree *b)
{
int x;
btree 8s;
b==NULL;
do
{
scanf("%d",&x);
s=(bnode *)malloc(sizeof(bnode));
s->data=x;
s->left=NULL;
s->right=NULL;
insert(b,s);
}while(x!=-1);
}
c、从二叉树中删除一个结点
bsnodetype *Delete(bsnodetype *bt,keytype Key)
/*在bt为根结点的二叉树中删除值为Key的结点*/
{
bsnodetype *p,*q;
if(bt->Key==Key)
{
/*bt的左右子树均为空*/
if(bt->Lchild==NULL&&bt->Rchild==NULL)
{
free(bt); /*删除叶结点*/
return(NULL);
}
else if(bt->Lchild==NULL)/*bt的左子树为空*/
{
p=bt->Rchild;
free(bt);
return(p);
}
else if(bt->Rchild==NULL)/*bt的右子树为空*/
{
p=bt->Lchild;
free(bt);
return(p);
}
else
{
p=q=bt->Rchild;
while(p->Lchild!=NULL)p=p->Lchild;
p->Lchild=bt->Lchild;
free(bt);
return(q);
}
}
/*在bt->Lchild为根结点的二叉树中删除值为Key的结点*/
if(bt->Key>Key&&bt->Lchild!=NULL)
bt->Lchild=Delete(bt->Lchild,Key);
/*在bt->Rchild为根结点的二叉树中删除值为Key的结点*/
if(bt->Key<Key&&bt->Rchild!=NULL)
bt->Rchild=Delete(bt->Rchild,Key);
return(bt);
}