实现平衡二叉排序树(c/c++)

  1. 用函数实现平衡二叉排序树算法(1)插入新结点;(2)前序、中序、后序遍历二叉树 (递归);(3)前序、中序、后序遍历的非递归算法 ;(4)层次遍历二叉树 ;(5)在二叉树中查找给定关键字;(6)交换各结点的左右子树 ;(7)求二叉树的深度 ;(8)求叶子结点数;(9)删除某结点。
  2. #include <iostream>
    #include <stack>
    #include <queue>
    #include <algorithm>
    using namespace std;
    
    int flag = 0,n=0;
    
    typedef struct n//data为节点数据,lchild和rchild分别为左子树和右子树
    {
        int data;
        struct n* lchild, * rchild;
    
    }Tree, * PTree;//定义
    
    int GetHeight(PTree& T)//二叉树的高度
    {
        if (!T)
            return 0;
        return max(GetHeight(T->lchild), GetHeight(T->rchild)) + 1;//左右子树中较大者加一 
    }
    
    PTree zuoxuan(PTree& T)//对树进行调整,插入右孩子的右子树,左旋
    {
        PTree a = T->rchild;
        T->rchild = a->lchild;
        a->lchild = T;
        return a;
    }
    
    PTree youxuan(PTree& T)//对树进行调整,插入左孩子的左子树,右旋
    {
        PTree a = T->lchild;
        T->lchild = a->rchild;
        a->rchild = T;
        return a;
    }
    
    PTree zuoyou(PTree& T)//对树进行调整,先左旋再右旋
    {
        PTree a = T;
        if (!a->rchild)
        {
            a = youxuan(a);
            return a;
        }
        a->lchild = zuoxuan(a->lchild);
        a = youxuan(a);
        return a;
    }
    
    PTree youzuo(PTree& T)//对树进行调整,先右旋再左旋
    {
        PTree a = T;
        if (!a->lchild)
        {
            a = zuoxuan(a);
            return a;
        }
        a->rchild = youxuan(a->rchild);
        a = zuoxuan(a);
        return a;
    }
    
    void ist(int a, PTree& T)//插入数据
    {
        int i, j;
        if (!T)
        {
            T = new Tree;
            T->data = a;
            T->lchild = NULL;
            T->rchild = NULL;
        }
        else if (a > T->data)
        {
            ist(a, T->rchild);
            if (GetHeight(T->rchild) - GetHeight(T->lchild) > 1)//判断是否需要调整
            {
                if (a > T->rchild->data)
                {
                    T = zuoxuan(T);
                }
                else
                {
                    T = youzuo(T);
                }
            }
        }
        else
        {
            ist(a, T->lchild);
            if (GetHeight(T->lchild) - GetHeight(T->rchild) > 1)//判断是否需要调整
            {
                if (a < T->lchild->data)
                {
                    T = youxuan(T);
                }
                else
                {
                    T = zuoyou(T);
                }
            }
        }
    }
    
    void cret(int n, PTree& T)//创建二叉树
    {
        int a, i;
        for (i = 0; i < n; i++)
        {
            scanf("%d", &a);
            ist(a, T);
        }
    }
    
    void PreOrder(PTree& T)//前序遍历递归算法
    {
        if (T)
        {
            printf("%d ", T->data);
            PreOrder(T->lchild);
            PreOrder(T->rchild);
        }
    
    }
    void InOrder1(PTree& T)//中序遍历递归算法 
    {
        if (T)
        {
            InOrder1(T->lchild);
            printf("%d ", T->data);
            InOrder1(T->rchild);
        }
    }
    void LastOrder(PTree& T)//后序遍历递归算法
    {
        if (T)
        {
            LastOrder(T->lchild);
            LastOrder(T->rchild);
            printf("%d ", T->data);
        }
    }
    
    void Traverse(PTree& T)//三种次序遍历 
    {
        PreOrder(T);
        printf("\n");
        InOrder1(T);
        printf("\n");
        LastOrder(T);
        printf("\n");
    }
    
    void srch(int a, PTree& T)//查找关键字
    {
        if (!T)
        {
            flag = 0;
            return;
        }
        if (a == T->data)
        {
            flag = 1;
            return;
        }
        else if (a < T->data)
        {
            srch(a, T->lchild);
        }
        else
        {
            srch(a, T->rchild);
        }
    
    
    }
    
    void ExchangeTree(PTree& T)//交换左右子树 (递归实现)
    {
        if (!T)
            return;
        swap(T->lchild, T->rchild);
        ExchangeTree(T->lchild);
        ExchangeTree(T->rchild);
    }
    
    int GetNum(PTree& T)//叶子节点的数量 
    {
        if (!T)
            return 0;
        if (!T->lchild && !T->rchild)
            return 1;
        return GetNum(T->lchild) + GetNum(T->rchild);//左右子树的叶子节点 
    }
    
    void InOrder2(PTree& T)//非递归中序遍历
    {
        if (!T)
        {
            return;
        }
        int i, t;
        stack<PTree> s;
        PTree p = T;
        while (p || !s.empty())
        {
            while (p)
            {
                s.push(p);
                p = p->lchild;
            }
            if (!s.empty())
            {
                p = s.top();
                s.pop();
                printf("%d ", p->data);
                p = p->rchild;
            }
        }
    
    }
    
    void PreOrder2(PTree& T)//非递归前序遍历
    {
        if (!T)
        {
            return;
        }
        int i, t;
        stack<PTree> s;
        PTree p = T;
        s.push(T);
        while (!s.empty())
        {
            p = s.top();
            s.pop();
            printf("%d ", p->data);
            if (p->rchild != NULL)
            {
                s.push(p->rchild);
            }
            if (p->lchild != NULL)
            {
                s.push(p->lchild);
            }
        }
    }
    
    void LastOrder2(PTree& T)//非递归后序遍历
    {
        if (!T)
        {
            return;
        }
        int i, t;
        stack<PTree> s;
        PTree p = T,q=NULL;
        while (p!=NULL||!s.empty())
        {
            while (p != NULL)
            {
                s.push(p);
                p = p->lchild;
            }
            p = s.top();
            s.pop();
            if (p->rchild == NULL || p->rchild == q)
            {
                q = p;
                printf("%d ", p->data);
                p = NULL;
            }
            else
            {
                s.push(p);
                p = p->rchild;
            }
        }
        
    }
    
    void Traverse2(PTree& T)//三种非递归遍历
    {
        PreOrder2(T);
        printf("\n");
        InOrder2(T);
        printf("\n");
        LastOrder2(T);
        printf("\n");
    }
    
    void Breadother(PTree& T)//层序遍历
    {
        PTree p = T;
        queue<PTree> s;
        if (!T)
        {
            return;
        }
        s.push(p);
        while (!s.empty())
        {
            p = s.front();
            printf("%d ", p->data);
            if (p->lchild)
            {
                s.push(p->lchild);
            }
            if (p->rchild)
            {
                s.push(p->rchild);
            }
            s.pop();
        }
    
    }
    
    PTree min(PTree& T)//删除操作辅助函数,找到最小的结点
    {
        if (T == NULL)
            return NULL;
        while (T->lchild)
            T=T->lchild;
        return T;
    
    }
    
    int dele(PTree& T, int a)
    {
        if (!T)
        {
            return 0;
        }
        if (a < T->data)
        {
    
            dele(T->lchild, a);//递归找到要删除结点
    
            if (GetHeight(T->rchild) - GetHeight(T->lchild) > 1)//检测并调整树的平衡性
            {
                if (a < T->rchild->data)
                    T = youzuo(T);
                else
                    T = zuoxuan(T);
            }
        }
        else if (a > T->data)
        {
            dele(T->rchild, a);//递归找到要删除结点
            if (GetHeight(T->lchild) - GetHeight(T->rchild) > 1)//检测并调整树的平衡性
            {
                if (a < T->lchild->data)
                    T = youxuan(T);
                else
                    T = zuoyou(T);
            }
        }
        else if (T->lchild && T->rchild)//待删除结点有左右孩子
        {
            flag = 1;
            PTree p = min(T->rchild);
            T->data = p->data;
            dele(T->rchild, p->data);
        }
        else if (T->lchild)//只有一个孩子或者没有孩子
        {
            flag = 1;
            T = T->lchild;
        }
        else
        {
            flag = 1;
            T = T->rchild;
        }
        return 1;
    }
    int main()
    {
        int a, b, c,d,l,k;
        int i = 0,j=0;
        PTree T = NULL;//创建一个AVL树
        printf("请输入树的结点数:");
        scanf("%d", &n);
        cret(n, T);
        printf("\n三种遍历(递归):\n");
        Traverse(T);
        printf("\n三种遍历(非递归):\n");
        Traverse2(T);
        printf("请输入要查找的数据:");
        scanf("%d",&a);
        srch(a, T);
        printf("%d\n", flag);
        flag = 0;
        printf("请输入要查找的数据:");
        scanf("%d", &b);
        srch(b, T);
        printf("%d\n", flag);
        flag = 0;
        i = 1;
        while (i)
        {
            printf("请输入要插入的数据:");
            scanf("%d", &c);
            ist(c, T);
            printf("\n三种遍历:\n");
            Traverse(T);
            printf("如果要退出插入操作,请输入0,如要继续,请输入1:");
            scanf("%d", &i);
        }
        printf("\n非递归中序遍历:\n");
        InOrder2(T);
        printf("\n");
        printf("层序遍历:\n");
        Breadother(T);
        printf("\n");
        printf("\n交换左右子树\n");
        ExchangeTree(T);
        printf("\n三种遍历:\n");
        Traverse(T);
        printf("\n交换左右子树\n");
        ExchangeTree(T);
        printf("\n三种遍历:\n");
        Traverse(T);
        printf("二叉树的深度:%d\n", GetHeight(T));
        printf("二叉树的叶子结点个数:%d\n", GetNum(T));
        i = 1;
        while (i)
        {
            
            printf("\n请输入要删除的数据:\n");
            scanf("%d", &d);
            flag = 0;
            dele(T, d);
            if (flag)
            {
                printf("\n删除成功!");
            }
            else
            {
                printf("\n删除失败!\n");
            }
            printf("\n三种遍历:\n");
            Traverse(T);
            printf("如果要退出删除操作,请输入0,如要继续,请输入1:");
            scanf("%d", &i);
        }
        return 0;
    }
    
    

     

 

  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mika的瑞士卷

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值