数据结构的静态查找(C语言实现)

来源:互联网 发布:网络安全意识培训内容 编辑:程序博客网 时间:2024/05/01 20:25
 
#include "string.h"#include "stdio.h"#include "string.h"#include "malloc.h"#define ERROR 0;#define TRUE 1;#define OK 1;typedef char KeyType;typedef struct{ KeyType key;}ElemType; typedef struct{ //顺序存储结构 ElemType elem[100]; int length;}SSTable;SSTable ST,Idx,Bi; //定义查找表ST为全局变量 //定义分块有序表Idx的存储typedef struct{ //索引表存储结构 KeyType key; int link;}IdxType;IdxType index[50]; //定义索引表为全局变量int e,bi; //e,bi为全局变量,分别是索引表中每块表记录的个数和块数,全局变量方便踌函数调用 void Creat_ST() //构造一个含n个数据元素的表态查找表ST{ int n,i,j=0; char s[100]; printf("你需要构造多少个数据?请输入:"); scanf("%d",&n); printf("\n"); while(n<0||n>100) {  printf("抱歉,系统暂时无法完成你需要的个数的操作,请重输:\n");  getchar();  scanf("%d",&n);   } printf("接着,请输入%d个数据,以构造一个数据表\n",n); getchar(); gets(s); for(;s[j]!='\0';j++)  ST.elem[j].key=s[j];  ST.length=j; printf("你输入了%d个数据!它们是:\n",j); for(i=0;i<j;i++)  printf("%c ",ST.elem[i].key); printf("\n");}void Destroy_ST() //销毁表ST{ int i; if(!ST.elem[0].key)  printf("错误!原表为空,销毁失败。\n"); else {for(i=ST.length-1;i<0;i--)  free(ST.elem[i].key); //从表尾开始销毁 ST.length=0;  printf("原表销毁成功!\n"); }}int Search_Seq() //顺序查找{ KeyType ky; int i; if(ST.length==0) {printf("查找表为空,请先建表!\n"); return ERROR;}  printf("要查找的数据:\n"); scanf("%c",&ky); ST.elem[ST.length+1].key=ky; //哨兵 for(i=0;ST.elem[i].key!=ky;i++); //从前往后找  //i为要查找元素在表中位置,若失败,为0 if(i<=ST.length)printf("恭喜,查找成功!该数据在表的第%d个位置上。\n",i+1); else printf("抱歉,查找失败!\n");}void visit_S() //被 Trave_ST函数调用{ int i; printf("ST表中的元素如下:\n"); for(i=0;i<ST.length;i++)  printf("%c ",ST.elem[i].key);  printf("\n");}void Trave_ST() //遍历查找表,其中对ST的每个元素调用函数visit_S{ if(ST.length==0)  printf("错误,原表为空,遍历失败!"); else  visit_S();}void Creat_Bi() //构造一个含n个数据元素的表态查找表Bi,数据实现有序排列{ int n,i,j=0; char c; char s[100]; printf("你需要构造多少个数据?请输入:"); scanf("%d",&n); printf("\n"); while(n<0||n>100) {  printf("抱歉,系统暂时无法完成你需要的个数的操作,请重输:\n");  getchar();  scanf("%d",&n);   } printf("接着,请输入%d个数据,以构造一个数据表\n",n); getchar(); gets(s); for(;s[j]!='\0';j++)  Bi.elem[j].key=s[j];  Bi.length=j; printf("你输入了%d个数据!它们是:\n",j); for(i=0;i<Bi.length;i++)    printf("%c ",Bi.elem[i].key);   printf("\n"); for(i=0;i<j;i++)  printf("%c ",ST.elem[i].key); printf("\n"); for(j=0;j<Bi.length-1;j++)  for(i=0;i<Bi.length-1-j;i++)   if(Bi.elem[i].key>Bi.elem[i+1].key)   {    c=Bi.elem[i].key;    Bi.elem[i].key=Bi.elem[i+1].key;    Bi.elem[i+1].key=c;   }   printf("你输入的数据有序排列后为:\n");   for(i=0;i<Bi.length;i++)    printf("%c ",Bi.elem[i].key);   printf("\n");}void Destroy_Bi() //销毁表Bi{ int i; if(!Bi.elem[0].key)  printf("错误!原表为空,销毁失败。\n"); else {for(i=Bi.length-1;i<0;i--)  free(Bi.elem[i].key); //从表尾开始销毁 Bi.length=0;  printf("原表销毁成功!\n"); }}int Search_Bin() //有序查找{ KeyType ky; int i; int high,mid; int low=0; if(Bi.length==0) {printf("查找表为空,请先建表!\n"); return ERROR; }  high=Bi.length; printf("要查找的数据:\n"); scanf("%c",&ky); while(low<=high) {  mid=(low+high)/2;  if(Bi.elem[mid].key==ky)  {printf("恭喜,查找成功!该数据在表的第%d个位置上。\n",mid+1);  return;  }  else if(ky<Bi.elem[mid].key)   high=mid-1;  else   low=mid+1; } printf("抱歉,查找失败!\n");}  void visit_B() //被 Trave_Bi函数调用{ int i; printf("Bi表中的元素如下:\n"); for(i=0;i<Bi.length;i++)  printf("%c ",Bi.elem[i].key);  printf("\n");}void Trave_Bi() //遍历查找表,其中对Bi的每个元素调用函数visit_B{ if(Bi.length==0)  printf("错误,原表为空,遍历失败!"); else  visit_B();}void Creat_Idx() //构造一个含n个数据元素的索引查找表Idx,因为时间和水平有限,算法中要求读者有序输入数据{ int n,i,j=0; //n为有序表中数据个数 char s[100]; char c; printf("你需要构造多少个数据?请输入:"); scanf("%d",&n); printf("\n"); while(n<0||n>100) {  printf("抱歉,系统暂时无法完成你需要的个数的操作,请重输:\n");  getchar();  scanf("%d",&n);   } printf("接着,请输入%d个数据,以构造一个数据表\n",n); getchar(); gets(s); //如果输入的数据串大于n,系统将自动进行截断处理 for(i=0;i<n;i++) {     if(i>1) //当已输入的数据多于一个时  while(s[i]<s[i-1]) //检查当前输入的数据是否比前一个数据大   //如果大于前者,要求重输,并自动覆盖当前检测到的数据  { printf("你输入的第%d个数据比前一个数小了,请重输一个比%c大的数据: ",i+1,s[i-1]);   scanf("%c",&c);   s[i]=c;   getchar();  }   } //完成数据输入  for(;s[j]!='\0';j++)  Idx.elem[j].key=s[j];  Idx.length=j; printf("你输入的数据中%d个有效!它们是:\n",n); Idx.length=n; for(i=0;i<n;i++)  printf("%c ",Idx.elem[i].key); printf("\n"); printf("你想把有序表分成多少块?__"); //索引表 scanf("%d",&bi);  while(bi<1||bi>100||n/bi<1){  printf("\n输入错误或表中数据个数少于%d个,请重输要分的块数! ",bi);  scanf("%d",&bi);  e=n/bi;} e=n/bi; //每块记录个数 i=0; for(j=0;j<bi;j++) //建立索引表数组 {index[j].key=Idx.elem[i].key; //初始化  index[j].link=i; //link即为Idx中元素的标记号  for(i=(j?e*j-1:0);i<j*e+e-1;i++) //插入条件判断语句,实现跳跃前移  {      if(Idx.elem[i+1].key>Idx.elem[i].key) //后面的大,重新赋值给index   {index[j].key=Idx.elem[i+1].key;   index[j].link=i+1;}   else //保持不变   { index[j].key=Idx.elem[i].key;    index[j].link=i;   }  } //for i } //for j printf("你建立的索引表为:\n"); for(i=0;i<bi;i++) {  printf("块中最大数据: %c, 位置:%d \n",index[i].key,index[i].link+1);    } }void Destroy_Idx() //销毁表Idx{ int i; if(!Idx.elem[0].key)  printf("错误!原表为空,销毁失败。\n"); else {for(i=Idx.length-1;i<0;i--)  free(Idx.elem[i].key); //从表尾开始销毁 Idx.length=0;  printf("原表销毁成功!\n"); }}void IdxSerch() //索引表查找{ int low=0,high=bi-1,mid,i; int fl=0; char ky;  if(Idx.length==0) {printf("查找表为空,请先建表!\n"); return ;} printf("请输入你要查找的数据:_\n"); getchar(); scanf("%c",&ky);  while(low<=high) {  mid=(low+high)/2;  if(index[mid].key<ky)   low=mid+1;  else   high=mid-1; } if(low<bi) {  for(i=index[low].link;i<=index[low].link+e-1&&i<Idx.length;i++)   if(Idx.elem[i-1].key==ky) //此处,如果用Idx.elem[i]将查找表中首元素失败   {printf("恭喜,查找成功!该数据在表的第%d个位置上。\n",i);fl=1;}     } if(fl==0)printf("抱歉,查找失败!\n");    } void visit_Idx() //被 Trave_Idx函数调用{ int i; printf("Idx表中的元素如下:\n"); for(i=0;i<Idx.length;i++)  printf("%c ",Idx.elem[i].key);  printf("\n");}void Trave_Idx() //遍历查找表,其中对Bi的每个元素调用函数visit_B{ if(Idx.length==0)  printf("错误,原表为空,遍历失败!"); else  visit_Idx();}  int menu(a)//可以公用的分菜单{int i;printf("\n\n\n");for(i=0;i<80;i++)printf("-");printf("\n");printf("1.构建查找表\t\t2.销毁查找表\t\t3.在表中查找元素\n");printf("4.遍历表中记录\t\t5.返回上层主菜单\t\t0.退出本系统\n"); for(i=0;i<80;i++)    printf("-");printf("\n");printf("\t\t请输入0——5选择:");scanf("%d",&a);   getchar(); return (a);} void MENU_All() //主菜单{int a;int i,flag,go;printf("\n\n\n");for(i=0;i<80;i++)printf("^");for(i=0;i<80;i++)printf("^"); printf("\t\t\t欢迎使用静态查找表系统\n"); printf("\t<作者:CPU温度 年级:2008级软件工程二班 学号:310800CPU温度>\n");    for(i=0;i<80;i++)         printf("*");printf("\n");printf("1.顺序表的查找\t\t2.有序表的查找(折半查找)\t\t3.索引表顺序查找\n");printf("0.退出本系统\n");for(i=0;i<80;i++)    printf("*");printf("\n");printf("\t\t现在,请输入0——3选择您的操作(继续或退出):");scanf("%d",&go);   getchar();   switch(go) {case 1:  {  for(i=1;a!=5;i++)  {  a=menu(a);  switch(a)   {   case 1: Creat_ST();break;   case 2: Destroy_ST();break;   case 3: Search_Seq();break;    case 4: Trave_ST();break;   case 5:break;//跳出顺序表查找的循环,回到上一层菜单   case 0: exit(0);    default:printf("选择错误,请重选!\n\n");    }      }//for break; } //case 1 case 2:   {  for(i=1;a!=5;i++)  {  a=menu(a);  switch(a)  {case 1: Creat_Bi();break;  case 2: Destroy_Bi();break;  case 3: Search_Bin();break;   case 4: Trave_Bi();break;  case 5:break;//跳出有序表的查找(折半查找)的循环,回到上一层菜单  case 0: exit(0);   default:printf("选择错误,请重选!\n\n"); }  }  break;   }//case 2 case 3:   {  for(i=1;a!=5;i++)  {  a=menu(a);  switch(a)  {case 1: Creat_Idx();break;  case 2: Destroy_Idx();break;  case 3: IdxSerch();break;  case 4: Trave_Idx();break;  case 5:break;//跳出索引表顺序查找的循环,回到上一层菜单  case 0: exit(0);   default:printf("选择错误,请重选!\n\n"); }  }  break;   }//case 3 case 0: exit(0);  default:printf("选择错误,请重新输入你的操作选择!\n\n");  } }void main() {int a,b;int i;for(i=1;;i++){  if(i>1) {printf("\n请注意,系统即将刷新清屏并回到主菜单,请记住当前操作!\n\n");  system("PAUSE"); //暂停函数   system("cls");   //清屏函数 }  MENU_All();}}