/*1.顺序查找
复杂性:O(n)
缺点:效率低,尤其是线性表的n很大时
优点:适用于顺序表和单链表,对元素排列次序没有要求。为新的元素插入提供了方便,不需要寻找插入位置
改进:
在已知各元素的查找概率不等的情况下,将元素按照从大到小进行排序
事先不知道各元素查找概率的情况下,每次查找一个元素,将它与前驱元素对调位置,使概率大的元素自然逐渐前移动
*/
/*数组前N个元素查找值为v的节点,查找成功返回数组下标,查找失败返回-1*/
int search(int *a,int n,v)
{
int i=0;
for(i=0;a[i]!=v&&i<n;i++);
if(i==n)
return -1;
else
return i;
}
/*head为链表的表头指针,v是要给定的查找的定值,查找成功返回地址,不成功返回NULL*/
typedef struct Link
{
int data;
struct Link *Next;
}Link;
Link* search_link(int v,Link *head)
{
Link *p;
p=head;
if(p!=NULL&&p->data!=v)
{
p=p->Next;
}
return p;
}
/*2.二分查找
优点:效率高
缺点:不适合链存储,必须有序存储,关键字要按照值不减或者不增的次序
复杂度:O(log2N)
*/
/*递增数组前N个元素查找值为v的节点,查找成功返回数组下标,查找失败返回-1*/
int bin_search(int *a,int v,int n)
{
int low=0,high=n-1,mid,i;
while(low<high)
{
mid=(low+high)/2;
if(a[mid]==v)
{
return mid;
}
else if(a[mid]>v)
{
high=mid-1;
}
else
{
low=mid+1;
}
}
return -1;
}
/*3.分块查找,对应分块存储*/
/*分两步进行,先查找结点属于哪一个块,在索引表里面查找的,数序递增可以二分法,块内可以顺序查找*/
/*a为顺序存储的线性表,idx是索引表,v是给定的值。m是总块数*/
typedef struct
{
int key;//索引表项结构
int start;//块起始位置
int len;//节点长度
}IDX ;
int blk_search(int *a,IDX *idx,int v,int m)
{
int low=0,high=m-1,mid,i,h;
while(low<=high)//二分法找块
{
mid=(high+low)/2;
if(v<idx[mid].key)
high=mid-1;
else if(v>idx[mid].key)
{
low=mid+1;
}
else
{
low=mid;
break;
}
}
if(low>=m)
{
return -1;//超过索引表的最大值
}
i=idx[low].start;//确定块的起始位置
h=i+idx[low].len;
while(i<h&&a[i]!=v)
{
i++;
}
if(a[i]!=v)
{
i=-1;
}
return i;
}
/*散列查找*/
/*用构造散列表时使用的函数对给定值进行运算,求得地址,用该地址存放的值与给定值比较,相同则成功,否则
按照构造散列表时解决冲突的方法到相应地址查找*/
/*实现开放定址法解决冲突的散列表的查找功能,其中参数v为要查找的值,t为散列表,大小是M,空位置用0表示。查找成功返回
位置,失败返回-1,*/
int hash_search(int v,int *t)
{
int addr,i;
addr=h(v);//计算哈希函数
for(i=0;i<M&&t[(addr+i)%M]!=0;i++)
{
if(t[(addr+i)%M]==v)
{
return ((addr+i)%M);
}
}
return -1;
}
几种常见的查找
最新推荐文章于 2023-02-20 18:02:47 发布