线性表的查找算法-C语言

一、 实验目的

了解查找的基本概念,理解顺序查找、折半查找和分块查找的思想,掌握折半查找过程的判定树构造方法,实现线性表的查找算法。

二、 实验内容

通过编写程序,实现线性表的查找算法。具体步骤如下:

  1. 在主函数中输入线性序列和关键字;
  2. 创建实现顺序查找和折半查找的子函数;
  3. 在主函数中通过switch语句选择调用相关函数实现查找。

三、 实验工具

Dev - C++

四、 实验代码

//Authors:xiaobei

//线性表的查找方法:顺序查找、二分查找
#include<stdio.h>
#include<stdlib.h>
#define MAXSIZE 10
#define OK 1;
//定义线性表数据项结构
typedef struct{
 int key;//关键字域
}ElemType;
//定义线性表结构
typedef struct{
 ElemType *R;
 int length;
}SSTable;
//初始化线性表
int InitList_SSTable(SSTable &L){
 L.R=(ElemType*)malloc(sizeof(ElemType)*MAXSIZE);
 if (!L.R){
  printf("初始化错误!");
  return 0;
 }
 L.length=0;
 return OK;
}
//函数赋值线性表
int Insert_SSTable(SSTable &L){
 int i,num;           //空出ST.R[0]的位置
 for(i=1;i<MAXSIZE;i++){
  printf("
【请依次输入关键字的值】
>>>");
  getchar();
  scanf("%d",&num);
  L.R[i].key=num;
  L.length++;
 }
 return OK;
}
//函数顺序查找线性表
int Search_Seq(SSTable ST, int key){
//在顺序表ST中顺序查找其关键字等于key的数据元素。若找到,则函数值为
//该元素在表中的位置,否则为0
 int i;
    ST.R[0].key = key;                            //“哨兵”
    for(i = ST.length; ST.R[i].key!=key; --i);   //从后往前找
    return i;                                         
}// Search_Seq
//函数折半查找线性表(非递归)
int Search_Bin(SSTable ST,int key){
   // 在有序表ST中折半查找其关键字等于key的数据元素。若找到,则函数值为
   // 该元素在表中的位置,否则为0
   int low=1,high=ST.length;       //置查找区间初值
   int  mid;
   while(low<=high) {
    mid=(low+high) / 2;
      if (key==ST.R[mid].key)
    return mid;              //找到待查元素
      else if(key<ST.R[mid].key)
    high = mid -1;        //继续在前一子表进行查找
      else  
    low =mid +1;                          //继续在后一子表进行查找
   }//while
   return 0;           //表中不存在待查元素
}// Search_Bin
//函数折半查找线性表(递归)
int Search_Bin2(SSTable ST,int key,int low,int high){
 int mid = (low+high) / 2;       //向下去整
 if (key==ST.R[mid].key)
  return mid;              //找到待查元素
      else if(key<ST.R[mid].key)
    Search_Bin2(ST,key,low,mid-1);     //继续在前一子表进行查找
      else
    Search_Bin2(ST,key,mid+1,high);
}
//函数显示顺序表查找结果
void Show_End(int result,int key){
 if(result==0)
  printf("
未找到%d
",key);
 else
  printf("
找到%d,位置为%d
",key,result);
 return;
}
//函数打印菜单
void Menu(){
 printf("
************菜单***********
");
 printf("
1.创建线性表;
");
 printf("
2.顺序查找;
");
 printf("
3.折半查找(非递归);
");
 printf("
4.折半查找(递归);
");
 printf("
0.退出;
");
 printf("
***************************
");
 printf("
【请输入你的选择】
>>>");
}
//主函数
int main(){
 SSTable ST;
 int key,result,user;
 while (true)
 {
  Menu();
  scanf("%d",&user);
  switch(user){
  case 1:{
   if(InitList_SSTable(ST) && Insert_SSTable(ST))
    printf("
【创建成功……】
");
   break;
  }
  case 2:{
   printf("
-----------顺序查找-----------
");
   printf("
【请输入要查找的关键字】
>>>");
   getchar();
   scanf("%d",&key);
   result = Search_Seq(ST,key);
   Show_End(result,key);
   printf("
-------------------------------
");
   break;
  }
  case 3:{
   printf("
-----------折半查找(非递归)-----------
");
   printf("
【请输入要查找的关键字】
>>>");
   getchar();
   scanf("%d",&key);
   result = Search_Bin(ST,key);
   Show_End(result,key);
   printf("
---------------------------------------
");
   break;
  }
  case 4:{
   printf("
-----------折半查找(递归)-----------
");
   printf("
【请输入要查找的关键字】
>>>");
   getchar();
   scanf("%d",&key);
   result = Search_Bin2(ST,key,1,ST.length);
   Show_End(result,key);
   printf("
-------------------------------------
");
   break;
  }
  case 0:exit(0);
  }
 }
 return 0;
}

五、实验结果

  1. 创建线性表

1
2
2. 顺序查找
3
3. 折半查找(非递归)
4
4. 折半查找(递归)
5
5. 退出

6

六、总结与思考

等概率查找下:

  1. 顺序查找

①优点:
算法简单,对表结构无任何要求,既适用于顺序结构,也适用于链式结构,无论记录是否按关键字有序都可应用。
②缺点:
平均查找长度太大,查找效率低,所以当n很大时,不宜采用顺序查找。

(时间复杂度O(n))

7

  1. 折半查找

①优点:
比较次数少,查找效率高。
②缺点:
对表结构要求高,只能用于顺序存储有序表,查找前需要排序,而排序本身是一种费时运算。因此折半查找不适于数据元素经常变动的线性表。

(时间复杂度O(log2n))

8

  1. 分块查找

①优点:
表中插入和删除数据元素时,只要找到该元素对应的块,就可以在该块内进行插入和删除操作,由于块内无序,所以插入和删除很容易,无需大量移动,如果线性表既要快速查找,又要动态变化,可采用分块查找。
②缺点:
要增加一个索引表的存储空间,并对初始索引表作排序运算。

(略)

原文地址:https://www.cnblogs.com/slz99/p/12527727.html