/*******************************************************************************
程序名称 : 哈希表学生管理系统
作者 : 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,s
评论1