1. 程式人生 > 其它 >資料結構之二叉查詢樹的基本操作及選單應用(C程式實現)

資料結構之二叉查詢樹的基本操作及選單應用(C程式實現)

技術標籤:資料結構與演算法分析(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日 -------------------------------