資料結構之二叉查詢樹的基本操作及選單應用(C程式實現)
阿新 • • 發佈:2021-01-24
技術標籤:資料結構與演算法分析(C語言實現)資料結構二叉樹演算法
//參考書是機械工業出版社的資料結構與演算法分析(C語言描述);
//本程式是可移植性程式;
//能在Linux/Mac os/Windows下編譯執行;
//若有不足之處請提出,博主會盡所能修改;
//若是對您有用的話請點贊收藏或分享給它人;
//未經允許嚴禁抄襲以及轉載;
//原始碼奉上,希望能夠對您有所啟發;
//----------------------------------------------------------------------------
//main.c
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include "binarysearchtree.h"
int get_first(void); //獲取使用者輸入的第1個字元;
elemtype input(void); //處理錯誤輸入;
void eatline(void); //清空輸入緩衝區;
int show_menu(void); //提供二叉查詢樹選單選項;
void choice(int ch, bstree **root); //實現具體操作的函式;
int main(void)
{
int ch;
bstree *mytree = NULL;
while ((ch = show_menu()) != 'q')
{
choice(ch, &mytree);
}
destroy_tree(mytree);
puts("歡迎下次使用!");
return 0;
}
int get_first(void)
{
int ch;
do
{
ch = tolower(getchar());
} while (isspace(ch));
eatline();
return ch;
}
elemtype input(void)
{
elemtype val;
printf("請輸入一個元素值: ");
while (scanf("%d", &val) != 1)
{
eatline();
printf("輸入有誤!請重新輸入: ");
}
eatline();
return val;
}
void eatline(void)
{
while (getchar() != '\n')
continue;
return;
}
int show_menu(void)
{
int ch;
puts("===============================");
puts(" 歡迎使用二叉查詢樹選單");
puts("a) 為二叉查詢樹新增新元素");
puts("b) 刪除二叉查詢樹中的元素");
puts("c) 查詢二叉查詢樹中最小值");
puts("d) 查詢二叉查詢樹中最大值");
puts("e) 在二叉查詢樹中查詢元素");
puts("f) 多種遍歷當前二叉查詢樹");
puts("q) 退出本程式");
puts("===============================");
printf("請您輸入選擇: ");
while (ch = get_first(), strchr("abcdefq", ch) == NULL)
{
printf("您的選擇無效!請重新輸入:");
}
return ch;
}
void choice(int ch, bstree **root)
{
elemtype val;
bstree *pos = NULL;
switch (ch)
{
case 'a':
{
val = input();
insert(root, val);
break;
}
case 'b':
{
val = input();
if (cancel(root, val) != -1)
{
printf("為二叉查詢樹刪除元素%d成功!\n", val);
}
break;
}
case 'c':
{
pos = find_min(*root);
if (pos != NULL)
{
printf("二叉查詢樹中最小值是%d\n", pos->data);
}
else
{
printf("二叉查詢樹為空樹!無最小值!\n");
}
break;
}
case 'd':
{
pos = find_max(*root);
if (pos != NULL)
{
printf("二叉查詢樹中最大值是%d\n", pos->data);
}
else
{
printf("二叉查詢樹為空樹!無最大值!\n");
}
break;
}
case 'e':
{
val = input();
pos = find(*root, val);
if (pos != NULL)
{
printf("二叉查詢樹中存在元素%d\n", pos->data);
}
else
{
printf("二叉查詢樹中不存在元素%d\n");
}
break;
}
case 'f':
{
traverse(*root);
break;
}
}
printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
return;
}
//binarysearchtree.h
#ifndef BINARYSEARCHTREE_H_
#define BINARYSEARCHTREE_H_
typedef int elemtype;
typedef struct node
{
elemtype data; //二叉樹資料存放區;
struct node *left; //二叉樹左子樹指標域;
struct node *right; //二叉樹右子樹指標域;
} bstree;
//1) 插入一個元素至二叉查詢樹中;
void insert(bstree **t, elemtype val);
/*----------------------------------------------------------------------*/
//2) 刪除二叉查詢樹中的元素值;
int cancel(bstree **t, elemtype val);
/*----------------------------------------------------------------------*/
//3) 銷燬二叉查詢樹;
void destroy_tree(bstree *t);
/*----------------------------------------------------------------------*/
//4) 查詢二叉查詢樹中的最小值;
bstree *find_min(bstree *t);
/*----------------------------------------------------------------------*/
//5) 查詢二叉查詢樹中的最大值;
bstree *find_max(bstree *t);
/*----------------------------------------------------------------------*/
//6) 查詢二叉查詢樹中的元素值;
bstree *find(bstree *t, elemtype val);
/*----------------------------------------------------------------------*/
//7) 進行二叉查詢樹的遍歷(先序中序以及後序遍歷);
void traverse(bstree *t);
/*----------------------------------------------------------------------*/
#endif
//binarysearchtree.c
#include <stdio.h>
#include <stdlib.h>
#include "binarysearchtree.h"
static bstree *make_treenode(elemtype val)
{
bstree *temp = NULL;
if ((temp = (bstree *)malloc(sizeof(bstree))) != NULL)
{
temp->data = val;
temp->left = temp->right = NULL;
return temp;
}
else
{
fprintf(stderr, "記憶體不足無法新增新元素!自動退出本程式!\n");
exit(EXIT_FAILURE);
}
}
void insert(bstree **t, elemtype val)
{
if (NULL == (*t))
{
(*t) = make_treenode(val);
printf("成功新增資料元素%d至二叉查詢樹中\n", val);
}
else if (val == (*t)->data)
{
printf("二叉查詢樹中已存在元素%d故無法新增!\n", val);
}
else if (val < (*t)->data)
{
insert(&(*t)->left, val);
}
else if (val > (*t)->data)
{
insert(&(*t)->right, val);
}
return;
}
int cancel(bstree **t, elemtype val)
{
bstree *pos = NULL;
if (NULL == (*t))
{
printf("二叉查詢樹中不存在資料%d, 刪除失敗!\n", val);
return -1;
}
else if (val < (*t)->data)
{
cancel(&(*t)->left, val);
}
else if (val > (*t)->data)
{
cancel(&(*t)->right, val);
}
else if ((*t)->left != NULL && (*t)->right != NULL)
{
pos = find_min((*t)->right);
(*t)->data = pos->data; //待刪除結點的值賦值為其右子樹中的最小值;
cancel(&(*t)->right, (*t)->data); //刪除右子樹中的最小值的結點;
}
else
{
pos = (*t);
if (NULL == (*t)->left)
{
(*t) = (*t)->right;
}
else if (NULL == (*t)->right)
{
(*t) = (*t)->left;
}
free(pos);
return 0;
}
}
void destroy_tree(bstree *t)
{
if (t != NULL)
{
destroy_tree(t->left);
destroy_tree(t->right);
free(t);
}
return;
}
bstree *find_min(bstree *t)
{
if (t != NULL)
{
while (t->left != NULL)
{
t = t->left;
}
}
return t;
}
bstree *find_max(bstree *t)
{
if (t != NULL)
{
while (t->right != NULL)
{
t = t->right;
}
}
return t;
}
bstree *find(bstree *t, elemtype val)
{
if (NULL == t)
{
return NULL;
}
else if (val < t->data)
{
return find(t->left, val);
}
else if (val > t->data)
{
return find(t->right, val);
}
else
{
return t;
}
}
static void pre_order_traverse(bstree *t) //先序遍歷;
{
if (t != NULL)
{
printf("%d ", t->data);
pre_order_traverse(t->left);
pre_order_traverse(t->right);
}
return;
}
static void in_order_traverse(bstree *t) //中序遍歷;
{
if (t != NULL)
{
in_order_traverse(t->left);
printf("%d ", t->data);
in_order_traverse(t->right);
}
return;
}
static void post_order_traverse(bstree *t) //後序遍歷;
{
if (t != NULL)
{
post_order_traverse(t->left);
post_order_traverse(t->right);
printf("%d ", t->data);
}
return;
}
void traverse(bstree *t)
{
if (t != NULL)
{
printf("先序遍歷結果是:\n");
pre_order_traverse(t);
printf("\n中序遍歷結果是:\n");
in_order_traverse(t);
printf("\n後序遍歷結果是:\n");
post_order_traverse(t);
return;
}
printf("二叉查詢樹為空!無法遍歷!\n");
return;
}
//----------------------------------------------------------------------------
//----------------------------2021年1月23日 -------------------------------