這是一個多年來一直困擾着我的問題。我想知道如何構建大型二叉樹,我知道的唯一方法是創建一個將一個元素推送到樹上的函數(稱爲insert();的函數)。如果我有一個3元素樹並且想要添加5個元素,我將不得不調用插入函數5次。這似乎是一個非常糟糕的方法,如果我想添加50個元素呢?必須有比調用insert()函數五十次更好的方法。如何構建大型二叉樹?
回答
如果數據是預先排序的,您可以遞歸構建它。
基本上建立了樹的一些輸入:
- 創建一個新的節點
- 如果輸入的是隻有一個條目,該節點的值是進入
- 否則:
- 在節點的左側子樹中,放置從輸入的前半部分構建的樹
- 在節點的右側子樹中,放置構建的樹M中的輸入
第三步將遞歸本身適用於輸入的多個部分的第二個一半。
下面是一些僞代碼:
FUNCTION TREE (input -> node)
IF input IS 1 ENTRY
VALUE OF node IS entry OF input
ELSE
SPLIT input IN 2
LEFT SUB-TREE OF node IS TREE(FIRST HALF OF input)
RIGHT SUB-TREE OF node IS TREE(SECOND HALF OF input)
下面是一些LINQPad C#代碼,你可以體驗:
// Add the following two using-directives to LINQPad:
// System.Drawing
// System.Drawing.Imaging
static Bitmap _Dummy = new Bitmap(16, 16, PixelFormat.Format24bppRgb);
static Font _Font = new Font("Arial", 12);
void Main()
{
var sorted = Enumerable.Range(1, 16).ToArray();
var tree = BuildTree(sorted);
Visualize(tree);
}
public Node<T> BuildTree<T>(T[] input)
{
return BuildTree<T>(input, 0, input.Length);
}
public Node<T> BuildTree<T>(T[] input, int left, int right)
{
if (right <= left)
return null;
if (right == left + 1)
return new Node<T> { Value = input[left] };
int middle = (left + right)/2;
return new Node<T>
{
Left = BuildTree<T>(input, left, middle),
Right = BuildTree<T>(input, middle, right)
};
}
public class Node<T>
{
public T Value;
public Node<T> Left;
public Node<T> Right;
public Bitmap ToBitmap()
{
Size valueSize;
using (Graphics g = Graphics.FromImage(_Dummy))
{
var tempSize = g.MeasureString(Value.ToString(), _Font);
valueSize = new Size((int)tempSize.Width + 4, (int)tempSize.Height + 4);
}
Bitmap bitmap;
Color valueColor = Color.LightPink;
if (Left == null && Right == null)
{
bitmap = new Bitmap(valueSize.Width, valueSize.Height);
using (var g = Graphics.FromImage(bitmap))
g.Clear(Color.White);
valueColor = Color.LightGreen;
}
else
{
using (var leftBitmap = Left.ToBitmap())
using (var rightBitmap = Right.ToBitmap())
{
int subNodeHeight = Math.Max(leftBitmap.Height, rightBitmap.Height);
bitmap = new Bitmap(
leftBitmap.Width + rightBitmap.Width + valueSize.Width,
valueSize.Height + 32 + subNodeHeight);
using (var g = Graphics.FromImage(bitmap))
{
g.Clear(Color.White);
int baseY = valueSize.Height + 32;
int leftTop = baseY; // + (subNodeHeight - leftBitmap.Height)/2;
g.DrawImage(leftBitmap, 0, leftTop);
int rightTop = baseY; // + (subNodeHeight - rightBitmap.Height)/2;
g.DrawImage(rightBitmap, bitmap.Width - rightBitmap.Width, rightTop);
g.DrawLine(Pens.Black, bitmap.Width/2 - 4, valueSize.Height, leftBitmap.Width/2, leftTop);
g.DrawLine(Pens.Black, bitmap.Width/2 + 4, valueSize.Height, bitmap.Width - rightBitmap.Width/2, rightTop);
}
}
}
using (var g = Graphics.FromImage(bitmap))
{
float x = (bitmap.Width - valueSize.Width)/2;
using (var b = new SolidBrush(valueColor))
g.FillRectangle(b, x, 0, valueSize.Width - 1, valueSize.Height - 1);
g.DrawRectangle(Pens.Black, x, 0, valueSize.Width - 1, valueSize.Height - 1);
if (Left == null && Right == null)
g.DrawString(Value.ToString(), _Font, Brushes.Black, x + 1, 2);
}
return bitmap;
}
}
void Visualize<T>(Node<T> node)
{
node.ToBitmap().Dump();
}
這裏的輸出:
謝謝你的回答。我給了你一個+1,但我想在獎勵獎金之前完全確信如何做到這一點 - 我不是。我有點同意你提供的步驟,但你的僞代碼不符合它。 '創建一個新節點',你如何遞歸地創建不同的節點,特別是使用像C/C++這樣的語言,你必須使用指針?在你的僞代碼中,你也沒有指定如何構建任何樹,這正是我正在尋找的。在你的步驟中,你會說:「放置從上半年建造的樹」,但這是如何發生的? – user2202911
另外 - 在您提供的C#代碼中,特別是Build
「輸入」是一個有序的輸入數組。左邊從0開始,右邊總是以數組長度開始。 –
- 1. 構建二叉樹圖
- 2. 如何建立二叉樹
- 3. 如何創建二叉樹
- 4. 二叉樹,基於前序構建樹
- 5. 如何創建二叉樹(非二叉搜索樹)
- 6. 創建二叉樹
- 7. 二叉樹中最大的二叉樹搜索樹
- 8. 需要創建二叉樹結構
- 9. 使用foldr構建平衡二叉樹
- 10. 構建方法來搜索二叉樹
- 11. 從預置位bitstring構建二叉樹
- 12. 構建二叉搜索樹在Java中
- 13. 遞歸構建二叉搜索樹
- 14. 如何獲取二叉樹的大小?
- 15. 二叉樹和結構
- 16. EXC_BAD_ACCESS二叉樹構造
- 17. 二叉樹,構造函數
- 18. 最大和二叉樹
- 19. 構建四叉樹
- 20. 使用二叉樹型
- 21. 二叉樹到二叉搜索樹(BST)
- 22. 二叉樹 - 哪一種二叉樹
- 23. 如何從給定的輸入構建二叉樹
- 24. 如何從給定接口構建二叉樹
- 25. 如何從帖子訂單構建二叉樹
- 26. 我如何使用boost :: shared_ptr構建二叉樹
- 27. 如何構建一個非遞歸的二叉樹?
- 28. 如何在O(N)時間構建二叉樹?
- 29. 從Stack創建二叉樹?
- 30. fork()和二叉樹創建
做一個快速谷歌尋找平衡的二叉樹來找到像[wik I](http://en.wikipedia.org/wiki/Self-balancing_binary_search_tree)。 –