04-树5 Root of AVL Tree (25 分)

对方算法完全正确,不贴图了.

 

下面是我的算法的图.

 

 

 

 

04-树5 Root of AVL Tree (25 分)

An AVL tree is a self-balancing binary search tree. In an AVL tree, the heights of the two child subtrees of any node differ by at most one; if at any time they differ by more than one, rebalancing is done to restore this property. Figures 1-4 illustrate the rotation rules.

 

 

 

 

Now given a sequence of insertions, you are supposed to tell the root of the resulting AVL tree.

 

Input Specification:

Each input file contains one test case. For each case, the first line contains a positive integer N (20) which is the total number of keys to be inserted. Then N distinct integer keys are given in the next line. All the numbers in a line are separated by a space.

Output Specification:

For each test case, print the root of the resulting AVL tree in one line.

Sample Input 1:

5
88 70 61 96 120

Sample Output 1:

70

Sample Input 2:

7
88 70 61 96 120 90 65

Sample Output 2:

88

 

 

 

 

另外,我不认为 4,5没通过,就是我答案的错误.

也许是 生成的树变化了.导致根节点不一样而已.

并不能说我产生的树 就错误.

 ----------

另外,关于性能,这代码,是每次都从根部开始查找插入的位置,然后插入的.

其实可以这样,

1若是插入右侧,可以判定右侧是不是已经饱和了.添加新节点,必须增加深度.左侧也一样.

2,不要每次查询插入位置,都从根节点开始,而是第一次从根节点,以后,从发现者节点开始往下搜索.

平衡树这个,我觉得,若是右侧饱和,又必须插入右侧数据,不如把这个节点,与根节点并排,作为树根.也就是说,有两个根,双根总比单根来的有效率.

或者是说让他产生一个虚根.

虚根若有一个子节点,虚根就不存在.若是有两个子节点,虚根就存在.

 ----------------

2018年10月1日

 

自己的代码效率根人家 4中方案的效率差太多.折腾了好些天,至少对方的4中情况怎么弄.自己算是弄清楚了.

晚些时候再去看看,他是怎么判断 谁是发现者的.

我寻找发现者的方式,是从插入的节点,向上寻找父节点,判断父节点是不是发现者,若不是,继续找父节点的父节点.因为我做的节点里,有个 父node 如果 avl树 是通过树根往下 遍历寻找发现者的话,如果树很大, 会很慢.

(好像我想的不对).......我是从底部向上寻找,他是从顶部向下寻找.一样的.

 

以下代码是对方的算法

using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Net;
using System.Text;
using System.Xml;


public class MyNode
{
    public MyNode(string s)
    {
        Value = int.Parse(s);
    }
    public MyNode(int s)
    {
        Value = s;
    }
    public MyNode Left;
    public MyNode Right;
    public int Value;


    public int 左右节点层级差值
    {
        get
        {
            if (this == null)
            {
                return int.MaxValue;
            }
            else
            {
                int l = Left != null ? Left.最大层级 : 0;
                int r = Right != null ? Right.最大层级 : 0;

                return l - r;
            }

        }

    }

    /// <summary>
    /// 当前有多少子层,孙层
    /// </summary>
    public int 最大层级
    {
        get
        {
            if (this == null)
            {
                return 0;
            }
            else
            {
                int max = 1;
                if (Left != null && Right != null)
                {
                    int l = Left.最大层级;
                    int r = Right.最大层级;
                    max += Math.Max(l, r);

                }
                else
                {
                    if (Left != null)
                    {
                        max += Left.最大层级;

                    }
                    else if (Right != null)
                    {
                        max += Right.最大层级;
                    }

                }
                return max;
            }
        }
    }

    #region 暂时无用的东西
    public MyNode 最小的孙子
    {
        get
        {
            var t = this;
            while (t.Left != null)
            {
                t = t.Left;

            }
            return t;


        }
    }
    public MyNode 最大的孙子
    {
        get
        {
            var t = this;
            while (t.Right != null)
            {
                t = t.Right;

            }
            return t;


        }
    }
    public int 直接子节点数量
    {
        get
        {
            int i = 0;
            if (Left != null) { i++; }
            if (Right != null) { i++; }
            return i;

        }

    }
    public MyNode Next
    {
        get
        {
            if (Left != null && Right == null)
            {
                return Left;
            }
            if (Left == null && Right != null)
            {
                return Right;

            }
            return null;
        }
    }
    #endregion


    /// <summary>
    /// 存放父node
    /// </summary>
    public MyNode Pnode;
}
class MyTree
{

