先序中序求解二叉树(使用二叉查找树原理)
二叉树的先序中序序列确定,二叉树也就确认了,但还原二叉树确实有点麻烦,要不断的遍历中序序列。后来学习了二叉查找树,发现了一个很巧的办法。
二叉查找树的特性是每个节点都有权值,其规律为左子节点小于父节点,右子节点大于父节点,其中序序列是有序的。如果我们把二叉树变成二叉查找树,就是要给每个子节点赋值,最简单的根据中序序列从0->赋值,现在我们来看看二叉查找树先序序列和二叉查找树的关系。以下树的中序序列为DBEGACF,附上权值为(D:0,B:1,E:2,G:3,A:4,C:5,F:6 )
关于这个2插树先序为ABDEGCF,先序序列是先本身节点->左节点->有节点。细心发现二叉查找树的先序序列可以作为节点进入树的先后顺序(节点进入树的先后顺序可以有多个,不一定是先序序列),根据中序的赋值先序可以为4102356(与ABDEGCF相对应)也就是用这个序列来创建二叉查找树。接下来就不用我多说了。附上C#实现代码(PS:写算法不要用C#,坑)
1 namespace Test 2 { 3 class Program 4 { 5 static void Main(string[] args) 6 { 7 string first = "ABDEGCF"; //先序 8 string mid = "DBEGACF"; //中序 9 DouBleTree doubletree = new DouBleTree(first,mid); 10 Console.WriteLine(doubletree.FirstOrder()); //先序 11 Console.WriteLine(doubletree.MidOrder()); //中序 12 Console.WriteLine(doubletree.AfterOrder()); //后序 13 Console.ReadLine(); 14 } 15 } 16 public class DouBleTree 17 { 18 /// <summary> 19 /// 20 /// </summary> 21 /// <param name="first">先序</param> 22 /// <param name="mid">中序</param> 23 public DouBleTree(string first, string mid) 24 { 25 tlist = new List<T>(); 26 for (int i = 0; i < mid.Length; i++) // 附加权值 27 { 28 T t = new T 29 { 30 data = mid[i], 31 WeigthValue = i, 32 }; 33 tlist.Add(t); 34 } 35 doubleTreeRoot = new DoubleTreePoint //创建根节点 36 { 37 data = first[0], 38 WeightValue = tlist.FirstOrDefault(n => n.data == first[0]).WeigthValue, 39 }; 40 for (int i = 1; i < first.Length; i++) //创建二叉树 41 { 42 T t = tlist.FirstOrDefault(n => n.data == first[i]); 43 doubleTreeRoot = InsertPoint(doubleTreeRoot, t); 44 } 45 } 46 private DoubleTreePoint doubleTreeRoot; //二叉树根节点 47 private List<T> tlist; //给中序队列附权值 48 private DoubleTreePoint InsertPoint(DoubleTreePoint point ,T t) //插入节点 49 { 50 if (point == null) 51 { 52 point = new DoubleTreePoint 53 { 54 data = t.data, 55 WeightValue = t.WeigthValue, 56 }; 57 return point; 58 } 59 if (point.WeightValue > t.WeigthValue) 60 { 61 point.left = InsertPoint(point.left, t); 62 } 63 else 64 { 65 point.right = InsertPoint(point.right, t); 66 } 67 return point; 68 69 } 70 public string FirstOrder() //返回先序队列 71 { 72 string str = ""; 73 First(doubleTreeRoot,ref str); 74 return str; 75 } 76 private void First(DoubleTreePoint doubleTreePoint,ref string str) 77 { 78 if (doubleTreePoint == null) return; 79 str += doubleTreePoint.data; 80 First(doubleTreePoint.left,ref str); 81 First(doubleTreePoint.right,ref str); 82 } 83 public string MidOrder() 84 { 85 string str = ""; 86 Mid(doubleTreeRoot, ref str); 87 return str; 88 } 89 private void Mid(DoubleTreePoint doubleTreePoint,ref string str) 90 { 91 if (doubleTreePoint == null) return; 92 Mid(doubleTreePoint.left,ref str); 93 str += doubleTreePoint.data; 94 Mid(doubleTreePoint.right,ref str); 95 } 96 public string AfterOrder() 97 { 98 string str = ""; 99 After(doubleTreeRoot,ref str); 100 return str; 101 } 102 private void After(DoubleTreePoint doubleTreePoint,ref string str) 103 { 104 if (doubleTreePoint == null) return; 105 After(doubleTreePoint.left,ref str); 106 After(doubleTreePoint.right,ref str); 107 str += doubleTreePoint.data; 108 } 109 } 110 public class DoubleTreePoint 111 { 112 public char data { get; set; } //数据 113 public DoubleTreePoint left { get; set; } 114 public DoubleTreePoint right { get; set; } 115 public int WeightValue { get; set; } //权值 116 } 117 public class T 118 { 119 public char data { get; set; } 120 public int WeigthValue { get; set; } 121 } 122 }