重拾算法(3)——用458329个测试用例全面测试二叉树和线索二叉树的遍历算法
重拾算法(3)——用458329个测试用例全面测试二叉树和线索二叉树的遍历算法
在"上一篇"和"上上一篇"中,我给出了二叉树和线索二叉树的遍历算法。给出算法容易,证明算法的正确性就不容易了。本文就通过自动化测试的方式证明给出的遍历算法是完全正确的。458329个测试用例是深度为1到5的所有的树结构的形态,所以我才胆敢说是"全面"测试。
我的证明思路如下
只需对深度为1到5的所有形态的树结构分别进行测试即可
如果我的遍历算法对深度为1到5的所有形态的树结构都是正确的,那么我就确信这个算法是完全正确的。
测试一个二叉树T的方法:分别用递归算法(记为R)和非递归算法(记为NR)对其进行遍历,如果遍历顺序相同,就说明两个算法都是正确的。
实际上如果能够得到深度为1到5的树结构,自然也可以得到6、7、8...的,但是深度到5的时候,不同形态的树结构就有458329种了,得到的结果文件就有800M,再深一度我怕我可怜的PC就受不了了,所以深度就到5为止。
注:测试线索二叉树是用线索二叉树的遍历方法和一般二叉树的遍历方法(即刚刚的NR)进行对比测试的。一般二叉树的遍历方法我用的也是非递归的。
想办法得到所有深度为1、2、3、4、5的树结构,记为集合S
这个只能通过程序去计算获得,手工一个一个写是不现实的。后文将讲述如何计算。
对S中每一个树T:
按照前序遍历的顺序,对T中的结点依次编号0、1、2、3、4、...(按照中序、后序、层次遍历的顺序编号也可以,编号只是为了区分各个结点)
仿照DOS里的树结构的显示方式显示T的结构,举例如下:
按先序遍历对结点进行编号的某树
1 tree 577: 2 [0] 3 ├─[1] 4 │ ├─[2] 5 │ │ ├─null 6 │ │ └─null 7 │ └─[3] 8 │ ├─[4] 9 │ │ ├─null 10 │ │ └─null 11 │ └─[5] 12 │ ├─null 13 │ └─null 14 └─[6] 15 ├─[7] 16 │ ├─[8] 17 │ │ ├─null 18 │ │ └─null 19 │ └─null 20 └─[9] 21 ├─null 22 └─[10] 23 ├─null 24 └─null
对树T依次进行前序、中序、后序遍历,每种遍历都使用非递归和递归两种方式进行,每种方式都按照遍历顺序输出结点编号,然后对比两种方式的输出结果是否相同(相同表示算法正确,否则表示算法错误)
记录所有出错的用例,用以发现算法的纰漏并修改。
我已经根据出错的情形进行分析,完善了算法,现在已经是0 error了。
得到所有深度为1到5的树结构
深度为1的树结构只有1个
1 tree 1: 2 ([0]) 3 ├─null 4 └─null
深度为2的树结构有3个
1 tree 2: 2 [0] 3 ├─[1] 4 │ ├─null 5 │ └─null 6 └─null 7 tree 3: 8 [0] 9 ├─null 10 └─[1] 11 ├─null 12 └─null 13 tree 4: 14 [0] 15 ├─[1] 16 │ ├─null 17 │ └─null 18 └─[2] 19 ├─null 20 └─null
深度为3的树结构有21个
1 tree 5: 2 [0] 3 ├─[1] 4 │ ├─[2] 5 │ │ ├─null 6 │ │ └─null 7 │ └─null 8 └─null 9 tree 6: 10 [0] 11 ├─[1] 12 │ ├─null 13 │ └─[2] 14 │ ├─null 15 │ └─null 16 └─null 17 tree 7: 18 [0] 19 ├─[1] 20 │ ├─[2] 21 │ │ ├─null 22 │ │ └─null 23 │ └─[3] 24 │ ├─null 25 │ └─null 26 └─null 27 tree 8: 28 [0] 29 ├─null 30 └─[1] 31 ├─[2] 32 │ ├─null 33 │ └─null 34 └─null 35 tree 9: 36 [0] 37 ├─null 38 └─[1] 39 ├─null 40 └─[2] 41 ├─null 42 └─null 43 tree 10: 44 [0] 45 ├─null 46 └─[1] 47 ├─[2] 48 │ ├─null 49 │ └─null 50 └─[3] 51 ├─null 52 └─null 53 tree 11: 54 [0] 55 ├─[1] 56 │ ├─[2] 57 │ │ ├─null 58 │ │ └─null 59 │ └─null 60 └─[3] 61 ├─null 62 └─null 63 tree 12: 64 [0] 65 ├─[1] 66 │ ├─null 67 │ └─[2] 68 │ ├─null 69 │ └─null 70 └─[3] 71 ├─null 72 └─null 73 tree 13: 74 [0] 75 ├─[1] 76 │ ├─[2] 77 │ │ ├─null 78 │ │ └─null 79 │ └─[3] 80 │ ├─null 81 │ └─null 82 └─[4] 83 ├─null 84 └─null 85 tree 14: 86 [0] 87 ├─[1] 88 │ ├─null 89 │ └─null 90 └─[2] 91 ├─[3] 92 │ ├─null 93 │ └─null 94 └─null 95 tree 15: 96 [0] 97 ├─[1] 98 │ ├─[2] 99 │ │ ├─null 100 │ │ └─null 101 │ └─null 102 └─[3] 103 ├─[4] 104 │ ├─null 105 │ └─null 106 └─null 107 tree 16: 108 [0] 109 ├─[1] 110 │ ├─null 111 │ └─[2] 112 │ ├─null 113 │ └─null 114 └─[3] 115 ├─[4] 116 │ ├─null 117 │ └─null 118 └─null 119 tree 17: 120 [0] 121 ├─[1] 122 │ ├─[2] 123 │ │ ├─null 124 │ │ └─null 125 │ └─[3] 126 │ ├─null 127 │ └─null 128 └─[4] 129 ├─[5] 130 │ ├─null 131 │ └─null 132 └─null 133 tree 18: 134 [0] 135 ├─[1] 136 │ ├─null 137 │ └─null 138 └─[2] 139 ├─null 140 └─[3] 141 ├─null 142 └─null 143 tree 19: 144 [0] 145 ├─[1] 146 │ ├─[2] 147 │ │ ├─null 148 │ │ └─null 149 │ └─null 150 └─[3] 151 ├─null 152 └─[4] 153 ├─null 154 └─null 155 tree 20: 156 [0] 157 ├─[1] 158 │ ├─null 159 │ └─[2] 160 │ ├─null 161 │ └─null 162 └─[3] 163 ├─null 164 └─[4] 165 ├─null 166 └─null 167 tree 21: 168 [0] 169 ├─[1] 170 │ ├─[2] 171 │ │ ├─null 172 │ │ └─null 173 │ └─[3] 174 │ ├─null 175 │ └─null 176 └─[4] 177 ├─null 178 └─[5] 179 ├─null 180 └─null 181 tree 22: 182 [0] 183 ├─[1] 184 │ ├─null 185 │ └─null 186 └─[2] 187 ├─[3] 188 │ ├─null 189 │ └─null 190 └─[4] 191 ├─null 192 └─null 193 tree 23: 194 [0] 195 ├─[1] 196 │ ├─[2] 197 │ │ ├─null 198 │ │ └─null 199 │ └─null 200 └─[3] 201 ├─[4] 202 │ ├─null 203 │ └─null 204 └─[5] 205 ├─null 206 └─null 207 tree 24: 208 [0] 209 ├─[1] 210 │ ├─null 211 │ └─[2] 212 │ ├─null 213 │ └─null 214 └─[3] 215 ├─[4] 216 │ ├─null 217 │ └─null 218 └─[5] 219 ├─null 220 └─null 221 tree 25: 222 [0] 223 ├─[1] 224 │ ├─[2] 225 │ │ ├─null 226 │ │ └─null 227 │ └─[3] 228 │ ├─null 229 │ └─null 230 └─[4] 231 ├─[5] 232 │ ├─null 233 │ └─null 234 └─[6] 235 ├─null 236 └─null
深度为4的树结构有651个,深度为5的树结构有457653个,这就太多了,此处不能一一列举。
规律
通过深度为1、2、3的树结构,可以找到一些重要的规律。
深度为2的树结构(记为T2-1、T2-2、T2-3),可以由深度为1的树结构(记为T1-1)按如下规则进化而来:
T1-1有1个结点,这个结点一共有2*1个为null的Left/Right,只要分别给他们连上1个或0个新结点,就成了T2中的某一个(2^(2*1)-1=3);而所有这种连法就恰好得到了所有的T2的情况(即3)。
为什么要"-1"呢?因为如果两个为null的Left/Right都不连新结点,就仍然为T1-1,就是没有真正进化,所以要去掉这种情况。
再进一步看一下。
深度为3的树结构(记为T3-1、T3-2、T3-3、...),可以由深度为2的树结构(T2-1、T2-2、T2-3)按如下规则进化而来:
T2-1的深度最大的结点有1个,这些深度最大的结点一共有2*1个为null的Left/Right,只要分别给他们连上1个或0个新结点,就成了T2中的某一个(2^(2*1)-1=3)。
T2-2的深度最大的结点有1个,这些深度最大的结点一共有2*1个为null的Left/Right,只要分别给他们连上1个或0个新结点,就成了T2中的某一个(2^(2*1)-1=3)。
T2-3的深度最大的结点有2个,这些深度最大的结点一共有2*2个为null的Left/Right,只要分别给他们连上1个或0个新结点,就成了T2中的某一个(2^(2*2)-1=15)。
同上的原因,我们要记得"-1"。
而所有这种连法就恰好得到了所有的T3的情况(3+3+15=21种情况)。
好了,现在获取所有深度为1、2、3、4、5的树结构的方法已经很明显了。深度为N的树结构要通过深度为N-1的树结构进化得到。
写代码之前,还要考虑一个小问题,深度为1到5的树结构有458329个,如果一次性获取458329个树结构(我一开始就是这么办的),我的PC内存就受不了了,卡的要死要活的。所以我改进一下,每得到一个新的树结构,就立即对其进行测试;如果这个树结构的深度为maxDepth,测试之后就将其丢弃,静待.NET将其空间回收。这样效果就好多了,深度为5都没有卡顿。
测试线索二叉树的代码
下面是测试线索二叉树的代码。测试普通的二叉树代码和这个原理是一样的。
首先是测试一个树结构
1 static bool TestNode(ThreadedBinaryTreeNode<T> node, int index) 2 { 3 var arranger = new IntArranger<T>(); 4 node.Traverse(TraverseOrder.Preorder, arranger);//给各个树结点编号 5 Console.WriteLine("--------------------------------------------------------------------------------"); 6 Console.WriteLine("tree {0}:", index); 7 Console.WriteLine(node.ToTree());//打印树结构 8 var result = true; 9 foreach (var order in Enum.GetNames(typeof(TraverseOrder)))//分别用前序中序后序层次的遍历方式进行测试 10 { 11 Console.WriteLine(order + ":"); 12 var o = (TraverseOrder)Enum.Parse(typeof(TraverseOrder), order); 13 var nonRecursiveOutput = string.Empty; 14 { 15 var printer = new Printer<T>(); 16 node.Traverse(o, printer);//用线索二叉树的遍历方式测试 17 nonRecursiveOutput = printer.ToString();//获取结点的遍历顺序 18 } 19 var recursiveOutput = string.Empty; 20 { 21 var printer = new Printer<T>(); 22 node.NormalTraverse(o, printer);//用一般二叉树的遍历方式测试 23 recursiveOutput = printer.ToString();//获取结点的遍历顺序 24 } 25 if (nonRecursiveOutput != recursiveOutput)//对比两种方法得到的结果是否相同 26 { 27 Console.WriteLine("Error: different output from traverse and recursive traverse!"); 28 Console.WriteLine(" traverse:"); 29 Console.WriteLine(nonRecursiveOutput); 30 Console.WriteLine(" recursive traverse:"); 31 Console.WriteLine(recursiveOutput); 32 result = false;//测试结果failed,标记一下,以供统计 33 } 34 else 35 { 36 Console.WriteLine(nonRecursiveOutput); 37 } 38 39 } 40 return result; 41 }
然后是生成和测试所有深度为1到maxDepth的树结构
1 public static void Test(int maxDepth) 2 { 3 Console.WriteLine("Testing ThreadedBinaryTreeNode<T>.Traverse()"); 4 5 if (maxDepth <= 0) { return; } 6 7 var firstNode = new ThreadedBinaryTreeNode<T>(); 8 var queue = new Queue<ThreadedBinaryTreeNode<T>>(); 9 queue.Enqueue(firstNode); 10 var errorCount = 0; 11 var testCaseIndex = 1; 12 var successful = TestNode(firstNode, testCaseIndex++);//测试深度为1的树结构 13 if (!successful) { errorCount++; } 14 15 if (maxDepth > 1) 16 { 17 while (queue.Count > 0)//由深度为N的树结构进化出深度为N+1的树结构 18 { 19 var node = queue.Dequeue();//获取下一个要进行进化的树结构的根节点node 20 21 var recorder = new DeepestLeaveRecorder<T>(); 22 node.Traverse(TraverseOrder.Layer, recorder);//获取此树结构所有深度为最深的结点 23 var deepestLeavesCount = recorder.DeepestLeaves.Count; 24 var booleanList = new List<bool>();//booleanList充当是否连上新结点的标记,true为连,false为不连。 25 for (var i = 0; i < deepestLeavesCount * 2; i++) 26 { 27 booleanList.Add(false);//booleanList相当于一个二进制数 28 } 29 var derivedNodesCount = Math.Pow(2, deepestLeavesCount * 2) - 1;//node有这么多种进化方式 30 for (var i = 0; i < derivedNodesCount; i++) 31 { 32 IncreaseBooleanList(booleanList);//对booleanList进行“加1”操作,以获取下一个进化方式 33 var newNode = node.Clone() as ThreadedBinaryTreeNode<T>; 34 var r = new DeepestLeaveRecorder<T>(); 35 newNode.Traverse(TraverseOrder.Layer, r);//获取待进化的树结构所有深度为最深的结点 36 var index = 0; 37 foreach (var leave in r.DeepestLeaves) 38 { 39 if (booleanList[index * 2])//对leave这一结点的Left进行连接 40 { 41 var n = new ThreadedBinaryTreeNode<T>(); 42 leave.Point2PreviousNode = false; leave.Left = n; 43 n.Parent = leave; 44 } 45 if (booleanList[index * 2 + 1])//对leave这一结点的Right进行连接 46 { 47 var n = new ThreadedBinaryTreeNode<T>(); 48 leave.Point2NextNode = false; leave.Right = n; 49 n.Parent = leave; 50 } 51 index++; 52 } 53 var depth = newNode.GetDepth(); 54 if (depth < maxDepth)//深度不足maxDepth,说明此newNode还应该进化,因此入队待用 55 { 56 queue.Enqueue(newNode); 57 } 58 successful = TestNode(newNode, testCaseIndex++);//测试newNode 59 if (!successful) { errorCount++; } 60 } 61 } 62 } 63 Console.WriteLine("--------------------------------------------------------------------------------"); 64 Console.WriteLine("{0} error(s) occured.", errorCount); 65 }
下面是一些辅助用的代码。
遍历时对每个结点node依次调用DoActionOnNode方法。
1 public abstract class ThreadedNodeWorker<T> 2 { 3 public abstract void DoActionOnNode(ThreadedBinaryTreeNode<T> node); 4 }
对树节点进行编号
1 class IntArranger<TI> : ThreadedNodeWorker<TI> 2 { 3 int index = 0; 4 public override void DoActionOnNode(ThreadedBinaryTreeNode<TI> node) 5 { 6 node.Id = index; 7 index++; 8 } 9 }
获取树结构的遍历顺序
1 class Printer<TP> : ThreadedNodeWorker<TP> 2 { 3 public override String ToString() 4 { 5 return builder.ToString(); 6 } 7 StringBuilder builder = new StringBuilder(); 8 public override void DoActionOnNode(ThreadedBinaryTreeNode<TP> node) 9 { 10 var strNode = node.ToString(); 11 builder.Append(strNode); 12 } 13 }
获取树结构所有深度为最深的结点
1 class DeepestLeaveRecorder<TD> : ThreadedNodeWorker<TD> 2 { 3 List<ThreadedBinaryTreeNode<TD>> deepestLeaves = new List<ThreadedBinaryTreeNode<TD>>(); 4 public IList<ThreadedBinaryTreeNode<TD>> DeepestLeaves 5 { get { return this.deepestLeaves; } } 6 Dictionary<ThreadedBinaryTreeNode<TD>, int> nodeDepthDict = new Dictionary<ThreadedBinaryTreeNode<TD>, int>(); 7 int deepestDeep = 0; 8 public override void DoActionOnNode(ThreadedBinaryTreeNode<TD> node) 9 { 10 if (node == null) { return; } 11 if (nodeDepthDict.ContainsKey(node)) { return; } 12 var depthOfNode = GetDepthOfNode(node); 13 nodeDepthDict.Add(node, depthOfNode); 14 if (deepestDeep == depthOfNode) 15 { 16 deepestLeaves.Add(node); 17 } 18 else if (deepestDeep < depthOfNode) 19 { 20 deepestLeaves.Clear(); 21 deepestLeaves.Add(node); 22 deepestDeep = depthOfNode; 23 } 24 } 25 26 int GetDepthOfNode(ThreadedBinaryTreeNode<TD> node) 27 { 28 if (node == null) { return 0; } 29 var result = 1; 30 while (node.Parent != null) 31 { 32 result++; 33 node = node.Parent; 34 } 35 return result; 36 } 37 }
生成类DOS的树结构视图的代码
1 public partial class ThreadedBinaryTreeNode<T> 2 { 3 public String ToTree() 4 { 5 var builder = new StringBuilder(); 6 int tabSpace = 0; 7 GetBuilder(builder, this, ref tabSpace); 8 return builder.ToString(); 9 } 10 11 private void GetBuilder(StringBuilder builder, ThreadedBinaryTreeNode<T> node, ref int tabSpace, bool placeHolder = false, ThreadedBinaryTreeNode<T> parent = null, bool left = false) 12 { 13 if (placeHolder) 14 { 15 builder.Append(GetPremarks(null, placeHolder, parent, left)); 16 builder.AppendLine("null"); 17 } 18 else 19 { 20 if (node == null) { return; } 21 builder.Append(GetPremarks(node)); 22 builder.AppendLine(node.ToString()); 23 24 tabSpace++; 25 26 if ((node.Left != null) && (!node.Point2PreviousNode)) { GetBuilder(builder, node.Left, ref tabSpace); } 27 else { GetBuilder(builder, null, ref tabSpace, true, node, true); } 28 29 if ((node.Right != null) && (!node.Point2NextNode)) { GetBuilder(builder, node.Right, ref tabSpace); } 30 else { GetBuilder(builder, null, ref tabSpace, true, node, false); } 31 32 tabSpace--; 33 } 34 } 35 36 private string GetPremarks(ThreadedBinaryTreeNode<T> node, bool placeHolder = false, ThreadedBinaryTreeNode<T> parent = null, bool left = false) 37 { 38 ThreadedBinaryTreeNode<T> originalParent; 39 if (placeHolder) 40 { originalParent = parent; } 41 else 42 { originalParent = node.Parent; } 43 44 var ptrParent = originalParent; 45 if (ptrParent == null) return string.Empty; 46 var lstLine = new List<bool>(); 47 while (ptrParent != null) 48 { 49 var pp = ptrParent.Parent; 50 if (pp != null) 51 { 52 lstLine.Add((pp.Left == ptrParent));// && (pp.Right != null)); 53 } 54 ptrParent = pp; 55 } 56 var builder = new StringBuilder(); 57 for (var i = lstLine.Count - 1; i >=0; i--) 58 { 59 if (lstLine[i]) { builder.Append(" │ "); } 60 else { builder.Append(" "); } 61 } 62 if (placeHolder) 63 { 64 if (left) { builder.Append(" ├─"); } 65 else { builder.Append(" └─"); } 66 } 67 else 68 { 69 ptrParent = originalParent; 70 if ((ptrParent.Left == node))// && (ptrParent.Right != null)) 71 { builder.Append(" ├─"); } 72 else { builder.Append(" └─"); } 73 } 74 75 return builder.ToString(); 76 } 77 }
总结
我已经根据出错的用例完善了算法,现已成功通过所有458329个测试用例。
下面给出maxDepth为3时的输出结果:
1 Testing ThreadedBinaryTreeNode<T>.Traverse() 2 -------------------------------------------------------------------------------- 3 tree 1: 4 ([0]) 5 ├─null 6 └─null 7 8 Preorder: 9 ([0]) 10 Inorder: 11 ([0]) 12 Postorder: 13 ([0]) 14 Layer: 15 ([0]) 16 -------------------------------------------------------------------------------- 17 tree 2: 18 ([0]→1) 19 ├─(0←[1]) 20 │ ├─null 21 │ └─null 22 └─null 23 24 Preorder: 25 ([0]→1)(0←[1]) 26 Inorder: 27 ([1]→0)([0]) 28 Postorder: 29 ([1]→0)([0]) 30 Layer: 31 ([0]→1)(0←[1]) 32 -------------------------------------------------------------------------------- 33 tree 3: 34 ([0]) 35 ├─null 36 └─(0←[1]) 37 ├─null 38 └─null 39 40 Preorder: 41 ([0])(0←[1]) 42 Inorder: 43 ([0])(0←[1]) 44 Postorder: 45 ([1]→0)(1←[0]) 46 Layer: 47 ([0])(0←[1]) 48 -------------------------------------------------------------------------------- 49 tree 4: 50 ([0]) 51 ├─(0←[1]→2) 52 │ ├─null 53 │ └─null 54 └─(1←[2]) 55 ├─null 56 └─null 57 58 Preorder: 59 ([0])(0←[1]→2)(1←[2]) 60 Inorder: 61 ([1]→0)([0])(0←[2]) 62 Postorder: 63 ([1]→2)(1←[2]→0)([0]) 64 Layer: 65 ([0])(0←[1]→2)(1←[2]) 66 -------------------------------------------------------------------------------- 67 tree 5: 68 ([0]→1) 69 ├─([1]→2) 70 │ ├─(1←[2]) 71 │ │ ├─null 72 │ │ └─null 73 │ └─null 74 └─null 75 76 Preorder: 77 ([0]→1)([1]→2)(1←[2]) 78 Inorder: 79 ([2]→1)([1]→0)([0]) 80 Postorder: 81 ([2]→1)([1]→0)([0]) 82 Layer: 83 ([0]→1)([1]→2)(1←[2]) 84 -------------------------------------------------------------------------------- 85 tree 6: 86 ([0]→1) 87 ├─(0←[1]) 88 │ ├─null 89 │ └─(1←[2]) 90 │ ├─null 91 │ └─null 92 └─null 93 94 Preorder: 95 ([0]→1)(0←[1])(1←[2]) 96 Inorder: 97 ([1])(1←[2]→0)([0]) 98 Postorder: 99 ([2]→1)(2←[1])([0]) 100 Layer: 101 ([0]→1)(0←[1])(1←[2]) 102 -------------------------------------------------------------------------------- 103 tree 7: 104 ([0]→1) 105 ├─([1]) 106 │ ├─(1←[2]→3) 107 │ │ ├─null 108 │ │ └─null 109 │ └─(2←[3]) 110 │ ├─null 111 │ └─null 112 └─null 113 114 Preorder: 115 ([0]→1)([1])(1←[2]→3)(2←[3]) 116 Inorder: 117 ([2]→1)([1])(1←[3]→0)([0]) 118 Postorder: 119 ([2]→3)(2←[3]→1)([1])([0]) 120 Layer: 121 ([0]→1)([1])(1←[2]→3)(2←[3]) 122 -------------------------------------------------------------------------------- 123 tree 8: 124 ([0]) 125 ├─null 126 └─([1]→2) 127 ├─(1←[2]) 128 │ ├─null 129 │ └─null 130 └─null 131 132 Preorder: 133 ([0])([1]→2)(1←[2]) 134 Inorder: 135 ([0])(0←[2]→1)([1]) 136 Postorder: 137 ([2]→1)([1]→0)(1←[0]) 138 Layer: 139 ([0])([1]→2)(1←[2]) 140 -------------------------------------------------------------------------------- 141 tree 9: 142 ([0]) 143 ├─null 144 └─(0←[1]) 145 ├─null 146 └─(1←[2]) 147 ├─null 148 └─null 149 150 Preorder: 151 ([0])(0←[1])(1←[2]) 152 Inorder: 153 ([0])(0←[1])(1←[2]) 154 Postorder: 155 ([2]→1)(2←[1])(1←[0]) 156 Layer: 157 ([0])(0←[1])(1←[2]) 158 -------------------------------------------------------------------------------- 159 tree 10: 160 ([0]) 161 ├─null 162 └─([1]) 163 ├─(1←[2]→3) 164 │ ├─null 165 │ └─null 166 └─(2←[3]) 167 ├─null 168 └─null 169 170 Preorder: 171 ([0])([1])(1←[2]→3)(2←[3]) 172 Inorder: 173 ([0])(0←[2]→1)([1])(1←[3]) 174 Postorder: 175 ([2]→3)(2←[3]→1)([1])(1←[0]) 176 Layer: 177 ([0])([1])(1←[2]→3)(2←[3]) 178 -------------------------------------------------------------------------------- 179 tree 11: 180 ([0]) 181 ├─([1]→2) 182 │ ├─(1←[2]→3) 183 │ │ ├─null 184 │ │ └─null 185 │ └─null 186 └─(2←[3]) 187 ├─null 188 └─null 189 190 Preorder: 191 ([0])([1]→2)(1←[2]→3)(2←[3]) 192 Inorder: 193 ([2]→1)([1]→0)([0])(0←[3]) 194 Postorder: 195 ([2]→1)([1]→3)(1←[3]→0)([0]) 196 Layer: 197 ([0])([1]→3)(1←[3]→2)(3←[2]) 198 -------------------------------------------------------------------------------- 199 tree 12: 200 ([0]) 201 ├─(0←[1]) 202 │ ├─null 203 │ └─(1←[2]→3) 204 │ ├─null 205 │ └─null 206 └─(2←[3]) 207 ├─null 208 └─null 209 210 Preorder: 211 ([0])(0←[1])(1←[2]→3)(2←[3]) 212 Inorder: 213 ([1])(1←[2]→0)([0])(0←[3]) 214 Postorder: 215 ([2]→1)(2←[1])(1←[3]→0)([0]) 216 Layer: 217 ([0])(0←[1])(1←[3]→2)(3←[2]) 218 -------------------------------------------------------------------------------- 219 tree 13: 220 ([0]) 221 ├─([1]) 222 │ ├─(1←[2]→3) 223 │ │ ├─null 224 │ │ └─null 225 │ └─(2←[3]→4) 226 │ ├─null 227 │ └─null 228 └─(3←[4]) 229 ├─null 230 └─null 231 232 Preorder: 233 ([0])([1])(1←[2]→3)(2←[3]→4)(3←[4]) 234 Inorder: 235 ([2]→1)([1])(1←[3]→0)([0])(0←[4]) 236 Postorder: 237 ([2]→3)(2←[3]→1)([1])(1←[4]→0)([0]) 238 Layer: 239 ([0])([1])(1←[4]→2)(4←[2]→3)(2←[3]) 240 -------------------------------------------------------------------------------- 241 tree 14: 242 ([0]) 243 ├─(0←[1]→2) 244 │ ├─null 245 │ └─null 246 └─([2]→3) 247 ├─(2←[3]) 248 │ ├─null 249 │ └─null 250 └─null 251 252 Preorder: 253 ([0])(0←[1]→2)([2]→3)(2←[3]) 254 Inorder: 255 ([1]→0)([0])(0←[3]→2)([2]) 256 Postorder: 257 ([1]→3)(1←[3]→2)([2]→0)([0]) 258 Layer: 259 ([0])(0←[1]→2)([2]→3)(2←[3]) 260 -------------------------------------------------------------------------------- 261 tree 15: 262 ([0]) 263 ├─([1]→2) 264 │ ├─(1←[2]→3) 265 │ │ ├─null 266 │ │ └─null 267 │ └─null 268 └─([3]→4) 269 ├─(3←[4]) 270 │ ├─null 271 │ └─null 272 └─null 273 274 Preorder: 275 ([0])([1]→2)(1←[2]→3)([3]→4)(3←[4]) 276 Inorder: 277 ([2]→1)([1]→0)([0])(0←[4]→3)([3]) 278 Postorder: 279 ([2]→1)([1]→4)(1←[4]→3)([3]→0)([0]) 280 Layer: 281 ([0])([1]→3)([3]→2)(3←[2]→4)(2←[4]) 282 -------------------------------------------------------------------------------- 283 tree 16: 284 ([0]) 285 ├─(0←[1]) 286 │ ├─null 287 │ └─(1←[2]→3) 288 │ ├─null 289 │ └─null 290 └─([3]→4) 291 ├─(3←[4]) 292 │ ├─null 293 │ └─null 294 └─null 295 296 Preorder: 297 ([0])(0←[1])(1←[2]→3)([3]→4)(3←[4]) 298 Inorder: 299 ([1])(1←[2]→0)([0])(0←[4]→3)([3]) 300 Postorder: 301 ([2]→1)(2←[1])(1←[4]→3)([3]→0)([0]) 302 Layer: 303 ([0])(0←[1])([3]→2)(3←[2]→4)(2←[4]) 304 -------------------------------------------------------------------------------- 305 tree 17: 306 ([0]) 307 ├─([1]) 308 │ ├─(1←[2]→3) 309 │ │ ├─null 310 │ │ └─null 311 │ └─(2←[3]→4) 312 │ ├─null 313 │ └─null 314 └─([4]→5) 315 ├─(4←[5]) 316 │ ├─null 317 │ └─null 318 └─null 319 320 Preorder: 321 ([0])([1])(1←[2]→3)(2←[3]→4)([4]→5)(4←[5]) 322 Inorder: 323 ([2]→1)([1])(1←[3]→0)([0])(0←[5]→4)([4]) 324 Postorder: 325 ([2]→3)(2←[3]→1)([1])(1←[5]→4)([4]→0)([0]) 326 Layer: 327 ([0])([1])([4]→2)(4←[2]→3)(2←[3]→5)(3←[5]) 328 -------------------------------------------------------------------------------- 329 tree 18: 330 ([0]) 331 ├─(0←[1]→2) 332 │ ├─null 333 │ └─null 334 └─(1←[2]) 335 ├─null 336 └─(2←[3]) 337 ├─null 338 └─null 339 340 Preorder: 341 ([0])(0←[1]→2)(1←[2])(2←[3]) 342 Inorder: 343 ([1]→0)([0])(0←[2])(2←[3]) 344 Postorder: 345 ([1]→3)(1←[3]→2)(3←[2])([0]) 346 Layer: 347 ([0])(0←[1]→2)(1←[2])(2←[3]) 348 -------------------------------------------------------------------------------- 349 tree 19: 350 ([0]) 351 ├─([1]→2) 352 │ ├─(1←[2]→3) 353 │ │ ├─null 354 │ │ └─null 355 │ └─null 356 └─(2←[3]) 357 ├─null 358 └─(3←[4]) 359 ├─null 360 └─null 361 362 Preorder: 363 ([0])([1]→2)(1←[2]→3)(2←[3])(3←[4]) 364 Inorder: 365 ([2]→1)([1]→0)([0])(0←[3])(3←[4]) 366 Postorder: 367 ([2]→1)([1]→4)(1←[4]→3)(4←[3])([0]) 368 Layer: 369 ([0])([1]→3)(1←[3])(3←[2]→4)(2←[4]) 370 -------------------------------------------------------------------------------- 371 tree 20: 372 ([0]) 373 ├─(0←[1]) 374 │ ├─null 375 │ └─(1←[2]→3) 376 │ ├─null 377 │ └─null 378 └─(2←[3]) 379 ├─null 380 └─(3←[4]) 381 ├─null 382 └─null 383 384 Preorder: 385 ([0])(0←[1])(1←[2]→3)(2←[3])(3←[4]) 386 Inorder: 387 ([1])(1←[2]→0)([0])(0←[3])(3←[4]) 388 Postorder: 389 ([2]→1)(2←[1])(1←[4]→3)(4←[3])([0]) 390 Layer: 391 ([0])(0←[1])(1←[3])(3←[2]→4)(2←[4]) 392 -------------------------------------------------------------------------------- 393 tree 21: 394 ([0]) 395 ├─([1]) 396 │ ├─(1←[2]→3) 397 │ │ ├─null 398 │ │ └─null 399 │ └─(2←[3]→4) 400 │ ├─null 401 │ └─null 402 └─(3←[4]) 403 ├─null 404 └─(4←[5]) 405 ├─null 406 └─null 407 408 Preorder: 409 ([0])([1])(1←[2]→3)(2←[3]→4)(3←[4])(4←[5]) 410 Inorder: 411 ([2]→1)([1])(1←[3]→0)([0])(0←[4])(4←[5]) 412 Postorder: 413 ([2]→3)(2←[3]→1)([1])(1←[5]→4)(5←[4])([0]) 414 Layer: 415 ([0])([1])(1←[4])(4←[2]→3)(2←[3]→5)(3←[5]) 416 -------------------------------------------------------------------------------- 417 tree 22: 418 ([0]) 419 ├─(0←[1]→2) 420 │ ├─null 421 │ └─null 422 └─([2]) 423 ├─(2←[3]→4) 424 │ ├─null 425 │ └─null 426 └─(3←[4]) 427 ├─null 428 └─null 429 430 Preorder: 431 ([0])(0←[1]→2)([2])(2←[3]→4)(3←[4]) 432 Inorder: 433 ([1]→0)([0])(0←[3]→2)([2])(2←[4]) 434 Postorder: 435 ([1]→3)(1←[3]→4)(3←[4]→2)([2])([0]) 436 Layer: 437 ([0])(0←[1]→2)([2])(2←[3]→4)(3←[4]) 438 -------------------------------------------------------------------------------- 439 tree 23: 440 ([0]) 441 ├─([1]→2) 442 │ ├─(1←[2]→3) 443 │ │ ├─null 444 │ │ └─null 445 │ └─null 446 └─([3]) 447 ├─(3←[4]→5) 448 │ ├─null 449 │ └─null 450 └─(4←[5]) 451 ├─null 452 └─null 453 454 Preorder: 455 ([0])([1]→2)(1←[2]→3)([3])(3←[4]→5)(4←[5]) 456 Inorder: 457 ([2]→1)([1]→0)([0])(0←[4]→3)([3])(3←[5]) 458 Postorder: 459 ([2]→1)([1]→4)(1←[4]→5)(4←[5]→3)([3])([0]) 460 Layer: 461 ([0])([1]→3)([3])(3←[2]→4)(2←[4]→5)(4←[5]) 462 -------------------------------------------------------------------------------- 463 tree 24: 464 ([0]) 465 ├─(0←[1]) 466 │ ├─null 467 │ └─(1←[2]→3) 468 │ ├─null 469 │ └─null 470 └─([3]) 471 ├─(3←[4]→5) 472 │ ├─null 473 │ └─null 474 └─(4←[5]) 475 ├─null 476 └─null 477 478 Preorder: 479 ([0])(0←[1])(1←[2]→3)([3])(3←[4]→5)(4←[5]) 480 Inorder: 481 ([1])(1←[2]→0)([0])(0←[4]→3)([3])(3←[5]) 482 Postorder: 483 ([2]→1)(2←[1])(1←[4]→5)(4←[5]→3)([3])([0]) 484 Layer: 485 ([0])(0←[1])([3])(3←[2]→4)(2←[4]→5)(4←[5]) 486 -------------------------------------------------------------------------------- 487 tree 25: 488 ([0]) 489 ├─([1]) 490 │ ├─(1←[2]→3) 491 │ │ ├─null 492 │ │ └─null 493 │ └─(2←[3]→4) 494 │ ├─null 495 │ └─null 496 └─([4]) 497 ├─(4←[5]→6) 498 │ ├─null 499 │ └─null 500 └─(5←[6]) 501 ├─null 502 └─null 503 504 Preorder: 505 ([0])([1])(1←[2]→3)(2←[3]→4)([4])(4←[5]→6)(5←[6]) 506 Inorder: 507 ([2]→1)([1])(1←[3]→0)([0])(0←[5]→4)([4])(4←[6]) 508 Postorder: 509 ([2]→3)(2←[3]→1)([1])(1←[5]→6)(5←[6]→4)([4])([0]) 510 Layer: 511 ([0])([1])([4])(4←[2]→3)(2←[3]→5)(3←[5]→6)(5←[6]) 512 -------------------------------------------------------------------------------- 513 0 error(s) occured.
现在我可以放心大胆地说,我给出的二叉树和线索二叉树的遍历算法是真正正确的!
需要工程源码的同学麻烦点个赞并留言你的Email~
微信扫码,自愿捐赠。天涯同道,共谱新篇。
微信捐赠不显示捐赠者个人信息,如需要,请注明联系方式。 |