【輸入】
可以對BST樹進行插入或刪除數字
【輸出】
依前序追蹤輸出BST樹
【完整程式碼】
#include <stdio.h>
#include <stdlib.h>
typedef struct Node{
int data;
struct Node *left, *right;
} Node;
Node* BSTroot = NULL;
//建新節
Node* newNode(int val) {
Node* node = (Node*)malloc(sizeof(Node));
node->data = val;
node->right = node->left = NULL;
return node;
}
//前序印出BST樹
void preOrder(Node* root) {
if(root) {
printf("%d ", root->data);
preOrder(root->left);
preOrder(root->right);
}
}
//插入BST樹(用while迴圈配合指標做)
void insert(int val){
Node **ptr = &BSTroot; //依址找值
while(*ptr != NULL){ //找要插入的樹葉的位址
if(val < (*ptr)->data)
ptr = &(*ptr)->left;
else if(val > (*ptr)->data)
ptr = &(*ptr)->right;
else
break;
}
if(*ptr == NULL) //要插位的位置為空表示無重複
*ptr = newNode(val); //新節點插入此位址
}
//找子樹中最小的樹 (從根開始往左走直到不能走)
Node* minValue(Node* rootT){
Node* ptr = rootT;
while(ptr->left)
ptr = ptr->left;
return ptr;
}
//自BST樹中刪除(用while迴圈配合指標做)
void remove(int val){
Node **ptr = &BSTroot; //依址找值
while(*ptr == NULL || (*ptr)->data != val){ //找要刪除的節點的位址
if(val < (*ptr)->data)
ptr = &(*ptr)->left;
else if(val > (*ptr)->data)
ptr = &(*ptr)->right;
}
if(*ptr != NULL){ //要刪位的位置為空表示有找到值
if((*ptr)->left == NULL || (*ptr)->right == NULL){ //若目前節點的子樹數量為 0(無子樹) 或 1(僅左或右子樹)
Node* childT = ((*ptr)->left!=NULL)? (*ptr)->left: (*ptr)->right; //暫存左子樹或右子樹
free((*ptr)); //釋放目前子樹樹根記憶體
(*ptr) = childT; //若無子樹,令目前節點為空 否則令其為其暫存的子樹
}else{ //若目前節點 左、右子樹皆有
Node* minNode = minValue((*ptr)->right); //取得 右子樹最小的節點
int minValue = minNode->data; //取得 右子樹最小的節點的值
remove(minValue); //刪除剛剛找到的節點 (註:因為右子樹最小的節點必無左子樹,故遞迴結果必為第1或第2個if)
(*ptr)->data = minValue; //設目前子樹樹根的數字 為剛剛找到的節點的數字
}
}
}
int main(void){
int val;
char SENT;
//對BST樹的操作
printf("<1: 插入> <2: 刪除> <3: 列出(前序)> <q: 離開>\n選擇操作 : ");
scanf(" %c", &SENT);
while(SENT != 'q'){
switch(SENT) {
case '1':
printf("輸入要插入的數: ");
scanf("%d", &val);
insert(val);
break;
case '2':
printf("輸入要刪除的數: ");
scanf("%d", &val);
remove(val);
break;
case '3':
preOrder(BSTroot);
putchar('\n');
break;
default:
break;
}
printf("\n<1: 插入> <2: 刪除> <3: 列出(前序)> <q: 離開>\n選擇操作 : ");
scanf(" %c", &SENT);
}
system("pause");
return 0;
}
測試資料1:
依序插入:10 20 30 40 50 25
列出結果:10 20 30 25 40 50
測試資料2:
依序插入:9 5 10 0 6 11 -1 1 2
列出結果:9 5 0 -1 1 2 6 10 11
刪除節點:10
列出結果:9 5 0 -1 1 2 6 11
刪除節點:5
列出結果:9 6 0 -1 1 2 11
刪除節點:9
列出結果:11 6 0 -1 1 2