⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 哈希表学生管理系统.cpp

📁 数据结构课程设计(严蔚敏c版) 哈希表学生管理系统
💻 CPP
字号:
/*******************************************************************************

    
程序名称 : 哈希表学生管理系统

作者 : 040540227 张欢

单位 : 南京航空航天大学信息科学与技术学院

完成时间 : 2007年1月10号

程序功能 : 1.把学生的信息(姓名,学号)插到哈希表中。
           2.按照姓名或学号查找学生。
		   3.删除某学生。
           4.查看哈希表内容。
		   5.修改某学生的信息。

主要用的知识 : 哈希表存储方式,链地址解决冲突,函数调用,循环控制,字符串处理等等。 


希望广大用户及时反馈意见以便我们为您提供更好的服务,谢谢!
		   

********************************************************************************/

#include"stdio.h"
#include"conio.h"
#include"string.h"
#include"stdlib.h"


typedef struct student                     //学生结点
{
	char name[16];
	char number[11];
    struct student *next;          

}student;

/**************************************全局变量***********************************/
 
student *HashTable[16];                    //数组里的16个值元素都是头指针(什么都不存),全局变量
char name[16];
char number[11];
int  location;                              //地址
	
/*************************************哈希函数***********************************/

int Hash(char *str)                        //哈希函数
{
	int i;

	i = strlen(str);

	return i;
}

/*********************************按姓名查找************************************/

student  *search1(char *name)              //按姓名查找的简单,因为可以用哈希函数
{   
	student *p;

	location = Hash(name);                 //此同学应该存放的地址
	
	p = HashTable[location];

	while (p && strcmp(p->name,name))      //p指针不空并且p->name不是要找的那个name则循环进行
	     p = p->next;
 
	if (!p)
	
   	    return NULL;                      //返回空指针 
	
    else
    
		return p;                          //返回指针p
	 
}
     
/*********************************按学号查找************************************/

student  *search2(char *number)                          
{   
	int i;
	student *p,*q;

	for(i = 0 ; i < 16 ; i++)
	{ 
	     p = HashTable[i];
    
	     if (p == NULL)              //该地址上没有元素的情况
		      
			 continue;              //p等于下一个位置上的指针
	
	     else if (p->next == NULL)   //该地址上只有1个元素的情况
		 {
		   if (strcmp(p->number,number))
			
			   continue;
		   
		   else
		  
		       return p;
		    
		      
		 }
	
        else                          //该地址上多于1个元素的情况
		{
		      
		      q = HashTable[i];       //此时p和q都是HashTable[i]
	
              while (p && strcmp(p->number,number))          //p指针不空并且p->name不是要找的那个name则循环进行
			  {
		         q = p;              //保持q在p的前面
		         
				 p = p->next;
			  }

	          if (!p)
		      
				  continue;        

	          else                   //p指针所指的结点 p->name就是要查找的name
			  
		          return p;
			  
		} 
	} 
    
    
	return NULL;                    //如果直到i=16时才结束,正常结束,则没有找到该学号的学生
	
}

/*******************************插入某指针指向的结点*****************************/

void ins(student *q)
{
    location = strlen(q->name);

	if (HashTable[location] == NULL)          //此位置上还没有插入一个元素
	{
		HashTable[location] = q;           // HashTable[location]指向node

		q->next = NULL;
	}
        
	else                                      //向前插
	{
		q->next = HashTable[location];     //HashTable[location] 是指针!!
	    
		HashTable[location] = q;
		
	}

}

/*********************************删除p指针所指的结点****************************/

void del(student *p)                //删除p指针所指向的结点
{   
	student *q;
	int location = Hash(p->name);   //找到地址

	if (p->next == NULL)             //要删除的元素所在地址上只有1个元素的情况
	{
		 HashTable[location] = NULL;	  
		 
		 free(p);
	}
		 
	 
	
    else                           //要删除的元素所在地址上多于1个元素的情况
	{
		 p = HashTable[location];
		
		 q = HashTable[location];
	
         while (p && strcmp(p->name,name))          //p指针不空并且p->name不是要找的那个name则循环进行
		 {
		    q = p;                 //保持q在p的前面
		    
			p = p->next;
		 }
                                   //循环结束时已经找到要删的结点了
	        q->next = p->next;
	        
			free(p);               //删除p结点
	 }

}

/************************************插入****************************************/

