编程语言应用

首页 » 常识 » 问答 » C语言编程九种必会查找算法附完整代码
TUhjnbcbe - 2020/12/7 2:05:00
时间、空间复杂度比较查找算法平均时间复杂度空间复杂度查找条件顺序查找O(n)O(1)无序或有序二分查找(折半查找)O(log2n)O(1)有序插值查找O(log2(log2n))O(1)有序斐波那契查找O(log2n)O(1)有序哈希查找O(1)O(n)无序或有序二叉查找树(二叉搜索树查找)O(log2n)红黑树O(log2n)2-3树O(log2n-log3n)B树/B+树O(log2n)1顺序查找

算法思路:

对于任意一个序列,从一端开始,顺序扫描,依次将扫描到的结点关键字与给定值k相比较,若相等则表示查找成功;若扫描结束仍没有找到关键字等于k的结点,表示查找失败。

代码:

#includestdio.h#includestdlib.h#definekeyTypeint//.05.24typedefstruct{  keyTypekey;//查找表中每个数据元素的值}ElemType;typedefstruct{  ElemType*elem;//存放查找表中数据元素的数组  intlength;//记录查找表中数据的总数量}SSTable;//创建查询数据voidCreate(SSTable**st,intlength){  (*st)=(SSTable*)malloc(sizeof(SSTable));  (*st)-length=length;  (*st)-elem=(ElemType*)malloc((length+1)*sizeof(ElemType));  printf("输入表中的数据元素:\n");  //根据查找表中数据元素的总长度,在存储时,从数组下标为1的空间开始存储数据  for(inti=1;i=length;i++)  {    scanf("%d",((*st)-elem.key));  }}//顺序查找函数,其中key为要查找的元素intSearch_seq(SSTable*str,keyTypekey){  //str-elem[0].key=key;//将关键字作为一个数据元素存放到查找表的第一个位置,起监视哨的作用  intlen=str-length;  //从最后一个数据元素依次遍历,一直遍历到数组下标为0  for(inti=1;ilen+1;i++)//创建数据从数组下标为1开始,查询也从1开始  {    if(str-elem.key==key)    {      returni;    }  }  //如果i=0,说明查找失败;查找成功返回要查找元素key的位置i  return0;}intmain(){  SSTable*str;  intnum;  printf("请输入创建数据元素的个数:\n");  scanf("%d",num);  Create(str,num);  getchar();  printf("请输入要查找的数据:\n");  intkey;  scanf("%d",key);  intlocation=Search_seq(str,key);  if(location==0){    printf("查找失败");  }else{    printf("要查找的%d的顺序为:%d",key,location);  }  return0;}

运行结果:

查找成功查找失败2二分查找(折半查找)

算法思路:

确定查找范围low=0,high=N-1,计算中项mid=(low+high)/2。

若mid==x或low=high,则结束查找;否则,向下继续。

若amidx,说明待查找的元素值只可能在比中项元素大的范围内,则把mid+1的值赋给low,并重新计算mid,转去执行步骤2;若midx,说明待查找的元素值只可能在比中项元素小的范围内,则把mid-1的值赋给higt,并重新计算mid,转去执行步骤2。

说明:

查找元素必须是有序的,如果是无序的则要先进行排序操作。

在做查找的过程中,如果low指针和high指针的中间位置在计算时位于两个关键字中间,即求得mid的位置不是整数,需要统一做取整操作。

折半查找的前提条件是需要有序表顺序存储,对于静态查找表,一次排序后不再变化,折半查找能得到不错的效率。但对于需要频繁执行插入或删除操作的数据集来说,维护有序的排序会带来不小的工作量,那就不建议使用。

——《大话数据结构》

代码:

#includestdio.h#includestdlib.h#definekeyTypeinttypedefstruct{  keyTypekey;//查找表中每个数据元素的值}ElemType;typedefstruct{  ElemType*elem;//存放查找表中数据元素的数组  intlength;//记录查找表中数据的总数量}SSTable;//创建查询数据voidCreate(SSTable**st,intlength){  (*st)=(SSTable*)malloc(sizeof(SSTable));  (*st)-length=length;  (*st)-elem=(ElemType*)malloc((length+1)*sizeof(ElemType));  printf("输入表中的数据元素:\n");  //根据查找表中数据元素的总长度,在存储时,从数组下标为1的空间开始存储数据  for(inti=1;i=length;i++)  {    scanf("%d",((*st)-elem.key));  }}//折半查找函数key为要查找的元素intSearch_Bin(SSTable*str,keyTypekey){  intlow=1;//初始状态low指针指向第一个关键字  inthigh=str-length;//high指向最后一个关键字  intmid;  while(low=high)  {    mid=(low+high)/2;//int本身为整形,所以,mid每次为取整的整数    if(str-elem[mid].key==key)//如果mid指向的同要查找的相等,返回mid所指向的位置    {      returnmid;    }elseif(str-elem[mid].keykey)//如果mid指向的关键字较大,则更新high指针的位置    {      high=mid-1;    }    //反之,则更新low指针的位置    else    {      low=mid+1;    }  }  return0;}intmain(){  SSTable*str;  intnum;  printf("请输入创建数据元素的个数:\n");  scanf("%d",num);  Create(str,num);  getchar();  printf("请输入要查找的数据:\n");  intkey;  scanf("%d",key);  intlocation=Search_Bin(str,key);  if(location==0){    printf("没有查找到");  }else{    printf("要查找的%d的顺序为:%d",key,location);  }  return0;}

运行结果:

查找成功没有查找到3插值查找

插值查找基于二分查找算法,将查找点的选择改进为自适应选择,可以提高查找效率。当然,差值查找也属于有序查找

算法思路:

确定查找范围low=0,high=N-1,计算中项mid=low+(key-a[low])/(a[high]-a[low])*(high-low)。

若mid==x或low=high,则结束查找;否则,向下继续。

若amidx,说明待查找的元素值只可能在比中项元素大的范围内,则把mid+1的值赋给low,并重新计算mid,转去执行步骤2;若midx,说明待查找的元素值只可能在比中项元素小的范围内,则把mid-1的值赋给higt,并重新计算mid,转去执行步骤2。

说明:

插值查找是基于折半查找进行了优化的查找方法。当表长较大,而关键字分布又比较均匀的查找表来说,插值查找算法的平均性能要比折半查找要好得多。

代码:

#includestdio.hintarray[10]={1,4,9,16,27,31,33,35,45,64};intInsertionSearch(intdata){intlow=0;inthigh=10-1;intmid=-1;int

1