二叉樹中的先序,中序,後續遍曆很容易讓人迷糊,記錄一下概念。
遍曆是將二叉樹中的結點資訊由非線性排列變為某種意義上的線性排列。也就是說,遍曆操作使非線性結構線性化。
一棵二叉樹由根結點、左子樹和右子樹三部分組成,若規定 D、L、R 分別代表遍曆根結點、遍曆左子樹、遍曆右子樹,則二叉樹的遍曆方式有 6 種:DLR、DRL、LDR、LRD、RDL、RLD。由於先遍曆左子樹和先遍曆右子樹在演算法設計上沒有本質區別,所以,只討論三種方式:DLR(先序 遍曆)、LDR(中序遍曆)和 LRD(後序遍曆)。
我們對如下樹進行先序遍曆(DLR)、中序遍曆(LDR)和 後序遍曆(LRD),大家試著寫出各種遍曆後的字母排列後再看答案。
1、先序遍曆(DLR)
先序遍曆的基本思想是:首先訪問根結點,然後先序遍曆其左子樹,最後先序遍曆其右子樹。
DLR結果A B D H I E J C F G
2、DRL
DRL的基本思想是:首先訪問根結點,然後先序遍曆其右子樹,最後先序遍曆其左子樹。
DRL結果A C G F B E J D I H
3、中序遍曆(LDR) 中序遍曆的基本思想是:首先中序遍曆根結點的左子樹,然後訪問根結點,最後中序遍曆其右子樹。
LDR結果H D I B J E A F C G
4、RDL
RDL的基本思想是:首先中序遍曆根結點的右子樹,然後訪問根結點,最後中序遍曆其左子樹。
RDL結果G C F A E J B I D H
5、後序遍曆(LRD) 後序遍曆的基本思想是:首先後序遍曆根結點的左子樹,然後後序遍曆根結點的右子樹,最後訪問根結點
LRD結果H I D J E B F G C A
6、RLD
RLD的基本思想是:首先後序遍曆根結點的右子樹,然後後序遍曆根結點的左子樹,最後訪問根結點
RLD結果G F C J E I H D B A
實現二叉樹排序,尋找/// <summary> /// 1、選定要排列數組第一個作為跟節點 /// 2、從索引為1的元素開始迴圈到最後一個,和根節點比較如果 <=根節點 則走根節點的左子節點樹直到最後一個節點 ,如果<=最後一個節點 則添加到此節點的左側,否則添加到此節點的右側 /// 如果>根節點 則走根節點的右子節點樹直到最後一個節點 ,如果<=最後一個節點 則添加到此節點的左側,否則添加到此節點的右側 /// 3、將二叉樹按照中序遍曆列印出字元即為 升序排序 /// </summary> public class BinaryTreeSort { //成員變數 private NodeSort _head; //頭指標 private int[] aInt; //用於構造二叉樹 public NodeSort Head //頭指標 { get { return _head; } } //構造方法 public BinaryTreeSort(int[] arrint) { aInt = arrint; _head = new NodeSort(aInt[0]); //添加頭結點 for (int i = 1; i < aInt.Length; i++) { Insert(aInt[i]); } } public void Insert(int i) { NodeSort newNode = new NodeSort(i); NodeSort current = _head; NodeSort parent; while (true) { parent = current; if (i < current.Value) { current = current.Left; if (current == null) { parent.Left = newNode; break; } } else { current = current.Right; if (current == null) { parent.Right = newNode; break; } } } } public void PreOrder(NodeSort NodeSort) //先序遍曆 { if (NodeSort != null) { Console.Write(" {0}",NodeSort.ToString()); //列印字元 PreOrder(NodeSort.Left); //遞迴 PreOrder(NodeSort.Right); //遞迴 } } public void MidOrder(NodeSort NodeSort) //中序遍曆 { if (NodeSort != null) { MidOrder(NodeSort.Left); //遞迴 Console.Write(" {0}", NodeSort.ToString()); //列印字元 MidOrder(NodeSort.Right); //遞迴 } } public void AfterOrder(NodeSort NodeSort) //後繼遍曆 { if (NodeSort != null) { AfterOrder(NodeSort.Left); //遞迴 AfterOrder(NodeSort.Right); //遞迴 Console.Write(" {0}", NodeSort.ToString()); //列印字元 } } public bool Find(int value) { return SubFind(_head, value); } bool flg = false; private bool SubFind(NodeSort rootnode, int value) { if (rootnode != null) { if (value > rootnode.Value) { if (!flg) SubFind(rootnode.Right, value); } else if (value < rootnode.Value) { if (!flg) SubFind(rootnode.Left, value); } else { flg = true; } } return flg; } } public class NodeSort { //成員變數 private int _data; //資料 private NodeSort _left; //左孩子 private NodeSort _right; //右孩子 public int Data { get { return _data; } } public NodeSort Left //左孩子 { get { return _left; } set { _left = value; } } public NodeSort Right //右孩子 { get { return _right; } set { _right = value; } } //構造方法 public NodeSort(int data) { _data = data; } public override string ToString() { return _data.ToString(); } public int Value { get { return _data; } } }