Data_Structure/資料結構光碟檔/CH14/hashingTableUsingList.c.txt
2025-01-20 21:25:33 +08:00

217 lines
4.8 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* file name: hashingTableUsingList.c */
/* 雜湊法 : 使用鏈結串列處理碰撞 */
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define MAX_NUM 100 /* 最大資料筆數 */
#define PRIME 97 /* MAX_NUM之質數 */
/* 定義資料結構 */
typedef struct Person {
long id;
char name[21];
struct Person *link;
} Student;
/* 建立雜湊表串列 */
Student *Hashtab[MAX_NUM], *current;
/*函數原型宣告*/
long hashfun(long);
void insert(void);
void del(void);
Student *search(Student *,Student *);
void query(void);
void show(void);
void flushBuffer(void);
int main()
{
char *menu_prompt =
"\n=== Hashing Table Program ==\n"
" 1. Insert\n"
" 2. Delete\n"
" 3. Show\n"
" 4. Search\n"
" 5. Quit\n"
" 請輸入選項: ";
char choice;
int i;
/* 起始雜湊串列,將各串列指向 NULL */
for (i = 0; i< MAX_NUM; i++)
Hashtab[i] = NULL;
do {
printf("%s", menu_prompt);
choice = toupper(getchar());
flushBuffer();
printf("\n");
switch (choice) {
case '1':
insert();
break;
case '2':
del();
break;
case '3':
show();
break;
case '4':
query();
break;
case '5':
puts("Bye Bye ^_^");
break;
default:
puts("錯誤選項!!");
}
} while (choice != '5');
return 0;
}
/* 雜湊函數: */
/* 以除法運算傳求出記錄應儲存的位址 */
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);
flushBuffer();
/* 利用雜湊函數求得記錄位址 */
index = hashfun(newnode->id);
printf("index 為 %ld\n", index);
/* 判斷該串列是否為空,若為空則建立此鏈結串列 */
if (Hashtab[index] == NULL) {
Hashtab[index] = newnode;
printf("Node insert ok!\n");
}
else {
printf("有碰撞,加入串列中...\n");
/* 加入於串列中 */
current = Hashtab[index];
while (current->link != NULL) {
current = current->link;
}
current->link = newnode;
}
}
/* 刪除節點函數 */
void del()
{
Student *node ,*node_parent;
long index;
node = (Student *)malloc(sizeof(Student));
printf("Enter ID: ");
scanf("%ld",&node->id);
flushBuffer();
/* 利用雜湊函數轉換記錄位址 */
index = hashfun(node->id);
/* 搜尋節點是否存在並傳回指向該節點指標 */
node = search(Hashtab[index], node);
if (node == NULL)
printf("此資料找不到...\n");
else {
/* 如節點為串列首則將串列指向NULL
否則找到其父節點並將父節點link向節點後端 */
printf("ID : %ld Name : %s\n",node->id,node->name);
if (node == Hashtab[index])
Hashtab[index] = NULL;
else {
node_parent = Hashtab[index];
while (node_parent->link->id != node->id)
node_parent = node_parent->link;
node_parent->link = node->link;
}
free(node);
printf("此筆資料已刪除....\n");
}
}
/* 搜尋節點函數
如找到節點則傳回指向該節點之指標
否則傳回NULL */
Student *search(Student *linklist, Student *Node)
{
Student *ptr = linklist;
if (ptr == NULL)
return NULL;
while (ptr->id != Node->id && ptr->link != NULL)
ptr = ptr->link;
if (ptr == NULL)
return NULL;
else
return ptr;
}
/*查詢節點函數*/
void query()
{
Student *query_node;
long index;
query_node = (Student *)malloc(sizeof(Student));
printf("Enter ID: ");
scanf("%ld", &query_node->id);
flushBuffer();
index = hashfun(query_node->id);
/* 搜尋節點 */
query_node = search(Hashtab[index], query_node);
if (query_node == NULL)
printf("雜湊表沒有此筆資料...\n");
else {
printf("ID: %ld Name: %s\n", query_node->id,query_node->name);
}
}
/* 顯示節點函數,
從雜湊串列一一尋找是否有節點存在 */
void show()
{
int i, flag=0;
Student *ptr;
puts("ID NAME");
puts("------------------------");
for ( i = 0; i < MAX_NUM; i++ ) {
if (Hashtab[i] != NULL){
flag = 1;
ptr = Hashtab[i];
/* 串列後面若還有資料,則將整串列顯示出 */
while (ptr) {
printf("%-5ld %15s\n",ptr->id,ptr->name);
ptr = ptr->link;
}
}
}
if (flag == 0)
printf("The Hashing table is empty !!!\n");
}
void flushBuffer()
{
while (getchar() != '\n')
continue;
}