Data_Structure/作業/unit7/try.cpp
2025-01-20 21:30:53 +08:00

204 lines
4.8 KiB
C++
Raw Permalink 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.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
/* 定義引線二元搜尋樹結構 */
typedef struct student {
char name[20]; /* 學生姓名 */
int score; /* 學生成績 */
struct student *left; /* 左子指標 */
struct student *right; /* 右子指標 */
int leftThread; /* 左線索標記 */
int rightThread; /* 右線索標記 */
} student;
/* 全域變數 */
student *root = NULL;
student *head = NULL;
/* 函數原型 */
void insert(char [], int);
void remove_node(char []);
void show_tree();
student *search(char []);
student *find_inorder_successor(student *);
student *find_inorder_predecessor(student *);
void free_tree(student *);
/* 找尋中序後繼節點 */
student *find_inorder_successor(student *node) {
if (node->rightThread)
return node->right;
node = node->right;
while (!node->leftThread)
node = node->left;
return node;
}
/* 找尋中序前驅節點 */
student *find_inorder_predecessor(student *node) {
if (node->leftThread)
return node->left;
node = node->left;
while (!node->rightThread)
node = node->right;
return node;
}
/* 插入節點 */
void insert(char name[], int score) {
student *new_node, *current, *parent;
/* 檢查節點是否已存在 */
if (search(name) != NULL) {
printf("%s 已存在!\n", name);
return;
}
new_node = (student *)malloc(sizeof(student));
strcpy(new_node->name, name);
new_node->score = score;
new_node->leftThread = new_node->rightThread = 1;
if (root == NULL) {
/* 建立表頭節點 */
head = (student *)malloc(sizeof(student));
head->leftThread = head->rightThread = 0;
head->right = head;
head->left = new_node;
/* 第一個節點 */
new_node->left = head;
new_node->right = head;
root = new_node;
return;
}
current = root;
while (1) {
parent = current;
if (strcmp(name, current->name) < 0) {
if (current->leftThread)
break;
current = current->left;
} else {
if (current->rightThread)
break;
current = current->right;
}
}
if (strcmp(name, parent->name) < 0) {
/* 左子節點 */
new_node->left = parent->left;
new_node->right = parent;
parent->left = new_node;
parent->leftThread = 0;
} else {
/* 右子節點 */
new_node->right = parent->right;
new_node->left = parent;
parent->right = new_node;
parent->rightThread = 0;
}
}
/* 中序遍歷 */
void show_tree() {
student *current;
if (root == NULL) {
printf("樹是空的!\n");
return;
}
current = root;
while (!current->leftThread)
current = current->left;
printf("字典變數內部儲存的元素(keyvalue)如下\n");
while (current != head) {
printf("%s%d\n", current->name, current->score);
current = find_inorder_successor(current);
}
}
/* 搜尋節點 */
student *search(char target[]) {
student *current = root;
while (current != NULL) {
if (strcmp(target, current->name) == 0)
return current;
if (strcmp(target, current->name) < 0) {
if (current->leftThread)
break;
current = current->left;
} else {
if (current->rightThread)
break;
current = current->right;
}
}
return NULL;
}
/* 刪除節點 */
void remove_node(char name[]) {
student *node = search(name);
if (node == NULL) {
printf("%s 不在樹中!\n", name);
return;
}
// 刪除節點的實作較為複雜,這裡會有更多細節需要處理
printf("刪除節點的實作在引線二元搜尋樹中較為複雜,需要特別處理線索。\n");
}
/* 釋放樹的記憶體 */
void free_tree(student *node) {
if (node == NULL) return;
if (!node->leftThread)
free_tree(node->left);
if (!node->rightThread)
free_tree(node->right);
printf("刪除'w[%s]=%d'節點\n", node->name, node->score);
free(node);
}
int main() {
char line[128], key[20];
int value;
printf("輸入存取字典的陳述,按<Enter>結束程式\n");
while (1) {
printf("\n指令 => ");
fgets(line, 128, stdin);
if (line[0] == '\n') break;
if (sscanf(line, "w[%[^]]] = %d", key, &value) == 2) {
insert(key, value);
printf("新增w[%s]=%d\n", key, value);
} else if (sscanf(line, "w[%[^]]]?", key) == 1) {
student *found = search(key);
if (found)
printf("字典元素w[%s]=%d\n", key, found->score);
else
printf("錯誤! %s 不在此樹中!\n", key);
} else if (line[0] == 'w' && line[1] == '?') {
show_tree();
}
}
free_tree(root);
free(head);
return 0;
}