重拾算法(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

深度为3的树结构

深度为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     }

生成类DOS的树结构视图的代码

总结

我已经根据出错的用例完善了算法,现已成功通过所有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.

max depth = 3的输出结果

现在我可以放心大胆地说,我给出的二叉树和线索二叉树的遍历算法是真正正确的!

需要工程源码的同学麻烦点个赞并留言你的Email~

重拾算法(3)——用458329个测试用例全面测试二叉树和线索二叉树的遍历算法相关推荐

  1. 【练习】2021下半年数据结构刷题笔记和总结 (二) 树、查找-- 不同的排序算法、二叉排序树 平衡二叉树、哈希表查找、线索二叉树、

    记录自己下半年写题目的记录.题目来自书或者网站. 练习(一)的地址: https://blog.csdn.net/qq_41358574/article/details/117098620?ops_r ...

  2. 二叉树非递归后序遍历算法(C语言)

    二叉树非递归后序遍历算法(C语言) 二叉树后序遍历的规律:左右根 后序非递归遍历中,访问根(子根)结点有两种情况 ①:遍历完左子树,需要遍历右子树,需要从栈中访问最顶上的根(子根)结点从而得到右子树的 ...

  3. 二叉树非递归后序遍历算法

    与正常的非递归中序遍历算法不同于两点: 一  比正常的中序遍历算法多了对数据元素的标记. 在压数据元素入栈(标记记为0,用来表示访问了其左子树)时标记, 还有访问完左子树利用gettop()获取双亲通 ...

  4. 【Java数据结构与算法】第十一章 顺序存储二叉树、线索二叉树和堆

    第十一章 顺序存储二叉树.线索化二叉树.大顶堆.小顶堆和堆排序 文章目录 第十一章 顺序存储二叉树.线索化二叉树.大顶堆.小顶堆和堆排序 一.顺序存储二叉树 1.介绍 2.代码实现 二.线索二叉树 1 ...

  5. 二叉树非递归后序遍历算法的一种简单思路

    首先从简单的例子开始 1 2 3 上图二叉树的后序遍历序列是"231", 颠倒一下就是"132", 而其前序遍历是"123" 有什么发现? ...

  6. 二叉树 中序非递归遍历算法 c++

    二叉树的中序非递归算法,详见下 首先,二叉树结点定义 typedef struct BiTNode//二叉树结点结构 {string data;struct BiTNode *lchild,*rchi ...

  7. C++ 二叉树实现及四种遍历算法(Basic Realization of the BinaryTree Template class)

    Basic Realization of the BinaryTree 环境: Codeblocks 实现二叉树展示: 头文件 main.cpp //Written by Xuebi //本程序先构建 ...

  8. 数据结构与算法(八)-二叉树(斜二叉树、满二叉树、完全二叉树、线索二叉树)...

    前言:前面了解了树的概念和基本的存储结构类型及树的分类,而在树中应用最广泛的种类是二叉树 一.简介 在树型结构中,如果每个父节点只有两个子节点,那么这样的树被称为二叉树(Binary tree).其中 ...

  9. 数据结构 第七章 实验题2 实现二叉树的各种遍历算法

    实验题目:     实现二叉树各种遍历算法 实验目的:      领会二叉树的各种遍历过程以及遍历算法设计 实验内容:       设计程序,实现二叉树的先序遍历.中序遍历和后序遍历的       递 ...

最新文章

  1. python画笑脸图案-如何让这些代码中的一个在窗口中绘制不同大小的笑脸?
  2. finereport 登录界面的代码文件_【干货下载】多彩包含网页登录界面等4款WEB模板素材作品集源文件...
  3. @Html.Action()
  4. SAP C4C business object的UUID和可读性更好的ID
  5. 网络时延——发送时延和传播时延
  6. jee过滤器应用场景_将涡轮增压器添加到JEE Apps
  7. 阿里巴巴 连接池 druid 的使用、maven依赖
  8. RTEMS 网络资料的部分翻译
  9. poj 3211 Washing Clothes (01)
  10. Oracle 9.2.0.4的一个简单安装脚本(含安装前补丁p3006854)
  11. 史上最全的福昕高级pdf编辑器安装教程
  12. 在这个520特别的日子里,分享几个用的上的Python代码
  13. 【电路补习笔记】7、磁珠的工作原理、磁珠的分类、磁珠的模型、磁珠的参数、磁珠与电感的区别、磁珠的应用、磁珠的误区
  14. Html中style标签是做什么的
  15. 云存储平台——Seafile搭建
  16. 【Python与数据分析实验报告】Pandas数据分析基础应用
  17. Docker部署Jenkins服务
  18. wireshark的usb抓包分析 2 - 分析数据
  19. 互联网红利之道-流量变现
  20. 优衣库46万客户信息遭泄露,这些年,你的信息还被谁泄露过?

热门文章

  1. Exchange2007 中Send as 与Send on behalf of 讲解
  2. Python基础23_os,sys,序列化,pickle,json
  3. React多页面应用脚手架-v1.3.0
  4. 重新捡起flask(二)
  5. 无所不在的物联网设备 你我都需要正视所带来的安全问题
  6. python 自动化对比返回结果
  7. 批量 kill mysql 中运行时间长的sql
  8. 【百度地图API】百度API卫星图使用方法和卫星图对比工具
  9. 【观点】“另类”设计模式
  10. TOP Server教程:预览非标准协议创建的未来