Basic operation and menu application of binary search tree of data structure (C program implementation)

//The reference book is the data structure and algorithm analysis of the Machinery Industry Press (C language description);

//This program is a portability program;

//Can compile and run under Linux/Mac os/Windows;

//If you have any shortcomings, please raise them, and the blogger will do their best to modify;

//If it is useful to you, please like to collect or share with others;

// Plagiarism and reprinting without permission are strictly prohibited;

//The source code is here, I hope to inspire you;

//----------------------------------------------------------------------------
//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;
}

//----------------------------------------------------------------------------

//----------------------------January 23, 2021-------------- -----------------

Guess you like

Origin blog.csdn.net/m0_46181359/article/details/113009675