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

220 lines
6.4 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: heap.c */
/* 利用堆積樹(heap tree)處理會員進出資料--載入、儲存、插入、刪除、輸出 */
#include <stdio.h>
#include <stdlib.h>
#define MAX 100 /* 設定上限 */
void insert_f(void); /* 插入函數 */
void delete_f(void); /* 刪除函數 */
void display_f(void); /* 輸出函數 */
void create(int); /* 建立資料於堆積樹 */
void removes(int); /* 從堆積樹中刪除資料 */
void show(char); /* 印出資料於螢幕 */
void adjust_u(int [], int); /* 從下而上調整資料 */
void adjust_d(int [], int, int); /* 從上而下調整資料 */
void exchange(int *, int *); /* 交換資料 */
int search(int); /* 搜尋資料 */
void flushBuffer(void);
int heap_tree[MAX]; /* 堆積樹陣列 */
int last_index = 0; /* 最後一筆資料的INDEX */
int main(void)
{
char option;
do {
printf("\n ******************\n");
printf(" <1> login\n");
printf(" <2> logout\n");
printf(" <3> show\n");
printf(" <4> quit\n");
printf(" ******************\n");
printf(" Enter your choice: ");
option = getchar();
flushBuffer();
printf("\n");
switch(option) {
case '1':
insert_f();
break;
case '2':
delete_f();
break;
case '3':
display_f();
break;
case '4':
exit(0);
default :
puts("選項錯誤!");
}
} while(option != '4');
return 0;
}
void insert_f(void)
{
int id_temp;
if (last_index >= MAX) { /* 資料數超過上限,顯示錯誤訊息 */
printf("\n Login members are more than %d!!\n", MAX);
printf(" Please wait for a minute!!\n");
}
else {
printf("\n Enter login ID number: ");
scanf("%d", &id_temp);
flushBuffer();
create(id_temp); /* 建立堆積 */
printf(" Login successfully!!\n");
}
}
void delete_f(void)
{
int id_temp, del_index;
if (last_index < 1) { /* 無資料存在,顯示錯誤訊息 */
printf("\n No member to logout!!\n");
printf(" Please check again!!\n");
}
else {
printf("\n Enter logout ID number: ");
scanf("%d", &id_temp);
flushBuffer();
del_index = search(id_temp); /* 尋找欲刪除資料 */
if (del_index == 0) /* 沒找到資料,顯示錯誤訊息 */
printf(" %d not found!!\n", id_temp);
else {
removes(del_index); /* 刪除資料,並調整堆積樹 */
printf(" %d is logout!!\n", id_temp);
}
}
}
void display_f(void)
{
char option;
if (last_index < 1) /* 無資料存在,顯示錯誤訊息 */
printf("\n 堆積中無資料!\n");
else {
printf("\n ****************\n");
printf(" <1> increase\n"); /* 選擇第一項為由小到大排列 */
printf(" <2> decrease\n"); /* 選擇第二項為由大到小排列 */
printf(" ******************\n");
do {
printf(" 請選擇: ");
option = getchar();
flushBuffer();
printf("\n");
} while(option != '1' && option != '2');
show(option);
}
}
void create(int id_temp) /* ID_TEMP為新增資料 */
{
heap_tree[++last_index] = id_temp; /* 將資料新增於最後 */
adjust_u(heap_tree, last_index); /* 調整新增資料 */
}
void removes(int index_temp) /* INDEX_TEMP為欲刪除資料之INDEX */
{ /* 以最後一筆資料代替刪除資料 */
heap_tree[index_temp] = heap_tree[last_index];
heap_tree[last_index--] = 0;
if (last_index > 1) { /* 當資料筆數大於1筆則做調整 */
/* 當替代資料大於其PARENT NODE則往上調整 */
if(heap_tree[index_temp] > heap_tree[index_temp / 2] && index_temp > 1)
adjust_u(heap_tree, index_temp);
else /* 替代資料小於其CHILDEN NODE則往下調整 */
adjust_d(heap_tree, index_temp, last_index-1);
}
}
void show(char op)
{
int heap_temp[MAX+1];
int c_index;
/* 將堆積樹資料複製到另一個陣列作排序工作 */
for (c_index = 1; c_index <= last_index; c_index++)
heap_temp[c_index] = heap_tree[c_index];
/* 將陣列調整為由小到大排列 */
for (c_index = last_index-1; c_index > 0; c_index--) {
exchange(&heap_temp[1], &heap_temp[c_index+1]);
adjust_d(heap_temp, 1, c_index);
}
printf("\n ID number\n");
printf(" =====================\n");
/* 選擇第一種方式輸出,以遞增方式輸出--使用堆疊
選擇第二種方式輸出,以遞減方式輸出--使用佇列 */
switch(op) {
case '1':
for(c_index = 1; c_index <= last_index; c_index++)
printf("%14d\n", heap_temp[c_index]);
break;
case '2':
for(c_index = last_index; c_index > 0; c_index--)
printf("%14d\n", heap_temp[c_index]);
break;
}
printf(" =====================\n");
printf(" Total member: %d\n", last_index);
}
void adjust_u(int temp[], int index) /* INDEX為目前資料在陣列之INDEX */
{
while (index > 1) { /* 將資料往上調整至根為止 */
if(temp[index] <= temp[index/2]) /* 資料調整完畢就跳出,否則交換資料 */
break;
else
exchange(&temp[index], &temp[index/2]);
index /= 2;
}
}
/* INDEX1為目前資料在陣列之INDEXINDEX2為最後一筆資料在陣列之INDEX */
void adjust_d(int temp[], int index1, int index2)
{ /* ID_TEMP記錄目前資料INDEX_TEMP則是目前資料之CHILDEN NODE的INDEX */
int id_temp, index_temp;
id_temp = temp[index1];
index_temp = index1 * 2;
/* 當比較資料之INDEX不大於最後一筆資料之INDEX則繼續比較 */
while (index_temp <= index2) {
if ((index_temp < index2) && (temp[index_temp] <
temp[index_temp+1]))
index_temp++; /* INDEX_TEMP記錄目前資料之CHILDEN NODE中較大者 */
if (id_temp >= temp[index_temp]) /* 比較完畢則跳出,否則交換資料 */
break;
else {
temp[index_temp/2] = temp[index_temp];
index_temp *= 2;
}
}
temp[index_temp/2] = id_temp;
}
/* 交換傳來之 ID1 及 ID2 儲存之資料 */
void exchange(int *id1, int *id2)
{
int id_temp;
id_temp = *id1;
*id1 = *id2;
*id2 = id_temp;
}
int search(int id_temp) /* 尋找陣列中ID_TEMP所在 */
{
int c_index;
for (c_index = 1; c_index <= MAX; c_index++)
if (id_temp == heap_tree[c_index])
return c_index; /* 找到則回傳資料在陣列中之INDEX */
return 0; /* 沒找到則回傳0 */
}
/* 清空緩衝區 */
void flushBuffer()
{
while (getchar() != '\n')
continue;
}