#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();}}