void Insert()                      //插入完成
{   
	
	 
	student *node;
	
	 
	printf("请输入要插入的同学的姓名(汉语拼音,字符不多于15个):\n");
	gets(name);

	printf("请输入要插入的同学的学号(不多于10位):\n");
	gets(number);
    
	 

	node = (student *)malloc(sizeof(struct student));
	
	node->next = NULL;
	
	strcpy(node->name,name);          //复制字符串
	
	strcpy(node->number,number);
	
	location = Hash(node->name);      //找到应该插入的位置

	if (HashTable[location] == NULL)   //此位置上还没有插入一个元素
	{
		HashTable[location] = node;   // HashTable[location]指向node
        
		printf("  插入完成!\n\n");
	}

	else                              //向前插
	{
		node->next = HashTable[location];     //HashTable[location] 是指针!!
	    
		HashTable[location] = node;
		
		printf("  插入完成!\n\n");
	}

}

 
void Delete()                                //按姓名删除
{
    student *p; 
	char info[16];
	
	printf("请输入要删除的同学的姓名或学号:\n");
	gets(info);

	if (info[0] >= '0' && info[0] <= '9')    //知道输入的是学号
	{ 	   
		p = search2(info);
		
		if(!p)
		{
			printf("没有此学号的学生,无法修改信息!\n\n");
		   
			return;
		}

		else
		{
			del(p);
	 	
			printf("删除成功!\n\n");
			
			return;
		}
	}

	else
	{
		p = search1(info);
		
		if (!p)
		{
			printf("没有此学号的学生,无法修改信息!\n\n");
		    
			return;
		}
	
		else
		{
			del(p);
	 	    
			printf("删除成功!\n\n");
			
			return;
		}

	}
}

/**********************************输出哈希表全部的内容*******************************/

void print()
{   
	int i ;
	student *p ;
	
	printf("哈希表的所有元素及所在地址如下:\n");
	
	for (i = 0 ; i < 16 ; i++)
	{
		printf("%-2d :",i);
		
		if (!HashTable[i])        
	
			printf("\n");                           //如果是空指针
		
		else                                    //输出该地址下所有的元素
		{
			for(p = HashTable[i] ; p ; p = p->next)
			{
				printf("%s",p->name);           //姓名
				
				printf("(%s)",p->number);       //学号
			   
				if (p->next)
			 
					printf("--->");
			}
		    
			printf("\n");
		} 
		 
	}
}

/******************************************修改内容**************************************/


void change()                                      //虽然复杂,但是思想简单
{   
	char ch;
	char info[16];                                 //可以放姓名可以放学号
	char str[16];
	char c;
	int i;
	student *p, *q;
	
	printf("请输入你要更改信息的学生的姓名或学号:\n"); //这里我用了一个小技巧
	gets(info);

	if (info[0] >= '0' && info[0] <= '9')          //知道输入的是学号
	{	
		p = search2(info);

		if (!p)
		{	
			printf("没有此学号的学生,无法修改信息!\n\n");
		    return ;
		}

		else                                        //要修改的人在哈希表中
		{   
			i=strlen(p->name);

			printf("你要修改姓名,还是学号?请选择1.姓名.2.学号.\n");
		    
			c = getch();
			
			if (c == '1')
			{   
		    	printf("\n此人姓名是:%s.请输入改变后的姓名(如果新名字长度和原来不一样,则此学生将要换到哈希表中的另一个位置上!):\n",p->name);

			  	gets(str);
				
				if (strlen(str)!=strlen(p->name))
				{   
					q = (student *)malloc(sizeof(struct student));
                                                    //申请新的结点
				    strcpy(q->number,p->number);    //学号保留到q上

					del(p);
					
					strcpy(q->name,str);            //换上新名字,把q所指结点插入到合适的位置上

					ins(q);                         //插入q所指的结点

					printf("姓名更改完毕,该学生已经由原位置%d转移到位置%d上了!\n\n",i,strlen(q->name));
			 
		            printf("\n");
				}

				else
                {
					strcpy(p->name,str);            //新名字和原来一样长的
                     
				    printf("姓名更改完毕!\n");
				}   
				 
			}
		
			else                                     //c==2修改学号
			{
				printf("此人学号是:%s.请输入改变后的学号:",p->number);
			    
				gets(str);
			 	
				strcpy(p->number,str);
				
				printf("学号更改完毕!\n");
				 
			}

		}
	}
	
    else                                             //知道输入的是姓名
	{	
		p = search1(info);

	 
	    
		if (!p)
		{	
			printf("没有此姓名的学生,无法修改信息!\n\n");
		
			return ;
		}
        
		else
		{	
			i = strlen(p->name);
			
			printf("你要修改姓名,还是学号?请选择1.姓名.2.学号.\n");
		    
			c = getch();
			
			if (c == '1')
			{
				printf("\n此人姓名是:%s.请输入改变后的姓名(如果新名字长度和原来不一样,则此学生将要换到哈希表中的另一个位置上!):\n",p->name);

			   
				gets(str);
				
				if (strlen(str)!=strlen(p->name))
				{   
					q = (student *)malloc(sizeof(struct student));
                                                    //申请新的结点
				    strcpy(q->number,p->number);    //学号保留到q上

					del(p);
					
					strcpy(q->name,str);            //换上新名字,把q所指结点插入到合适的位置上

					ins(q);

					printf("姓名更改完毕,该学生已经由原位置%d转移到位置%d上了!\n\n",i,strlen(q->name));
			 
		            printf("\n");
				}

				else
                {
					strcpy(p->name,str);            //新名字和原来一样长的

				    printf("姓名更改完毕!\n\n");
				}
				 
			}
		
			else                                     //c==2修改学号
			{
				printf("此人学号是:%s.请输入改变后的学号:",p->number);
			    
				gets(str);
			 	
				strcpy(p->number,str);
				
				printf("学号更改完毕!\n\n");
				 
			}

		}
	}

 }