    public MyNode myNode;
    public MyTree(string v2)
    {
        var temp = v2.Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries);
        if (temp.Length > 0)
        {


            for (int i = 0; i < temp.Length; i++)
            {
                int v = int.Parse(temp[i]);

                插入并调整平衡(v);


            }

        }

    }

    /// <summary>
    /// 插入节点并返回这个节点
    /// </summary>
    /// <param name="v"></param>
    /// <returns></returns>
    MyNode Insert(int v)
    {
        if (myNode == null)
        {
            myNode = new MyNode(v);
            return myNode;
        }
        MyNode temp;
        temp = myNode;
        while (temp != null)
        {
            if (temp.Value > v)
            {

                var t2 = temp.Left;
                if (t2 != null)
                {
                    t2.Pnode = temp;
                    temp = t2;
                }
                else
                {
                    temp.Left = new MyNode(v);
                    temp.Left.Pnode = temp;
                    return temp.Left;
                }


            }
            else
            {

                var t2 = temp.Right;
                if (t2 != null)
                {
                    t2.Pnode = temp;
                    temp = t2;
                }
                else
                {
                    temp.Right = new MyNode(v);
                    temp.Right.Pnode = temp;
                    return temp.Right;
                }

            }


        }
        return null;
    }

    void 平衡插入弃用(int v)
    {
        var 麻烦节点 = Insert(v);



        if (麻烦节点.Pnode == null)//p为空,说明只有一个节点
        {
            //无需操作,平衡着呢
            return;
        }
        else
        {
            MyNode 发现者 = 获取不平衡节点(麻烦节点.Pnode);
            if (发现者 == null)
            {
                //平衡,结束操作
            }
            else
            {
                //此时,只需要修改 发现者 以内的节点,即可做到平衡

                //先把这个 麻烦节点,从树中移除掉

                麻烦节点.Pnode.Left = 麻烦节点.Pnode.Right = null;



                if (v > 发现者.Value)//说明需要插入到根节点的右侧
                {
                    var p = 麻烦节点.Pnode;
                    int newV = v;
                    while (p != 发现者)
                    {
                        if (newV > p.Value)
                        {
                            int tempV = p.Value;
                            p.Value = newV;
                            newV = tempV;
                            break;
                        }
                        else
                        {
                            p = p.Pnode;

                        }
                    }
                    if (p == 发现者)
                    {
                        if (newV > p.Value)
                        {
                            int tempV = p.Value;
                            p.Value = newV;
                            newV = tempV;

                        }
                    }


                    平衡插入弃用(newV);
                }
                if (v < 发现者.Value)//说明需要插入到根节点的右侧
                {
                    var p = 麻烦节点.Pnode;
                    int newV = v;
                    while (p != 发现者)
                    {
                        if (newV < p.Value)
                        {
                            int tempV = p.Value;
                            p.Value = newV;
                            newV = tempV;
                            break;
                        }
                        else
                        {
                            p = p.Pnode;

                        }
                    }
                    if (p == 发现者)
                    {
                        if (newV < p.Value)
                        {
                            int tempV = p.Value;
                            p.Value = newV;
                            newV = tempV;

                        }
                    }


                    平衡插入弃用(newV);
                }


            }

        }
    }

    void 插入并调整平衡(int v)
    {
        var 麻烦节点 = Insert(v);



        if (麻烦节点.Pnode == null)//p为空,说明只有一个节点
        {
            //无需操作,平衡着呢
            return;
        }
        else
        {
            MyNode 发现者 = 获取不平衡节点(麻烦节点.Pnode);
            if (发现者 == null)
            {
                //平衡,结束操作
            }
            else
            {
                if (v > 发现者.Value)
                {//右旋
                    if (v < 发现者.Right.Value)
                    {//左旋RL


                        var fxzP = 发现者.Pnode;
                        var fxz = 发现者;
                        var fxzR = 发现者.Right;
                        var fxzRL = 发现者.Right.Left;
                        if (fxzP != null)
                        {
                            if (fxzP.Left == fxz)
                            {
                                fxzP.Left = fxzRL;
                            }
                            else
                            {
                                fxzP.Right = fxzRL;
                            }
                            fxzRL.Pnode = fxz.Pnode;

                        }
                        fxz.Pnode = fxzRL;

                        fxz.Right = fxzRL.Left;
                        if (fxzRL.Left != null)
                        {
                            fxz.Right.Pnode = fxz;
                        }
                        fxzR.Left = fxzRL.Right;
                        if (fxzRL.Right != null)
                        {

                            fxzR.Left.Pnode = fxzR;
                        }

                        fxzRL.Left = fxz;
                        fxzRL.Right = fxzR;
                        if (fxzP == null)
                        {
                            myNode = fxzRL; myNode.Pnode = null;
                        }
                    }
                    else
                    {//RR
                        var fxzP = 发现者.Pnode;
                        var fxz = 发现者;
                        var fxzR = 发现者.Right;
                        var fxzRL = 发现者.Right.Left;

                        if (fxzP != null)
                        {
                            if (fxzP.Left == fxz)
                            {
                                fxzP.Left = fxzR;
                            }
                            else
                            {
                                fxzP.Right = fxzR;
                            }
                            fxzR.Pnode = fxzP;


                        }

                        fxz.Right = fxzRL;
                        if(fxz.Right!=null)
                        {
                            fxz.Right.Pnode = fxz;
                        }

                        fxzR.Left = fxz;
                        fxz.Pnode = fxzR;
                        if (fxzP == null)
                        {
                            myNode = fxzR; myNode.Pnode = null;
                        }

                    }
                }
                else
                {//左旋

                    if (v > 发现者.Left.Value)
                    {//左旋LR

                        var fxzP = 发现者.Pnode;
                        var fxz = 发现者;
                        var fxzL = 发现者.Left;
                        var fxzLR = 发现者.Left.Right;
                        if (fxzP != null)
                        {
                            if (fxzP.Left == fxz)
                            {
                                fxzP.Left = fxzLR;
                            }
                            else
                            {
                                fxzP.Right = fxzLR;
                            }
                            fxzLR.Pnode = fxz.Pnode;

                        }
                        fxz.Pnode = fxzLR;

                        fxz.Left = fxzLR.Right;
                        if (fxzLR.Right != null)
                        {

                            fxz.Left.Pnode = fxz;
                        }
                        fxzL.Right = fxzLR.Left;
                        if (fxzLR.Left != null)
                        {
                            fxzL.Right.Pnode = fxzL;
                        }
                        fxzLR.Left = fxzL;
                        fxzLR.Right = fxz;
                        if (fxzP == null)
                        {
                            myNode = fxzLR;
                            myNode.Pnode = null;
                        }
                    }
                    else
                    {//LL

                        var fxzP = 发现者.Pnode;
                        var fxz = 发现者;
                        var fxzL = 发现者.Left;
                        var fxzLR = 发现者.Left.Right;
                        if (fxzP != null)
                        {
                            if (fxzP.Left == fxz)
                            {
                                fxzP.Left = fxzL;
                            }
                            else
                            {
                                fxzP.Right = fxzL;
                            }


                            fxzL.Pnode = fxz.Pnode;

                        }


                        fxz.Left = fxzLR;
                        if (fxz.Left != null)
                        {
                            fxzLR.Pnode = fxz;
                        }

                        fxz.Pnode = fxzL;
                        fxzL.Right = fxz;
                        if (fxzP == null)
                        {
                            myNode = fxzL; myNode.Pnode = null;
                        }
                    }
                }

            }
        }

    }
    /// <summary>
    /// 由插入的新节点,向上追溯,找到发现者
    /// </summary>
    /// <param name="p"></param>
    /// <returns></returns>
    private MyNode 获取不平衡节点(MyNode p)
    {
        var 发现者 = p;
        while (发现者 != null)
        {
            if (Math.Abs(发现者.左右节点层级差值) > 1)
            {
                return 发现者;
            }
            else
            {
                发现者 = 发现者.Pnode;//一直找父节点,知道根,根没有父节点,退出循环

            }
        }
        return null;

    }
}


