C语言二叉查找树及其简单操作()

第一次玩,水平有限,不过代码可运行

#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
typedef struct tree
{
    struct tree* lchild, *rchild;
    int data;
}treeNode;
treeNode* create(treeNode* );           //创建一棵树
void preordertransval(treeNode*);     //前序遍历
void inordertransval(treeNode*);       //中序遍历
void postordertransval(treeNode*);    //后序遍历
void lookup(treeNode*);                     //查找树中的数字
treeNode* delete_Node(treeNode*,int); //删除树中的某一个节点
int totleNode(treeNode*);                    //计算二叉树中的结点
int totleLeftNode(treeNode*);              //计算二叉树中的叶子结点
int totleinNode(treeNode*);                 //计算二叉树中的内部节点
void mirrorImage(treeNode*);          //将二叉树转化为镜像
void printfMenu();                            //创建一个菜单
int main()
{
    treeNode* T = NULL;
    int options;
    printfMenu();                          //打印一个菜单页面
    scanf_s("%d", &options);               //选择你的操作
    while (options != -1)
    {
        if (options == 1)
        {
            T = create(T);
        }
        else if (options == 2)
        {
            printf("前序表达式是:\t");
            preordertransval(T);
            printf("\n");
        }
        else if (options == 3)
        {
            printf("中序表达式是:\t");
            inordertransval(T);
            printf("\n");
        }
        else if (options == 4)
        {
            printf("后序表达式是:\t");
            postordertransval(T);
            printf("\n");
        }
        else if (options == 5)
        {
            lookup(T);
            printf("\n");
        }
        else if (options == 6)
        {
            int num;
            printf("你想删除哪一个节点?\t");
            scanf_s("%d", &num);
            T=delete_Node(T,num);
            printf("\n");
        }
        else if (options == 7)
        {
            int num;
            num = totleNode(T);
            printf("树中节点的个数是:%d\n", num);
        }
        else if (options == 8)
        {
            int num;
            num = totleLeftNode(T);
            printf("树中的叶子结点个数是:%d\n", num);
        }
        else if (options == 9)
        {
            int num;
            num = totleinNode(T);
            printf("树中的内部节点个数是:%d\n", num);
        }
        else if (options == 10)
        {
            mirrorImage(T);
        }
        else if (options == 0)
        {
            break;
        }
        printf("请再次输入你想要执行的操作:\n");                              //再次选择你的操作
        scanf_s("%d", &options);                                              //选择你的操作
    }
    return 0;
}
treeNode* create(treeNode* T)
{
    treeNode* parent_node, * ptr, * new_node;
    int i;                                                                    //i用来存储树中的data
    printf("如果想结束请输入-1:\n");
    printf("请输入二叉查找树中的数据:\t");
    scanf_s("%d", &i);
    while (i != -1)                                                           //输入-1树截止
    {
        new_node = (treeNode*)malloc(sizeof(treeNode));                       //将new_node进行变量转换
        new_node->data = i;
        new_node->lchild = NULL;
        new_node->rchild = NULL;
        if (T == NULL)                                                        //创建根节点
        {
            T = new_node;                                                     //将根节点赋值
        }
        else                                                                  //对树的节点进行插入
        {
            parent_node = NULL;
            ptr = T;
            while (ptr != NULL)                                               //寻找到空的子树进行赋值
            {
                if (i < ptr->data)
                {
                    parent_node = ptr;
                    ptr = ptr->lchild;
                }
                else
                {
                    parent_node = ptr;
                    ptr = ptr->rchild;
                }
            }
            if (i < parent_node->data)
            {
                parent_node->lchild = new_node;
            }
            else
            {
                parent_node->rchild = new_node;
            }
        }
        printf("请再次输入二叉查找树中的数据:\t");
        scanf_s("%d", &i);
    }
    return T;
}
void preordertransval(treeNode* T)//前序遍历二叉树
{
    if (T != NULL)
    {
        printf("%d   ", T->data);
        preordertransval(T->lchild);
        preordertransval(T->rchild);
    }
}
void inordertransval(treeNode* T)//中序遍历
{
    if (T != NULL)
    {
        inordertransval(T->lchild);
        printf("%d   ", T->data);
        inordertransval(T->rchild);
    }
}
void postordertransval(treeNode* T)//后序遍历二叉树,递归的思想一样,只不过遍历的时机不一样
{
    if (T != NULL)
    {
        postordertransval(T->lchild);
        postordertransval(T->rchild);
        printf("%d   ", T->data);
    }
}
void lookup(treeNode* T)//查找二叉树中的数
{
    treeNode* ptr;
    ptr = T;
    int i;
    printf("请输入你想查找的数:\n");
    scanf_s("%d", &i);
    if (ptr->data == i)
        printf("%d is the root number:\n", i);
    else
    {
        while (ptr->data != i)
        {
                if (i < ptr->data)
                {
                    ptr = ptr->lchild;
                }
                else
                {
                    ptr = ptr->rchild;
                }
                if (ptr == NULL)
                    break;
        }
        if (ptr != NULL)
        {
            printf("树中存在%d", ptr->data);
        }
        else
        {
            printf("树中不存在该数:\n");
        }
    }
}
treeNode* delete_Node(treeNode* T,int i)//删除树中的某一个节点
{
    treeNode* ptr,*parent_node;
    parent_node = NULL;
    ptr = T;
    while (ptr->data != i)
    {
        if (i < ptr->data)
        {
            parent_node = ptr;
            ptr = ptr->lchild;
        }
        else
        {
            parent_node = ptr;
            ptr = ptr->rchild;
        }
        if (ptr == NULL)
            break;
    }
    if (ptr == NULL)
        printf("wrong 树中没有此数:\n");
    else if (ptr->lchild == NULL && ptr->rchild == NULL)//当所要删除的节点是叶子节点时
    {
        if (ptr->data < parent_node->data)
            parent_node->lchild = NULL;
        else
            parent_node->rchild = NULL;
    }
    else if (ptr->lchild != NULL && ptr->rchild == NULL)//ptr有左孩子没有有孩子
    {
        if (ptr->data < parent_node->data)
        {
            parent_node->lchild = ptr->lchild;
            free(ptr);
        }
        else
        {
            parent_node->rchild = ptr->lchild;
            free(ptr);
        }
    }
    else if (ptr->lchild == NULL && ptr->rchild != NULL)//ptr有右孩子没有左孩子
    {
        if (ptr->data < parent_node->data)
        {
            parent_node->lchild = ptr->rchild;
            free(ptr);
        }
        else
        {
            parent_node->rchild = ptr->rchild;
        }
    }
    else if (ptr->lchild != NULL && ptr->rchild != NULL)//用中序遍历的前一个数或者后一个数来代替被删除的数
    {
        treeNode* find,*find_parent;//这个数是用来寻找中序遍历的前一个数的(后一个数方法一样,在这里我们不做展示)
        find = T;
        find_parent = NULL;
        inordertransval(T);
        int t;
        printf("%d前面的数是:", i);
        scanf_s("%d", &t);
        while (find->data != t)
        {
            if (t < find->data)
            {
                find_parent = find;
                find = find->lchild;
            }
            else
            {
                find_parent = find;
                find = find->rchild;
            }
            if (find == NULL)
                break;
        }
        int n;//n存放find中的数;
        n = find->data;                             
        if (find->data < find_parent->data)             //如果提前赋值将导致find和find_parent中的数相等从而使右子树全部被删除
            find_parent->lchild = NULL;
        else
            find_parent->rchild = NULL;
        ptr->data = n;//将find删除之后,再将find中的数赋值给ptr
    }
    return T;
}
int totleNode(treeNode* T)
{
    if (T == NULL)
        return 0;
    else
        return(totleNode(T->lchild) + totleNode(T->rchild) + 1);//每遍历一个节点就加一,知道遍历结束
}
int totleLeftNode(treeNode* T)
{
    if (T == NULL)
        return 0;
    else if ((T->lchild == NULL) && (T->rchild == NULL))
        return 1;
    else
        return(totleLeftNode(T->lchild) + totleLeftNode(T->rchild));
}
int totleinNode(treeNode* T)
{
    if (T == NULL || ((T->rchild == NULL) && (T->rchild == NULL)))
        return 0;
    else
        return(totleinNode(T->lchild) + totleinNode(T->rchild) + 1);
}
void mirrorImage(treeNode* T)
{
    if (T!=NULL)
    {
        treeNode* ptr;
        ptr = T->rchild;
        T->rchild = T->lchild;
        T->lchild = ptr;
        mirrorImage(T->lchild);
        mirrorImage(T->rchild);
    }
}
void printfMenu()
{
    printf("开始-------------------\n");
    printf("1》创建一个二叉查找树\n");
    printf("2》前序遍历二叉查找树\n");
    printf("3》中序遍历二叉查找树\n");
    printf("4》后序遍历二叉查找树\n");
    printf("5》查找二叉树中的数\n");
    printf("6》删除树中的某一个节点\n");
    printf("7》计算二叉树中节点数\n");
    printf("8》计算二叉树中的叶子结点数\n");
    printf("9》计算二叉树中内部节点数\n");
    printf("10》镜像树\n");
    printf("0》退出\n");
    printf("-----------------------\n");
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值