哈希法:使用链地址法解决冲突.c
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
/* file name: listhash.c */
/*哈希法:使用链地址法解决冲突*/
#include
#include
#include
#include
#define MAX_NUM 100 /*最大数据笔数*/
#define PRIME 97 /*MAX_NUM的质数*/
#define NOTEXISTED NULL
/*定义数据结构*/
typedef struct Person {
long id;
char name[21];
struct Person *link;
} Student;
/*建立哈希链表*/
Student *Hashtab[MAX_NUM];
/*函数原形声明*/
long hashfun(long);
void insert();
void del();
Student *search(Student *,Student *);
void query();
void show();
void main()
{
char *menu_prompt =
"=== Hashing Table Program ==\n"
" 1. Insert\n"
" 2. Delete\n"
" 3. Show\n"
" 4. Search\n"
" 5. Quit\n"
"Please input a number : ";
char menusele;
int i;
/*起始哈希链表,将各链表指向NULL*/
for ( i = 0; i< MAX_NUM; i++)
Hashtab[i] = NULL;
do
{
printf("%s",menu_prompt);
menusele = toupper(getche());
puts("");
switch (menusele)
{
case '1' :
insert();
break;
case '2' :
del();
break;
case '3' :
show();
break;
case '4' :
query();
break;
case '5' :
puts("Bye Bye ^_^");
break;
default :
puts("Invalid choice !!");
}
} while (menusele != '5' );
}
/*哈希函数 */
/*以除法运算求出记录应该存储的位置 */
long hashfun(long key)
{
return ( key % PRIME );
}
void insert()
{
Student *newnode;
long index;
/*输入记录*/
newnode = ( Student *)malloc(sizeof(Student));
newnode->link = NULL;
printf("Enter id : ");
scanf("%ld",&newnode->id);
printf("Enter Name : ");
scanf("%s",newnode->name);
/*利用哈希函数求得记录地址*/
index = hashfun(newnode->id);
/*判断该链表是否为空,若为空则建立链表*/
if ( Hashtab[index] == NULL )
{
Hashtab[index] = newnode;
printf("Node insert ok!\n");
}
else
{
/*查找节点是否在链表中,如未存在则将此节点加入链表首部*/
if ((search(Hashtab[index],newnode)) == NOTEXISTED)
{
newnode->link = Hashtab[index];
Hashtab[index] = newnode;
printf("Node insert ok!\n");
}
else
printf("Record existed...\n");
}
}
/*删除节点函数*/
void del()
{
Student *node ,*node_parent;
long index;
node = (Student *)malloc(sizeof(Student));
printf("Enter ID : ");
scanf("%ld",&node->id);
/*利用哈希函数转换记录地址*/
index = hashfun(node->id);
/*查找节点是否存在并传回指向该节的指针*/
node = search(Hashtab[index],node);
if ( node == NOTEXISTED )
printf("Record not existed ...\n");
else
{
/*如节点为链表头,则将链表指向NULL
否则找到其父节点,并将父节点link向节点尾部*/
printf("ID : %ld Name : %s\n",node->id,node->name);
printf("Deleting record....\n");
if ( node == Hashtab[index] )
Hashtab[index] = NULL;
else
{
n
ode_parent = Hashtab[index];
while ( node_parent->link->id != node->id )
node_parent = node_parent->link;
node_parent->link = node->link;
}
free(node);
}
}
/* 查找节点函数,如找到节点则返回指向该节点的指针 */
Student *search(Student *linklist,Student *Node)
{
Student *ptr = linklist;
while (ptr->id != Node->id && ptr->link != NULL)
ptr = ptr->link;
if ( ptr == NULL )
return NOTEXISTED;
else
return ptr;
}
/*查询节点函数*/
void query()
{
Student *query_node;
long index;
query_node = (Student *)malloc(sizeof(Student));
printf("Enter ID : ");
scanf("%ld",&query_node->id);
index = hashfun(query_node->id);
/*查找节点函数*/
query_node = search(Hashtab[index],query_node);
if ( query_node == NOTEXISTED )
printf("Record not existed...\n");
else
{
printf("ID : %ld Name : %s\n",
query_node->id,query_node->name);
}
}
/* 显示节点函数,从哈希表一一查找是否有节点存在 */
void show()
{
int i;
Student *ptr;
puts("ID NAME");
puts("------------------------");
for ( i = 0; i < MAX_NUM;i++ )
{
/* 表不为空,则将整个表显示出来*/
if ( Hashtab[i] != NULL )
{
ptr = Hashtab[i];
while (ptr) {
printf("%-5ld %15s\n",ptr->id,ptr->name);
ptr = ptr->link;
}
}
}
}