/**************************************两种方式查找**************************************/

void  search()                                      //先编查找,两种方式查找
{
 
    char c;

	printf("你是按姓名查找还是按学号查找?请选择:1.姓名. 2.学号.\n");
    
	c = getch();

	if (c == '1')
	{
	  printf("请输入你要查找的人的姓名(不多于15个字符):\n");
	 
	  gets(name);
	  
	  printf("%s\n\n",search1(name)?"此人在哈希表中":"查无此人");
	   
	}
    
	else if (c == '2')
	{
	  printf("请输入你要查找的人的学号(不多于10个字符):\n");
	 
	  gets(number);
	  
	  printf("%s\n\n",search2(number)?"此人在哈希表中":"查无此人");
	   
	} 
                                                     //search1,search2要带参数,便于传递
	else 
	{
		putch(7);
	  
		printf("你输入了'1','2'之外的字符,请检查!\n");
	}                                                //输入的选项有误则也返回NULL
}



void main()
{
	char menu[220] = "     请选择你要的操作的序号:\n       1.插入元素\n       2.删除元素\n       3.查看哈希表\n       4.查找元素\n       5.更改信息\n       6.退出\n "  ;
	char c;
	int i;
    
	printf("\n\n");
	printf("                ****************************************************************\n");
	printf("                **  程序说明:本程序利用哈希表,按照学生姓名(汉语拼音)长度分 **\n");
	printf("                **  配其所在地址,学生信息包括姓名,学号,可以对该表进行插入, **\n");
	printf("                **  删除,查找,查看,更改信息等操作,是一个管理学生的小系统  **\n");
	printf("                **  ,若发现问题或有好的建议请及时反馈,以便我们为您提供更好  **\n");
	printf("                **  的服务!                                                  **\n");
	printf("                ****************************************************************\n\n\n");
	
	for(i = 0 ; i < 13 ; i++)
		HashTable[i] = NULL;               //初始置空
	    
	
	do
	{
		   puts(menu);

		   c = getch();
		   putchar(c);
		   
		   printf("\n\n");

		   switch (c)
		{
		   case '1' : Insert();
					  break;
		  
		   case '2' : Delete();             //两种方法的删除!!
					  break; 
	  		  
		   case '3' : print();
					  break; 

		   case '4' : search();             //两种方法的查找!!
			          break;  

	       case '5' : change();             //先查找,再修改
		     		  break;  

	       case '6' : printf("谢谢使用本系统,欢迎再次使用!\n") ;    //下面的while中退出!
					  break;

		   default :
					  putch(7) ;
					  printf("输入有误,请重新输入!\n") ; 
		
		} 
	
	}while(c!='6');                       //while后面的';'不可少

				  
}

 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -