标签:
二叉树在数据结构中乃是重中之重,其应用非常广泛,很多数据结构都是建立在二叉树的基础上,如红黑色,平衡树等。
二叉树的定义如下:
一个有穷的结点集合。
这个集合可以为空。
若不为空,则它是由根结点和称为其左子树TL和右子树TR的两个不相交的二叉树组成。
可以看出,二叉树的定义是递归的。所以其递归遍历代码很容易理解。
// 二叉树节点 struct BinTreeNode { int data; BinTreeNode *leftChild; BinTreeNode *rightChild; };
前序遍历的访问顺序:根节点→左子树→右子树。
// 前序遍历 void preoder(BinTreeNode* bt) { if (NULL != bt) { cout << bt->data << " "; preoder(bt->leftChild); preoder(bt->rightChild); } }
中序遍历的访问顺序:左子树→根节点→右子树。
// 中序遍历 void inorder(BinTreeNode* bt) { if (NULL != bt) { inorder(bt->leftChild); cout << bt->data << " "; inorder(bt->rightChild); } }
后序遍历的访问顺序:左子树→右子树→根节点。
// 后序遍历 void postorder(BinTreeNode* bt) { if (NULL != bt) { postorder(bt->leftChild); postorder(bt->rightChild); cout << bt->data << " "; } }
其实前序遍历、中序遍历和后序遍历的访问路径都是一样的,只是访问的时机不一样。
前序遍历的访问顺序:根节点→左子树→右子树。所以,对于每个节点,程序将在第1次遇到时就访问。
1 // 前序遍历 2 void preoder(BinTreeNode* bt) 3 { 4 BinTreeNode *T = bt; 5 stack<BinTreeNode*> st; 6 7 while (T || !st.empty()) 8 { 9 while (T) // 遍历左子树 10 { 11 cout << T->data << " "; 12 13 st.push(T); 14 T = T->leftChild; 15 } 16 if (!st.empty()) // 进入右儿子 17 { 18 T = st.top(); 19 st.pop(); 20 21 T = T->rightChild; 22 } 23 } 24 25 }
中序遍历的访问顺序:左子树→根节点→右子树。所以,对于每个节点,程序将在第2次遇到时才访问。
1 // 中序遍历 2 void inorder(BinTreeNode* bt) 3 { 4 BinTreeNode *T = bt; 5 stack<BinTreeNode*> st; 6 7 while (T || !st.empty()) 8 { 9 while (T) 10 { 11 st.push(T); 12 T = T->leftChild; 13 } 14 if (!st.empty()) 15 { 16 T = st.top(); 17 st.pop(); 18 cout << T->data << " "; 19 20 T = T->rightChild; 21 } 22 } 23 }
后序遍历的访问顺序:左子树→右子树→根节点。所以,对于每个节点,程序将在第3次遇到时才访问。这里,针对每个节点,将使用一个标示来记录节点的被遇到的次数。
1 // 后序遍历 2 void postorder(BinTreeNode* bt) 3 { 4 BinTreeNode *T = bt; 5 stack<BinTreeNode*> st; 6 map<BinTreeNode*, int> visit; // 用来记录每个节点被遇见的次数 7 8 while (T || !st.empty()) 9 { 10 while (T) 11 { 12 if (visit.find(T) == visit.end()) // 第1次遇到 13 { 14 visit[T] = 1; 15 st.push(T); 16 } 17 T = T->leftChild; 18 } 19 20 if (!st.empty()) 21 { 22 T = st.top(); // 又遇见 23 visit[T]++; 24 25 if (3 == visit[T]) // 如果第3次遇到,此时访问该节点 26 { 27 st.pop(); 28 cout << T->data << " "; 29 } 30 T = T->rightChild; 31 } 32 } 33 }
1 #include "stdafx.h" 2 #include <iostream> 3 #include <stack> 4 #include <map> 5 6 using namespace std; 7 8 // 二叉树节点 9 struct BinTreeNode 10 { 11 int data; 12 BinTreeNode *leftChild; 13 BinTreeNode *rightChild; 14 }; 15 16 17 void insertData(BinTreeNode * &bt, int data) 18 { 19 if (NULL == bt) 20 { 21 bt = new BinTreeNode(); 22 23 bt->data = data; 24 bt->leftChild = NULL; 25 bt->rightChild = NULL; 26 27 return; 28 } 29 else 30 { 31 if (data < bt->data) 32 { 33 insertData(bt->leftChild, data); 34 } 35 else if (data > bt->data) 36 { 37 insertData(bt->rightChild, data); 38 } 39 40 } 41 } 42 43 44 // 遍历 45 // 前序遍历 46 void preoder(BinTreeNode* bt) 47 { 48 BinTreeNode *T = bt; 49 stack<BinTreeNode*> st; 50 51 while (T || !st.empty()) 52 { 53 while (T) 54 { 55 cout << T->data << " "; 56 57 st.push(T); 58 T = T->leftChild; 59 } 60 if (!st.empty()) 61 { 62 T = st.top(); 63 st.pop(); 64 65 T = T->rightChild; 66 } 67 } 68 69 } 70 71 // 中序遍历 72 void inorder(BinTreeNode* bt) 73 { 74 BinTreeNode *T = bt; 75 stack<BinTreeNode*> st; 76 77 while (T || !st.empty()) 78 { 79 while (T) 80 { 81 st.push(T); 82 T = T->leftChild; 83 } 84 if (!st.empty()) 85 { 86 T = st.top(); 87 st.pop(); 88 cout << T->data << " "; 89 90 T = T->rightChild; 91 } 92 } 93 } 94 95 // 后序遍历 96 void postorder(BinTreeNode* bt) 97 { 98 BinTreeNode *T = bt; 99 stack<BinTreeNode*> st; 100 map<BinTreeNode*, int> visit; // 用来记录每个节点被遇见的次数 101 102 while (T || !st.empty()) 103 { 104 while (T) 105 { 106 if (visit.find(T) == visit.end()) // 第1次遇到 107 { 108 visit[T] = 1; 109 st.push(T); 110 } 111 T = T->leftChild; 112 } 113 114 if (!st.empty()) 115 { 116 T = st.top(); // 又遇见 117 visit[T]++; 118 119 if (3 == visit[T]) // 如果第3次遇到,此时访问该节点 120 { 121 st.pop(); 122 cout << T->data << " "; 123 } 124 T = T->rightChild; 125 } 126 } 127 } 128 129 130 int main() 131 { 132 int arr[6] = { 1, 2, 3, 5, 6, 4 }; 133 134 // 建立根节点 135 BinTreeNode *bt = new BinTreeNode(); 136 bt->data = 3; 137 bt->leftChild = bt->rightChild = NULL; 138 139 140 // 插入元素 141 for (int i = 0; i < 6; i++) 142 { 143 insertData(bt, arr[i]); 144 } 145 146 // 前序遍历 147 preoder(bt); 148 cout << endl; 149 150 // 中序遍历 151 inorder(bt); 152 cout << endl; 153 154 // 后序遍历 155 postorder(bt); 156 cout << endl; 157 158 return 0; 159 }
标签:
原文地址:http://www.cnblogs.com/lzhxxyz/p/4857343.html