BuildTree 代码1次CODE完,没有BUG.
在画图地方debug了很多次.第一次画这种图.
一开始用treeview显示,但发现不是很好看出树结构,于是自己动手画了出来.
1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Data; 5 using System.Drawing; 6 using System.Linq; 7 using System.Text; 8 using System.Windows.Forms; 9 10 namespace 二叉查找树 11 { 12 public partial class Form1 : Form 13 { 14 public Form1() 15 { 16 InitializeComponent(); 17 18 //BuildTreeView(topNode , treeView1.Nodes); 19 treeView1.Visible = false; 20 } 21 BNode<int> topNode; 22 private void Form1_Click(object sender, EventArgs e) 23 { 24 var lastNode = RandomGenBSPTree(50); 25 topNode = lastNode.GetTopNode(); 26 //r1 += 0.1f; 27 DrawTree(topNode, 1); 28 29 maxLevel = dicLevel.Count; 30 Bitmap b = new Bitmap((marginX + blockWidth) * maxLevel, (marginY + blockHeight) * maxLevel); 31 var g = Graphics.FromImage(b); 32 g.Clear(Color.Black); 33 DrawTree2(topNode, g, b.Width / 2 - blockWidth / 2, 20,false,true); 34 DrawTree3(topNode, g); 35 int minI=0,maxI = 0; 36 for (int i = 0; i < b.Width; i++) 37 { 38 for (int y = 0; y < b.Height; y++) 39 { 40 if (b.GetPixel(i, y).R != 0 || b.GetPixel(i, y).G != 0 || b.GetPixel(i, y).B != 0) 41 goto QUITMAXI; 42 } 43 minI = i; 44 } 45 QUITMAXI: 46 for (int i = 0; i < b.Width-minI; i++) 47 { 48 int id=b.Width - 2 - i; 49 int ct = 0; 50 for (int y = 0; y < b.Height; y++) 51 { 52 if (b.GetPixel(id, y).R != 0 || b.GetPixel(id, y).G != 0 || b.GetPixel(id, y).B != 0) 53 ct++; 54 if(ct>50) 55 goto QUITMIN; 56 } 57 maxI = id; 58 } 59 QUITMIN: 60 Bitmap bmpOut = new Bitmap(maxI-minI, b.Height); 61 Graphics g2 = Graphics.FromImage(bmpOut); 62 g2.DrawImage(b, new Rectangle(0, 0, bmpOut.Width, bmpOut.Height), new Rectangle(minI-20, 0, maxI, b.Height), GraphicsUnit.Pixel); 63 64 this.BackgroundImage = bmpOut; 65 } 66 67 void BuildTreeView(BNode<int> node,TreeNodeCollection tn) 68 { 69 if (node == null) return; 70 var newNode= tn.Add(node.value.ToString()); 71 BuildTreeView(node.left, newNode.Nodes); 72 BuildTreeView(node.right, newNode.Nodes); 73 } 74 int blockWidth = 300; 75 int minBlockWidth = 10; 76 int blockHeight = 40; 77 int marginX = 10; 78 int marginY = 10; 79 int maxLevel = 0; 80 Font font = new Font("宋体",12,FontStyle.Bold); 81 Brush brush = new SolidBrush(Color.White); 82 Dictionary<int, List<BNode<int>>> dicLevel = new Dictionary<int, List<BNode<int>>>(); 83 void DrawTree(BNode<int> node,int level) 84 { 85 if (node == null) return; 86 if (dicLevel.ContainsKey(level) == false) 87 dicLevel.Add(level,new List<BNode<int>>()); 88 dicLevel[level].Add(node); 89 node.level = level; 90 DrawTree(node.left,level+1); 91 DrawTree(node.right, level + 1); 92 } 93 94 void DrawTree2(BNode<int> node , Graphics g,int x,int y , bool isLeft=false,bool isRoot=false) 95 { 96 if (node == null) return; 97 98 if (isRoot){ 99 g.DrawString(node.value.ToString(), font, brush, x, y); 100 node.pos = new Point(x, y); 101 } 102 else 103 { 104 105 Text = r1.ToString(); 106 var rate = (int)(blockWidth - r1*Math.Pow(node.level,2) * marginX); 107 rate = rate < minBlockWidth ? minBlockWidth : rate; 108 node.pos = new Point(x + (isLeft ? -1 : 1) * (rate), y + blockHeight + marginY); 109 g.DrawString(node.value.ToString(), font, brush, node.pos.X, node.pos.Y); 110 } 111 112 DrawTree2(node.left, g, node.pos.X, node.pos.Y, true); 113 DrawTree2(node.right, g, node.pos.X, node.pos.Y, false); 114 } 115 float r1=1f; 116 void DrawTree3(BNode<int> node, Graphics g) 117 { 118 if (node == null) return; 119 if (node.left != null) 120 g.DrawLine( new Pen(Color.Green,2.1f),node.pos,node.left.pos); 121 if (node.right != null) 122 g.DrawLine(new Pen(Color.Green, 2.1f), node.pos, node.right.pos); 123 DrawTree3(node.left , g); 124 DrawTree3(node.right, g); 125 } 126 127 BNode<int> RandomGenBSPTree(int Count) 128 { 129 var r = new Random(); 130 List<int> pool = new List<int>(); 131 132 BNode<int> curNode = new BNode<int>(); 133 curNode.value = 50; 134 pool.Add(curNode.value); 135 for (int i = 0; i < Count; i++) 136 { 137 do 138 { 139 var newValue = r.Next(1, 100); 140 if (pool.Contains(newValue) == false) 141 { 142 pool.Add(newValue); 143 break; 144 } 145 146 }while(true); 147 148 curNode.Insert(pool[pool.Count-1]); 149 } 150 return curNode; 151 } 152 153 class BNode<T>where T:IComparable 154 { 155 public BNode<T> left; 156 public BNode<T> right; 157 public BNode<T> parent; 158 public T value; 159 public int level; 160 public string text; 161 public Point pos; 162 public void Insert(T v) 163 { 164 var firstCompare=v.CompareTo( value ); 165 BNode<T> nextCompare=firstCompare<0?left:right; 166 167 if (nextCompare != null) 168 { 169 nextCompare.Insert(v); 170 } 171 else 172 { 173 if (firstCompare < 0) 174 left = new BNode<T> { parent=this, value=v }; 175 else 176 right = new BNode<T> { parent = this, value = v }; 177 } 178 } 179 180 public BNode<T> GetTopNode() 181 { 182 if (parent != null) 183 return parent.GetTopNode(); 184 else 185 return this; 186 } 187 } 188 189 } 190 }