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

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

}
}


  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值