C#AVL-Tree:方法会减慢我的程序,但为什么呢?

时间:2012-08-03 07:07:41

标签: c# performance avl-tree

我的ConsoleApplication从输入中生成正确的AVL树。 对于我的大学,我需要制作一个程序:

  • 在AVL-Tree中正确插入数据
  • 保持平衡
  • 足够快地输出输出并更正某些输入

我的问题是为什么我在本主题后面介绍的我的程序的方法/部分是如此非常缓慢(96%的总时间程序运行)?

我的程序中使用树木行走的其他方法/部件大约占我程序的0.05%或更少


我将解释部分/方法" 树中节点的等级"相应于DotTrace(分析工具)的方法,这种方法占我整个程序的96%(所有其他方法大约需要0.05%或更少)。这就是为什么我在使用dumjudge系统提交时获得timeLimit。


  • 如果输入行以T开头: 在AVL树中插入新节点

  • 如果输入行以G开头: 确定指定节点的等级 排名是得分高于你+1的人数,而不是使用Console.Writeline(变量)得出的人数;

    示例:

  • 节点值:x(10)y(5)z(2)k(5)l(4)m(9)

  • 节点等级:X(1)y(3)z(6)k(3)l(5)m(2)


  • 如果输入行以其他内容开头: 无需解释这部分工作正确

我尝试了很多东西,但我不明白为什么它会慢下来我希望你们能帮助我让我看看我做错了什么。


变量:

  • MyAVLTree T:包含AVL树的根
  • MyNode NodeX,包含我们想要确定排名的节点
  • Int compareVAlue,是我们与其他节点比较的nodeX的值,以确定它是否更高(计数器++)或更低(无所事事)

当没有比nodeX更高的节点时,该方法将返回包含节点等级的计数器变量,以便将其打印为输出。


在AVL树中生成输出或插入数据的所有输入行大约占我程序的0.05%或更少...除了我的程序的方法/部分产生/返回AVL树中节点的等级(96) %)

我希望我的代码是可读的,提前感谢您的帮助和时间。


 public static int RankElement(MyAVLTree T, MyNode nodeX, int compareValue)
    {
        int counter = 1;

        while (true)
        {
            if (nodeX == T.root)
            {
                UnkownTreeWalk(T, nodeX.Right, compareValue, ref counter);
                return counter;
            }
            else if (nodeX == nodeX.Parent.Right)
            {
                UnkownTreeWalk(T, nodeX.Right, compareValue, ref counter);

                while (nodeX == nodeX.Parent.Right)
                {
                    nodeX = nodeX.Parent;
                    if (nodeX == T.root)
                    {
                        return counter;
                    }
                }
                nodeX = nodeX.Parent;
                if (nodeX.playerScore > compareValue)
                    counter++;
            }
            else
            {
                UnkownTreeWalk(T, nodeX.Right, compareValue, ref counter);

                nodeX = nodeX.Parent;
                if (nodeX.playerScore > compareValue)
                    counter++;
            }
        }


    }

    public static void UnkownTreeWalk(MyAVLTree T, MyNode nodeX, int compareValue, ref int counter)
    {
        if (nodeX != null)
        {
            if (nodeX.playerScore > compareValue)
            {
                counter++;
            }
            UnkownTreeWalk(T, nodeX.Right, compareValue, ref counter);

            UnkownTreeWalk(T, nodeX.Left, compareValue, ref counter);
        }
    }

1 个答案:

答案 0 :(得分:0)

有三件事需要研究。

首先,你有一些我认为不必要的条件。在UnknownTreeWalk中,我们检查节点的值是否小于compareValue。但是,compareValue是初始节点的值,当我们调用UnknownTreeWalk时,我们总是在该初始节点的右侧。在右边意味着它的值更大,因此检查是不必要的。可能会有一些类似的微小变化,你可以使事情变得更加快捷。

其次,您可能有很多CPU缓存未命中。您可以尝试安排将TreeNodes连续排列在内存中。在你的情况下,这可能不是什么大问题。

第三,最重要的是,我怀疑你花了很多时间在树木周围跑来跑去。您可以将每个子树的大小保存在它的MyNode对象中,然后只需查阅它而不是遍布整个地方计数。我认为这是最有可能让你快速到达的地方。

最后,可能会有一个非常简单的Rank实现。我鼓励你从这个实现中学习你所学到的关于这个问题的知识,然后写一个新的思考这些知识并计算这个节点右边的所有节点。