class T
{


    static void Main(string[] args)
    {
        int vvv = int.Parse(Console.ReadLine());
        var v = Console.ReadLine();


        MyTree tree = new MyTree(v);

        Console.WriteLine(tree.myNode.Value);

       


    }

}

 

 

 以下代码是自己的算法

using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Net;
using System.Text;
using System.Xml;


public class MyNode
{
    public MyNode(string s)
    {
        Value = int.Parse(s);
    }
    public MyNode(int s)
    {
        Value = s;
    }
    public MyNode Left;
    public MyNode Right;
    public int Value;


    public int 左右节点层级差值
    {
        get
        {
            if (this == null)
            {
                return int.MaxValue;
            }
            else
            {
                int l = Left != null ? Left.最大层级 : 0;
                int r = Right != null ? Right.最大层级 : 0;

                return l - r;
            }

        }

    }

    /// <summary>
    /// 当前有多少子层,孙层
    /// </summary>
    public int 最大层级
    {
        get
        {
            if (this == null)
            {
                return 0;
            }
            else
            {
                int max = 1;
                if (Left != null && Right != null)
                {
                    int l = Left.最大层级;
                    int r = Right.最大层级;
                      max += Math.Max(l, r);
                     
                }
                else
                {
                   if(Left!=null)
                    {
                        max+=Left.最大层级;
                        
                    }
                   else if(Right!=null)
                    {
                        max+=Right.最大层级;
                    }

                }
                return max;
            }
        }
    }

