hhhhyiuxiu 2018-11-30 09:13 采纳率: 0%
浏览 1753
已结题

平衡二叉树插入的旋转。。。

这个程序插入的时候会出现问题。问了学校的老师,他就非让我跟书上写的一样。。。。我在这里给出示例的输入。图片说明。希望大佬们能帮助一哈,困扰我蛮久了。。
输入的时候先序输入,比如图中的程序就应该输入:4 3,2 1,1 0,0 -1,0 -1,3 0,0 -1,0 -1,6 2,5 0,0 -1,0 -1,15 1,7 0,0 -1,0 -1,16 0,0 -1,0 -1(注:这里的叶子节点高度看做0,可以看成从叶子节点往上看的高度,第一个输入的值为节点的值,第二个输入的值为节点的高度)
我所给出的这个示例程序的含义就是先先序创建一个已经平衡的二叉树之后插入一个新的节点导致不平衡,然后进行旋转。

#include <stdio.h>
#include <stdlib.h>


typedef struct node
{
    int data;
    struct node *left;
    struct node *right;
    int height;            //定义平衡二叉树的数据结构
}tree,*PTree;


int get_height(PTree T)
{
    if(T==NULL)
        return -1;             //如果没有节点则为高度返回-1
    else
        return T->height;      //否则返回当前节点的高度
}



void creat_tree(PTree &T)      //先序创建平衡二叉树
{
    int a;
    printf("请输入元素:");
    scanf("%d",&a);
    /*printf("请输入高度:");
    scanf("%d",&b);*/
    if(a==0)
        T=NULL;
    else
    {
        T=(PTree)malloc(sizeof(tree));
        T->data=a;
        //T->height=b;
        printf("请输入高度:");
        scanf("%d",&T->height);
        printf("创建左子树:\n");
        creat_tree(T->left);
        printf("请输入高度:");
        scanf("%d",&T->height);
        printf("创建右子树:\n");
        creat_tree(T->right);
    }
}




int Max(int a,int b)          //用来得到高度的最大值,更新节点的高度
{
    int max;
    max=a;
    if(b>a)
        max=b;
    return max;
}



PTree Single_L(PTree &T)                //执行左侧单旋转例程
{
    PTree p;
    p=T;
    T=T->left;                          
    p->left=T->right;                   
    T->right=p;
    p->height=Max(get_height(p->left),get_height(p->right))+1;
    T->height=Max(get_height(T->left),get_height(T->right))+1;
    return T;
}




PTree Single_R(PTree &T)                  //执行右侧单旋转例程
{
    PTree p;
    p=T;
    T=T->right;
    p->right=T->left;           //t的左右都比p的值要大,但是左子树的值要相比于右子树要更小,所以应该T的左子树等于p的右子树,左侧的单旋转同理
    T->left=p;
    p->height=Max(get_height(p->left),get_height(p->right))+1;
    T->height=Max(get_height(T->left),get_height(T->right))+1;
    return T;
}


PTree Double_L(PTree &T)                 //执行左侧双旋转例程(由2个单旋转例程构成)
{
    T->left=Single_R(T->left);
    return Single_L(T);
}



PTree Double_R(PTree &T)               //执行右侧双旋转例程
{
    T->right=Single_L(T->right);
    return Single_R(T);
}





PTree insert(PTree &T,int x)
{
    if(T==NULL)                  //如果找到了待插入的位置,就创建节点,将其高度设置为0
    {
        T=(PTree)malloc(sizeof(tree));
        T->data=x;
        T->height=0;    //
        T->left=T->right=NULL;
    }          
    else
    {
        if(x<T->data)
        {
            T->left=insert(T->left,x);
            if(get_height(T->left)-get_height(T->right)==2)  //如果左子树的高度比右子树大2就不符合平衡二叉树的性质,需要执行旋转
            {
                if(x<T->left->data)           //如果插入的元素和当前节点的值在同一侧,那么就执行单旋转
                    T=Single_L(T);
                else
                    T=Double_L(T);           //否则执行双旋转
            }
        }
        else
        {
            if(x>T->data)
            {
                T->right=insert(T->right,x);
                if(get_height(T->right)-get_height(T->left)==2)         //如果右子树的高度比左子树大2就不符合平衡二叉树的性质,需要执行旋转
                {
                    if(x>T->right->data)
                        T=Single_R(T);                              //如果插入的元素和当前节点的值在同一侧,那么就执行单旋转
                    else
                        T=Double_R(T);                          //否则执行双旋转
                }
            }
        }
    }
    T->height=Max(get_height(T->left),get_height(T->right))+1;       //更新节点的高度
    return T;
}




void xianxubianli(PTree T)
{
    if(T!=NULL)
    {
        printf("%d ",T->data);
        //printf("%d ",T->height);
        xianxubianli(T->left);
        xianxubianli(T->right);
    }
}






void main()
{
    int a;
    PTree T;

    creat_tree(T);
    xianxubianli(T);
    printf("\n");

    printf("please input the number you want to insert:");
    scanf("%d",&a);

    T=insert(T,a);

    xianxubianli(T);


} 
  • 写回答

1条回答 默认 最新

  • devmiao 2018-11-30 12:09
    关注
    评论

报告相同问题?

悬赏问题

  • ¥500 把面具戴到人脸上,请大家贡献智慧
  • ¥15 任意一个散点图自己下载其js脚本文件并做成独立的案例页面,不要作在线的,要离线状态。
  • ¥15 各位 帮我看看如何写代码,打出来的图形要和如下图呈现的一样,急
  • ¥30 c#打开word开启修订并实时显示批注
  • ¥15 如何解决ldsc的这条报错/index error
  • ¥15 VS2022+WDK驱动开发环境
  • ¥30 关于#java#的问题,请各位专家解答!
  • ¥30 vue+element根据数据循环生成多个table,如何实现最后一列 平均分合并
  • ¥20 pcf8563时钟芯片不启振
  • ¥20 pip2.40更新pip2.43时报错