关于二叉搜索树的问题 [英] questions about binary search tree

查看:46
本文介绍了关于二叉搜索树的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

证明每个n节点二叉搜索树的可能性均不相同(假设以随机顺序插入项目),并且平衡树比直线树更有可能.

Show that every n-node binary search tree is not equally likely (assuming items are inserted in random order), and that balanced trees are more probable than straight-line trees.

它是如何证明数学的?

推荐答案

可能的树配置数量:请参见 获得单行,最不平衡,最深的树(具有n个节点)的方法数量:2 ^(n-1) 解释: 拾取第一个节点的两种方法(最大或最小) X 2种选择第二个节点的方式(在剩余的n-1个节点中最大或最小) ... X 2种拾取第(n-1)个节点的方法 X 1种方式来拾取最后一个节点

Number of ways to get a single line, most imbalanced, deepest tree with n nodes: 2^(n-1) Explanation: 2 ways to pick up first node (greatest or smallest) X 2 ways to pick up second node (greatest or smallest among the n-1 remaining nodes ... X 2 ways to pick up the (n-1)th node X 1 way to pick up the last node

以平衡的方式将n项添加到二叉树的方式数量: 令g(n,m)表示通过一次从一个列表或另一个列表中选取元素直到两个列表都为空来合并两个有序列表的方式的数量. g(n,m)= g(n-1,m)+ g(n,m-1)碰巧对应于Pascal Triangle中定义的数字.这将使n + m选择n或n + m选择m =(n + m)!/n! (n + m-n)! =(n + m)!/(n!m!) 例子: 合并两个包含2个元素的有序列表的方式数量= 4!/(2!2!)= 24/4 = 6 假设两个列表如下:

Number of ways to add n items to a binary tree in such a way that it is balanced: Let g(n,m) denote the number of ways to merge two ordered lists by picking elements from one list or the other one at a time until both lists are empty. g(n,m) = g(n-1,m) + g(n,m-1) which happen to correspond to the numbers defined in the Pascal Triangle. That would give n+m chose n or n+m chose m = (n+m)! / n! (n+m-n)! = (n+m)!/(n! m!) Example: Number of ways to merge two ordered lists containing 2 elements each = 4!/(2! 2!) = 24 / 4 = 6 Assuming the two lists are as follows:

1 A
2 B

六个合并的组合是:

1 1 1 A A A
2 A A B 1 1
A 2 B 1 B 2
B B 2 2 2 B

现在,让f(n)表示可以将n个排序元素添加到空的二叉树中以使二叉树达到平衡的组合数.达到此目的的唯一方法是先添加

Now, let f(n) denote the number of combinations in which n sorted elements can be added to a empty binary tree such that the binary tree is balanced. The only way to achieve that is to first add

  • 如果n为奇数,则为中间元素.那将是元素上限(n/2).每边将具有n/2-1个元素.
  • 如果n为偶数,则元素n/2或元素n/2 + 1.一侧将具有n/2-1个元素,另一侧将具有n/2个元素,反之亦然.

一旦选择了中间元素,则左侧的所有元素将始终位于左侧子树上,而右侧的所有元素将始终位于右侧子树上.假设右侧的元素以平衡左子树的方式排序,并且右侧的元素也以平衡右子树的方式排序,以任何方式合并两个列表将始终导致子树是平衡的.这意味着对于分别落在左右子树上的n和m个元素的每个列表,以使两个子树保持平衡,存在(n + m)!/(n!m!)合并它们,以实现结果相同.

Once the middle element is selected, all elements to the left will always fall on the left subtree and all elements on the right will always fall on the right subtree. Assuming the elements on the right are ordered in such a way that the left subtree is balanced and the elements on the right are also ordered in such a way that the right subtree is balanced, merging the two lists in any way will always result in both subtree being balanced. That means that for each list of n and m elements that respectively fall on the left and right subtree such that both subtrees are balanced, there are (n+m)!/(n!m!) to merge them so as to achieve the same result.

那会给我们(n + m)!/(n!m!)x f(n)x f(m)

That would give us (n+m)!/(n!m!) x f(n) x f(m)

我们现在可以将其表述如下: 基本案例:

We can now formulate this as follows: Base cases:

f(1) = 1
f(2) = 2

一般情况:

f(n) = (n-1)!/[((n-1)/2)!]^2 x [f((n-1)/2)]^2  | n odd
f(n) = (n-1)!/((n/2-1)! x (n/2)!) x 2 x f(n/2-1) x f(n/2) | n even

根据n将其转换为非递归公式.从n = 2 ^ m-1的最简单的情况开始可能会更容易(例如,删除节点并除以2总是得到一个整数,并且会形成一个完全平衡的树).

Rest to transform this into a non recursive formula in terms of n. Maybe it would be easier to start with the easiest case where n = 2^m - 1 (i.e. removing a node and dividing by two will always give a whole number and will result in a completely balanced tree).

注意:我在这里发布了一个相关的数学问题:

Note: I posted a related math question here: https://math.stackexchange.com/questions/460767/recurrent-relation-for-number-of-ways-to-get-a-balanced-n-binary-tree

以下是一个C#控制台应用程序,该应用程序列出了可将节点添加到二叉树以使其平衡的所有序列(运行

Following is a C# console application that lists all the sequences in which nodes can be added to a binary tree so as to have it balanced (Run it here ):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace AllBalancedTrees
{
    class Program
    {
        static void Main(string[] args)
        {
            char[] nodes = { 'A', 'B', 'C', 'D', 'E' };

            AllBalancedTrees<char> AllBalancedTrees = new AllBalancedTrees<char>(); 

            foreach (char[] a in AllBalancedTrees.allBalancedTreeCombinations(nodes))
            {
                foreach (char c in a)
                {
                    Console.Write(c + " ");
                }
                Console.WriteLine();
            }

            Console.ReadKey();
        }
    }

    class AllBalancedTrees<T>
    {
        public IEnumerable<T[]> allBalancedTreeCombinations(T[] nodes)
        {
            T[] result;
            if (nodes.Length == 1)
            {
                yield return nodes;
            }
            else if (nodes.Length == 2)
            {
                yield return nodes;
                T[] nodes2 = new T[2];
                nodes2[0] = nodes[1];
                nodes2[1] = nodes[0];
                yield return nodes2;
            }
            else if (nodes.Length % 2 == 1)
            {
                int mid = (nodes.Length - 1) / 2;
                T[] left = new T[mid];
                T[] right = new T[mid];
                Array.Copy(nodes, 0, left, 0, mid);
                Array.Copy(nodes, mid + 1, right, 0, mid);
                foreach (T[] l in allBalancedTreeCombinations(left))
                {
                    foreach (T[] r in allBalancedTreeCombinations(right))
                    {
                        result = new T[nodes.Length];
                        result[0] = nodes[mid];
                        foreach (T[] a in allMergeCombinations(l, r))
                        {
                            Array.Copy(a, 0, result, 1, a.Length);
                            yield return result;
                        }
                    }
                }
            }
            else
            {
                int mid = (nodes.Length) / 2;
                T[] left = new T[mid];
                T[] right = new T[mid - 1];
                Array.Copy(nodes, 0, left, 0, mid);
                Array.Copy(nodes, mid + 1, right, 0, mid - 1);
                foreach (T[] l in allBalancedTreeCombinations(left))
                {
                    foreach (T[] r in allBalancedTreeCombinations(right))
                    {
                        result = new T[nodes.Length];
                        result[0] = nodes[mid];
                        foreach (T[] a in allMergeCombinations(l, r))
                        {
                            Array.Copy(a, 0, result, 1, a.Length);
                            yield return result;
                        }
                    }
                }

                mid = nodes.Length / 2 - 1;
                left = new T[mid];
                right = new T[mid + 1];
                Array.Copy(nodes, 0, left, 0, mid);
                Array.Copy(nodes, mid + 1, right, 0, mid+1);
                foreach (T[] l in allBalancedTreeCombinations(left))
                {
                    foreach (T[] r in allBalancedTreeCombinations(right))
                    {
                        result = new T[nodes.Length];
                        result[0] = nodes[mid];
                        foreach (T[] a in allMergeCombinations(l, r))
                        {
                            Array.Copy(a, 0, result, 1, a.Length);
                            yield return result;
                        }
                    }
                }


            }
        }

        public IEnumerable<T[]> allMergeCombinations(T[] firstArray, T[] secondArray)
        {
            if (firstArray.Length == 0)
            {
                yield return secondArray;
            }
            else if (secondArray.Length == 0)
            {
                yield return firstArray;
            }
            else
            {
                T[] result;

                T[] firstMinusOne;
                firstMinusOne = new T[firstArray.Length - 1];
                Array.Copy(firstArray, 1, firstMinusOne, 0, firstMinusOne.Length);
                foreach (T[] a in allMergeCombinations(firstMinusOne, secondArray))
                {
                    result = new T[firstArray.Length + secondArray.Length];
                    result[0] = firstArray[0];
                    Array.Copy(a, 0, result, 1, a.Length);
                    yield return result;
                }

                T[] secondMinusOne;
                secondMinusOne = new T[secondArray.Length - 1];
                Array.Copy(secondArray, 1, secondMinusOne, 0, secondMinusOne.Length);
                foreach (T[] a in allMergeCombinations(firstArray, secondMinusOne))
                {
                    result = new T[firstArray.Length + secondArray.Length];
                    result[0] = secondArray[0];
                    Array.Copy(a, 0, result, 1, a.Length);
                    yield return result;
                }

            }
        }
    }
}

这篇关于关于二叉搜索树的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