拉链法哈希表(实战)

哈希表(拉链法)

1.代码部分

1.1主文件
/*hash_main.cpp文件*/
#include"hasha.cpp"
#include"string.h"
#include"stdio.h"
#include"iostream"
#include<string>
int main()
{
  hash a;
 char buf[MAX_LINE]; /*缓冲区*/
 char num[MAX_LINE];//学号
 FILE *fp;            /*文件指针*/
 int len;             /*行字符个数*/
 if((fp = fopen("num.txt","r")) == NULL)
 {
 perror("fail to read");
 exit (1) ;
 }
//打开文件
 int k=0,l=0,j=0,mm=0;
 while(fgets(buf,MAX_LINE,fp) != NULL)
 {
 len = strlen(buf);
 if(k>0){
   //第二行开始载入
   a.deal1(len,buf);//行载入
 }
  k++;
 }
 while(1)
 {
 printf("\nplease input the number:");
 scanf("%s",num);//输入学号
a.deal2(num);//输出学号,姓名,考场等信息
 }
 fclose(fp);//关闭文件
  return 0;
}
1.2主要函数
/*hasha.cpp*/
#include"hhsh.h"
#include"string.h"
#include"stdio.h"
#include"iostream"
#include<stdlib.h>
#include<string>

hash::hash()//构造函数把每一个key赋值为0
{
  std::cout<<"load file successed"<<std::endl;
  int i=400;
  while(--i)stu[i].key=0;
}


void hash::deal1(int len,char *buf)//将每一行数据放入哈系表中
{

  int    l=0,j=0,mm=len;
  char char_num[1024];
  while(mm--)//载入学号和考号到缓存区用o分隔开
  {
    if(buf[l]<='9'&&buf[l]>='0')
    {
      char_num[j]=buf[l];
      j++;l++;
    }
    else l++;
    if(buf[l-1]<='9'&&buf[l-1]>='0'&&(buf[l]>'9'||buf[l]<'0'))
    {
      char_num[j]='o';
      j++;
}
 }

  l=-1;
  while(1)//将姓名和学号放入哈希表,如果序号为学号后三位的位置没有元素(key为		0)则将信息放在该位置并将key改为1,如果序号为1或者2则把信息放在这个		一个新节点并插入到位置的next,将key赋值2
  {
    ElemType *p;
    ++l;
    if(char_num[l+3]=='o')
    {
      j=(char_num[l]-'0')*100+(char_num[l+1]-'0')*10+(char_num[l+2]-'0');
      if(stu[j].key==0)
      {
        strncpy(stu[j].name,buf,6);
        strncpy(stu[j].num,char_num,l+3);
        stu[j].key=1;
      }
      else
      {
        ElemType *p;
        p=(ElemType*)malloc(sizeof(ElemType));
        p->next=stu[j].next;
        stu[j].next=p;
        strncpy(p->name,buf,6);
        strncpy(p->num,char_num,l+3);
        p->key=1;
        stu[j].key=2;
        }
        break;
    }
  }
  l+=3;
  mm=l;
  while(++l)//将学号放入哈希表
  {
    if(char_num[l]=='o')
    {
      if(stu[j].key==1){strncpy(stu[j].qq,char_num+mm+1,l-mm-1);
      break;}
      else {
          if(stu[j].key==2)
          strncpy(stu[j].next->qq,char_num+mm+1,l-mm-1);
          break;
      }
    }
  }

}
void hash::deal2(char*num)//输出学号为num学生的信息
{
  int j,k=11;
  ElemType *p;
  j=(num[8]-'0')*100+(num[9]-'0')*10+(num[10]-'0');
  switch (stu[j].key)//按照key值分三种情况,如果0说明没有该尾号的学生,如果是1则是只有一个学生,next指针为NULL,如果是二,则有至少两个学生,next接一个链表
  {
    case  0:
        printf("cannot find the guy");
        break;
    case  1:
        while(k--)
        {
          if(stu[j].num[k]!=num[k])break;
        }
        if(k>0)
        printf("cannot find the guy");
        else
        printf("name:%s  number:%s  candidate number:%s",stu[j].name,stu[j].num,stu[j].qq); /* code */
        break;

   case  2:
        k=12;
        while(k--)
        {
          if(stu[j].num[k]!=num[k])break;
        }
        if(k<=0)printf("name:%s  number:%s  candidate number:%s",stu[j].name,stu[j].num,stu[j].qq);
      else
      {
      p=stu[j].next;
      while(1)
      {
        k=12;
        while(k--)
        {
          if(p->num[k]!=num[k])break;
        }
        if(k>0)
        {
          if(p->next!=NULL)
          p=p->next;
          else
          {
            printf("cannot find the guy");
            break;
          }
          continue;
        }
        else
        {
                    printf("name:%s  number:%s  candidate number:%s",p->name,p->num,p->qq); /* code */
          break;
        }
        //break;
      }
      }
      break;
    default:
      break;
         }

}
1.3声明
/* hhsh.h文件*/
    #pragma warning(disable:4996)
     
    struct ElemType{
    	int key;
		char num[20];
		char qq[20];
		char name[7];
    	struct ElemType*next;//方便在采用链地址法时用的
    };//用于存储信息的结构体

	class hash{
		public:
		hash();
		void deal1(int,char*);
		void deal2(char *num);
		private:
		ElemType stu[400];
	};//哈希表
	
ps:

表格类似于这种
姓名 学号 考号
孙尖 16040410043 2019070001
廖劳 16070110015 2019070002
樊范 16070199006 2019070003

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值