मैं निम्न विधि है कि आप मनमाने ढंग से सबट्री प्रिंट करने देता है के साथ समाप्त हो गया है:
public static class BTreePrinter
{
class NodeInfo
{
public BNode Node;
public string Text;
public int StartPos;
public int Size { get { return Text.Length; } }
public int EndPos { get { return StartPos + Size; } set { StartPos = value - Size; } }
public NodeInfo Parent, Left, Right;
}
public static void Print(this BNode root, string textFormat = "0", int spacing = 1, int topMargin = 2, int leftMargin = 2)
{
if (root == null) return;
int rootTop = Console.CursorTop + topMargin;
var last = new List<NodeInfo>();
var next = root;
for (int level = 0; next != null; level++)
{
var item = new NodeInfo { Node = next, Text = next.item.ToString(textFormat) };
if (level < last.Count)
{
item.StartPos = last[level].EndPos + spacing;
last[level] = item;
}
else
{
item.StartPos = leftMargin;
last.Add(item);
}
if (level > 0)
{
item.Parent = last[level - 1];
if (next == item.Parent.Node.left)
{
item.Parent.Left = item;
item.EndPos = Math.Max(item.EndPos, item.Parent.StartPos - 1);
}
else
{
item.Parent.Right = item;
item.StartPos = Math.Max(item.StartPos, item.Parent.EndPos + 1);
}
}
next = next.left ?? next.right;
for (; next == null; item = item.Parent)
{
int top = rootTop + 2 * level;
Print(item.Text, top, item.StartPos);
if (item.Left != null)
{
Print("/", top + 1, item.Left.EndPos);
Print("_", top, item.Left.EndPos + 1, item.StartPos);
}
if (item.Right != null)
{
Print("_", top, item.EndPos, item.Right.StartPos - 1);
Print("\\", top + 1, item.Right.StartPos - 1);
}
if (--level < 0) break;
if (item == item.Parent.Left)
{
item.Parent.StartPos = item.EndPos + 1;
next = item.Parent.Node.right;
}
else
{
if (item.Parent.Left == null)
item.Parent.EndPos = item.StartPos - 1;
else
item.Parent.StartPos += (item.StartPos - 1 - item.Parent.EndPos)/2;
}
}
}
Console.SetCursorPosition(0, rootTop + 2 * last.Count - 1);
}
private static void Print(string s, int top, int left, int right = -1)
{
Console.SetCursorPosition(left, top);
if (right < 0) right = left + s.Length;
while (Console.CursorLeft < right) Console.Write(s);
}
}
आप देख सकते हैं, मैं मैंने कुछ पैरामीटर जोड़े जो स्वरूपण को प्रभावित करते हैं। डिफ़ॉल्ट रूप से यह सबसे कॉम्पैक्ट प्रतिनिधित्व पैदा करता है।
ताकि इसे साथ खेलने के लिए में, मैं BTree
वर्ग संशोधित कर लिया है इस प्रकार है:
btr.Root.Print();
:
public class BTree
{
// ...
public BNode Root { get { return _root; } }
public void Print()
{
Root.Print();
}
}
अपने नमूना डेटा का उपयोग करना, यहाँ कुछ परिणाम हैं
btr.Root.Print(textFormat: "(0)", spacing: 2);
अद्यतन: IMO ऊपर डिफ़ॉल्ट प्रारूप कॉम्पैक्ट और पठनीय है, लेकिन सिर्फ मनोरंजन के लिए, एल्गोरिथ्म अधिक "चित्रमय" उत्पादन का उत्पादन करने के लिए (textFormat
और spacing
पैरामीटर निकाल दिए) समायोजित:
public static class BTreePrinter
{
class NodeInfo
{
public BNode Node;
public string Text;
public int StartPos;
public int Size { get { return Text.Length; } }
public int EndPos { get { return StartPos + Size; } set { StartPos = value - Size; } }
public NodeInfo Parent, Left, Right;
}
public static void Print(this BNode root, int topMargin = 2, int leftMargin = 2)
{
if (root == null) return;
int rootTop = Console.CursorTop + topMargin;
var last = new List<NodeInfo>();
var next = root;
for (int level = 0; next != null; level++)
{
var item = new NodeInfo { Node = next, Text = next.item.ToString(" 0 ") };
if (level < last.Count)
{
item.StartPos = last[level].EndPos + 1;
last[level] = item;
}
else
{
item.StartPos = leftMargin;
last.Add(item);
}
if (level > 0)
{
item.Parent = last[level - 1];
if (next == item.Parent.Node.left)
{
item.Parent.Left = item;
item.EndPos = Math.Max(item.EndPos, item.Parent.StartPos);
}
else
{
item.Parent.Right = item;
item.StartPos = Math.Max(item.StartPos, item.Parent.EndPos);
}
}
next = next.left ?? next.right;
for (; next == null; item = item.Parent)
{
Print(item, rootTop + 2 * level);
if (--level < 0) break;
if (item == item.Parent.Left)
{
item.Parent.StartPos = item.EndPos;
next = item.Parent.Node.right;
}
else
{
if (item.Parent.Left == null)
item.Parent.EndPos = item.StartPos;
else
item.Parent.StartPos += (item.StartPos - item.Parent.EndPos)/2;
}
}
}
Console.SetCursorPosition(0, rootTop + 2 * last.Count - 1);
}
private static void Print(NodeInfo item, int top)
{
SwapColors();
Print(item.Text, top, item.StartPos);
SwapColors();
if (item.Left != null)
PrintLink(top + 1, "┌", "┘", item.Left.StartPos + item.Left.Size/2, item.StartPos);
if (item.Right != null)
PrintLink(top + 1, "└", "┐", item.EndPos - 1, item.Right.StartPos + item.Right.Size/2);
}
private static void PrintLink(int top, string start, string end, int startPos, int endPos)
{
Print(start, top, startPos);
Print("─", top, startPos + 1, endPos);
Print(end, top, endPos);
}
private static void Print(string s, int top, int left, int right = -1)
{
Console.SetCursorPosition(left, top);
if (right < 0) right = left + s.Length;
while (Console.CursorLeft < right) Console.Write(s);
}
private static void SwapColors()
{
var color = Console.ForegroundColor;
Console.ForegroundColor = Console.BackgroundColor;
Console.BackgroundColor = color;
}
}
और परिणाम है:
मैं इस अन्य लिंक में दृष्टिकोण अच्छे लग रहा है लगता है और अधिक कॉम्पैक्ट: http://stackoverflow.com/a/1649223/831138। इस तथ्य में "कॉम्पैक्ट" कि एक ही स्क्रीन स्पेस में अधिक जानकारी फिट कर सकता है ... बेशक यह इसे लंबवत रूप से फैलाने जा रहा है, लेकिन कंसोल की स्क्रॉलबार का उपयोग करना कोई समस्या नहीं होनी चाहिए ... क्षैतिज से बाहर चलना अंतरिक्ष एक समस्या है। –
[ट्री विज़ुअलाइजेशन एल्गोरिदम] का संभावित डुप्लिकेट (http://stackoverflow.com/questions/8368386/tree-visualization-algorithm) – mbeckish
http://stackoverflow.com/questions/801740/c-how-to-draw-a -बिनरी-पेड़-टू-द-कंसोल – fubo