    #region 暂时无用的东西
    public MyNode 最小的孙子
    {
        get
        {
            var t = this;
            while (t.Left != null)
            {
                t = t.Left;

            }
            return t;


        }
    }
    public MyNode 最大的孙子
    {
        get
        {
            var t = this;
            while (t.Right != null)
            {
                t = t.Right;

            }
            return t;


        }
    }
    public int 直接子节点数量
    {
        get
        {
            int i = 0;
            if (Left != null) { i++; }
            if (Right != null) { i++; }
            return i;

        }

    }
    public MyNode Next
    {
        get
        {
            if (Left != null && Right == null)
            {
                return Left;
            }
            if (Left == null && Right != null)
            {
                return Right;

            }
            return null;
        }
    }
    #endregion


    /// <summary>
    /// 存放父node
    /// </summary>
    public MyNode Pnode;
}
class MyTree
{

    public MyNode myNode;
    public MyTree(string v2)
    {
        var temp = v2.Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries);
        if (temp.Length > 0)
        {


            for (int i = 0; i < temp.Length; i++)
            {
                int v = int.Parse(temp[i]);

                平衡插入(v);


            }
        }

    }

    /// <summary>
    /// 插入节点并返回这个节点
    /// </summary>
    /// <param name="v"></param>
    /// <returns></returns>
    MyNode Insert(int v)
    {
        if (myNode == null)
        {
            myNode = new MyNode(v);
            return myNode;
        }
        MyNode temp;
        temp = myNode;
        while (temp != null)
        {
            if (temp.Value > v)
            {

                var t2 = temp.Left;
                if (t2 != null)
                {
                    t2.Pnode = temp;
                    temp = t2;
                }
                else
                {
                    temp.Left = new MyNode(v);
                    temp.Left.Pnode = temp;
                    return temp.Left;
                }


            }
            else
            {

                var t2 = temp.Right;
                if (t2 != null)
                {
                    t2.Pnode = temp;
                    temp = t2;
                }
                else
                {
                    temp.Right = new MyNode(v);
                    temp.Right.Pnode = temp;
                    return temp.Right;
                }

            }


        }
        return null;
    }

    void 平衡插入(int v)
    {
        var 麻烦节点 = Insert(v);



        if (麻烦节点.Pnode == null)//p为空,说明只有一个节点
        {
            //无需操作,平衡着呢
            return;
        }
        else
        {
            MyNode 发现者 = 获取不平衡节点(麻烦节点.Pnode);
            if (发现者 == null)
            {
                //平衡,结束操作
            }
            else
            {
                //此时,只需要修改 发现者 以内的节点,即可做到平衡

                //先把这个 麻烦节点,从树中移除掉

                麻烦节点.Pnode.Left = 麻烦节点.Pnode.Right = null;



                if (v > 发现者.Value)//说明需要插入到根节点的右侧
                {
                    var p = 麻烦节点.Pnode;
                    int newV = v;
                    while (p != 发现者)
                    {
                        if (newV > p.Value)
                        {
                            int tempV = p.Value;
                            p.Value = newV;
                            newV = tempV;
                            break;
                        }
                        else
                        {
                            p = p.Pnode;

                        }
                    }
                    if (p == 发现者)
                    {
                        if (newV > p.Value)
                        {
                            int tempV = p.Value;
                            p.Value = newV;
                            newV = tempV;

                        }
                    }


                    平衡插入(newV);
                }
                if (v < 发现者.Value)//说明需要插入到根节点的右侧
                {
                    var p = 麻烦节点.Pnode;
                    int newV = v;
                    while (p != 发现者)
                    {
                        if (newV < p.Value)
                        {
                            int tempV = p.Value;
                            p.Value = newV;
                            newV = tempV;
                            break;
                        }
                        else
                        {
                            p = p.Pnode;

                        }
                    }
                    if (p == 发现者)
                    {
                        if (newV < p.Value)
                        {
                            int tempV = p.Value;
                            p.Value = newV;
                            newV = tempV;

                        }
                    }


                    平衡插入(newV);
                }


            }

        }
    }

    private MyNode 获取不平衡节点(MyNode p)
    {
        var 发现者 = p;
        while (发现者 != null)
        {
            if (Math.Abs(发现者.左右节点层级差值) > 1)
            {
                return 发现者;
            }
            else
            {
                发现者 = 发现者.Pnode;//一直找父节点,知道根,根没有父节点,退出循环

            }
        }
        return null;

    }
}


class T
{


    static void Main(string[] args)
    {
        Console.ReadLine();
        var v = Console.ReadLine();


        MyTree tree = new MyTree(v);

        Console.WriteLine(tree.myNode.Value);
        return;


    }

}

 

posted @ 2018-09-30 11:56  interim  阅读(236)  评论(0)    收藏  举报