• 实验 二叉排序树


    一、   实验目的

    1. 掌握二叉树逻辑结构;

    2. 掌握利用C/C++编程语言实现数据结构的编程方法;

    3. 通过上机时间加强利用数据结构解决实际应用问题的能力;

    二、   实验相关知识

    1. 二叉树的二叉链表存储结构的实现;

    2. 二叉树排序树的定义;

    3. 二叉排序树的插入、构建、删除;

    4. 二叉排序树的中序遍历。

    三、   实验内容与要求

    实现二叉排序树的结点插入、构建、遍历和元素删除( 已经提供结点删除函数实现)

    四、   实现过程与结构

    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    typedef char ElemType; //二叉链表中结点元素类型
    typedef struct BiTNode
    {
        ElemType data;
        struct BiTNode* lchild, *rchild;
    }BiTNode, *BiTree; //二叉链表的类型定义
    BiTree CreateBiTree();// 利用先序遍历创建二叉树,返回根指针。
    void InOrder(BiTree T);// 二叉树的中序遍历,参数:二叉树根指针T,输出:中间没有空格,末尾不换行。
    int InsertNode(BiTree& T, ElemType x);//二叉排序树的插入
    BiTree CreateBiTree()// 利用先序遍历创建二叉树,返回根指针。
    {
        //补充代码
        BiTree T = NULL;
        int  i, n, x;
        printf_s("输入元素的个数n和n个元素:
    ");
        scanf_s("%d:", &n);
        for (int i = 0; i < n; i++) {
            scanf_s("%d", &x);
            InsertNode(T, x);
        }
        return T;
    }
    
    int InsertNode(BiTree &T, ElemType x)//二叉排序树的插入
    {     //补充代码
        if (T == NULL) {
            T = (BiTNode*)malloc(sizeof(BiTNode));
            T->data = x;
            T->rchild = NULL;
            T->lchild = NULL;
        }
        else {
            if (T->data == x)return 0;
            if (T->data < x)
                InsertNode(T->rchild, x);
            else
                InsertNode(T->lchild, x);
        }
        return 1;
    }
    
    void InOrder(BiTree T) // 中序遍历
    {   //补充代码
        if (T != NULL) {
            InOrder(T->lchild);
            printf_s("%d ",T->data);
            InOrder(T->rchild);
        }
    }
    
    BiTNode* find(BiTree& T, ElemType x)
    {
        if (T == NULL)
            return NULL;
        if (T->data == x)
            return T;
        else
        {
            if (x < T->data)
                return find(T->lchild, x);
            else
                return find(T->rchild, x);
        }
    }
    
    
    int Delete(BiTree &p)
    {
        BiTree q, s;
        //情况 1,结点 p 本身为叶子结点,直接删除即可
        if (p->lchild == NULL && p->rchild == NULL) {
            free(p);
            p = NULL;
            return 1;
        }
        if (p->lchild == NULL) { //左子树为空,右子树非空,只需用结点 p 的右子树根结点代替结点 p 即可;
            q = p;
            p = p->rchild;
            free(q);
            return 1;
        }
        else if (p->rchild == NULL) {//右子树为空,左子树非空,只需用结点 p 的左子树根结点代替结点 p 即可;
            q = p;
            p = p->lchild;//这里不是指针 p 指向左子树,而是将左子树存储的结点的地址赋值给指针变量 p
            free(q);
        }
        else {//左右子树均不为空,采用第 2 种方式
            q = p;
            s = p->lchild;
            //遍历,找到结点 p 的直接前驱
            while (s->rchild)
            {
                q = s;
                s = s->rchild;
            }
            //直接改变结点 p 的值
            p->data = s->data;
            //判断结点 p 的左子树 s 是否有右子树,分为两种情况讨论
            if (q != p) {
                q->rchild = s->lchild;//若有,则在删除直接前驱结点的同时,令前驱的左孩子结点改为 q 指向结点的孩子结点
            }
            else {
                q->lchild = s->lchild;//否则,直接将左子树上移即可
            }
            free(s);
        }
        return 1;
    }
    int DeleteBST(BiTree &T, int key)
    {
        if (!T) {//不存在关键字等于key的数据元素
            return 0;
        }
        else
        {
            if (key == T->data) {
                Delete(T);
                return 1;
            }
            else if (key < T->data) {
                //使用递归的方式
                return DeleteBST(T->lchild, key);
            }
            else {
                return DeleteBST(T->rchild, key);
            }
        }
    }
    
    int main()
    {
        BiTree T;
        T = CreateBiTree();
        while (1)
        {
            printf_s("请选择选项      
    1.插入元素 
    2.删除元素   
    其他.结束程序
    ");
            InOrder(T);
            printf_s("
    ");
            int seleted;
            scanf_s("%d", &seleted);
            switch (seleted)
            {
            case 1:
            {
                int x;
                printf_s("输入插入的元素x=");
                scanf_s("%d", &x);
                if (InsertNode(T, x) > 0) printf_s("插入成功");
                else printf_s("元素重复,放弃插入");
                InOrder(T);
                printf_s("
    ");
                break;
            }
            case 2:
            {
                int x;
                printf_s("输入删除的元素x=");
                scanf_s("%d", &x);
                if (DeleteBST(T, x) > 0) printf_s("删除成功");
                else printf_s("元素不存在,放弃删除");
                InOrder(T);
                printf_s("
    ");
                break;
            }
            default:return 1;
            }
        }
    
    }

  • 相关阅读:
    懒加载 和 json
    [iOS]用instancetype代替id作返回类型有什么好处?
    (转)Objective-C语法之KVC使用
    UITableView 展示数据
    shopee
    防火墙
    vue项目开发技巧
    文件流
    vant
    node 使用
  • 原文地址:https://www.cnblogs.com/xxxsans/p/14182468.html
Copyright © 2020-2023  润新知