上码:
1 #include <iostream>
2 #include <string>
3 #include <stack>
4 #include <queue>
5 using namespace std;
6
7 template<class T>
8 struct BiNode {
9 T data;
10 BiNode<T> *lchild, *rchild;//左子树、右子树
11 };
12
13 template<class T>
14 class BiTree
15 {
16 public:
17 BiTree(); //构造函数,初始化二叉树,前序序列由键盘输入
18 ~BiTree(); //析构函数,释放二叉链表中的各结点的存储空间
19 BiNode<T>* Getroot(); //获得指向根节点的指针
20 void PreOrder(BiNode<T>* root); //前序遍历二叉树
21 void InOrder(BiNode<T>* root); //中序遍历二叉树
22 void PostOrder(BiNode<T>* root); //后序遍历二叉树
23 void LeverOrder(BiNode<T>* root); //层序遍历二叉树
24
25 void NonPreOrder(BiNode<T>* root);
26 void NonInOrder(BiNode<T>* root);
27 void NonPostOrder(BiNode<T>* root);
28 private:
29 BiNode<T> *root; //指向根节点的头指针
30 BiNode<T> *Create(); //有参构造函数调用
31 void ReLease(BiNode<T> *root); //析构函数调用
32 };
33 template<class T>
34 BiTree<T>::BiTree() {
35 this->root = Create(); //创建对象时,构造函数被调用后,调用Great函数进行初始化
36 }
37
38 template<class T>
39 BiTree<T>::~BiTree() {
40 ReLease(root); //调用ReLease释放二叉树链表
41 }
42
43 template<class T>
44 BiNode<T>* BiTree<T>::Getroot() {
45 return root; //返回根节点地址
46 }
47
48 template<class T>
49 void BiTree<T>::PreOrder(BiNode<T>* root) {
50 if (root == NULL)
51 return;
52 cout << root->data << " ";
53 PreOrder(root->lchild); //前序遍历二叉树(根,左,右)
54 PreOrder(root->rchild);
55 }
56
57 template<class T>
58 void BiTree<T>::InOrder(BiNode<T> *root) {
59 if (root == NULL)
60 return;
61 InOrder(root->lchild); //中序遍历二叉树(左,根,右)
62 cout << root->data << " ";
63 InOrder(root->rchild);
64 }
65
66 template<class T>
67 void BiTree<T>::PostOrder(BiNode<T>* root) {
68 if (root == NULL)
69 return;
70 PostOrder(root->lchild); //后序遍历二叉树(左,右,根)
71 PostOrder(root->rchild);
72 cout << root->data << " ";
73 }
74
75 template<class T>
76 void BiTree<T>::LeverOrder(BiNode<T>* root) {
77 BiNode<T> *p; //层序遍历
78 if (root == NULL)
79 return;
80 queue<BiNode<T>*> q;
81 q.push(root);
82 while (!q.empty()) {
83 p = q.front();
84 cout << p->data << " ";
85 q.pop();
86 if (p->lchild != NULL) {
87 q.push(p->lchild);
88 }
89 if (p->rchild != NULL) {
90 q.push(p->rchild);
91 }
92 }
93 }
94
95 template<class T>
96 BiNode<T>* BiTree<T>::Create() {
97 BiNode<T>* root; //构造二叉树
98 T ch;
99 cout << "请输入创建的一颗二叉树的结点数据:" << endl;
100 cin >> ch;
101 if (ch == "#")
102 root = NULL;
103 else {
104 root = new BiNode<T>;
105 root->data = ch;
106 root->lchild = Create();
107 root->rchild = Create();
108 }
109 return root;
110 }
111
112 template<class T>
113 void BiTree<T>::ReLease(BiNode<T>* root) {
114 if (root != NULL) { //删除二叉树
115 ReLease(root->lchild);
116 ReLease(root->rchild);
117 delete root;
118 }
119 }
120
121 template<class T>
122 void BiTree<T>::NonPreOrder(BiNode<T>* root) {
123 if (root == NULL)
124 return;
125 stack<BiNode<T>*> s;
126 BiNode<T> *p = root, *q;
127 while (p != NULL || !s.empty())
128 {
129 if (p != NULL) {
130 cout << p->data << ' ';
131 s.push(p);
132 p = p->lchild;
133 }
134 else {
135 q = s.top();
136 s.pop();
137 p = q->rchild;
138 }
139 }
140 }
141 template<class T>
142 void BiTree<T>::NonInOrder(BiNode<T>* root) {
143 if (root == NULL)
144 return;
145 stack<BiNode<T>*> s;
146 BiNode<T> *p = root, *q;
147 while (!s.empty() || p != NULL)
148 {
149 while (p != NULL) {
150 s.push(p);
151 p = p->lchild;
152 }
153 if (!s.empty()) {
154 q = s.top();
155 s.pop();
156 cout << q->data << ' ';
157 p = q->rchild;
158 }
159
160 }
161
162 }
163 template<class T>
164 void BiTree<T>::NonPostOrder(BiNode<T>* root) {
165 if (root == NULL)
166 return;
167 stack<BiNode<T>*> s;
168 stack<int> symbol; //visit 记录访问的次数0,1,与s栈一一对应
169 BiNode<T> *p = root, *q;
170 while (!s.empty() || p != NULL)
171 {
172 while (p != NULL) {
173 s.push(p);
174 symbol.push(0); //对应位置入栈 0,表示未经访问
175 p = p->lchild;
176 }
177 //栈不空,且栈顶元素未经访问
178 if (!s.empty() && !symbol.top()) {
179 symbol.pop();
180 symbol.push(1);
181
182 q = s.top();
183 p = q->rchild;
184 }
185 //栈不空,且栈顶元素已经被访问
186 else if (!s.empty() && symbol.top()) {
187 //经过循环体 右子树结束
188 while (symbol.top()) { //清空栈中已被访问过的元素,即symbol为 1者
189 q = s.top();
190 cout << q->data << ' ';
191 s.pop();
192
193 symbol.pop();
194 if (!symbol.size())
195 break;
196 }
197
198 if (!s.empty()) {
199 symbol.pop();
200 symbol.push(1);
201
202 q = s.top();
203 p = q->rchild;
204 }
205 else {
206 p = NULL;
207 }
208 }
209 else
210 continue;
211
212 }
213 }
214
215 int main()
216 {
217 BiTree<string> bt;//创建一棵树
218 BiNode<string>* root = bt.Getroot();
219 cout << "------前序遍历------" << endl;
220 bt.PreOrder(root);
221 cout << endl;
222 cout << "------后序遍历------" << endl;
223 bt.PostOrder(root);
224 cout << endl;
225 cout << "------中序遍历------" << endl;
226 bt.InOrder(root);
227 cout << endl;
228 cout << "------层序遍历------" << endl;
229 bt.LeverOrder(root);
230 cout << endl;
231 cout << "---非递归前序遍历---" << endl;
232 bt.NonPreOrder(root);
233 cout << endl;
234 cout << "---非递归后序遍历---" << endl;
235 bt.NonPostOrder(root);
236 cout << endl;
237 cout << "---非递归中序遍历---" << endl;
238 bt.NonInOrder(root);
239 cout << endl;
240 return 0;
241 }
后序遍历有点蹩脚,需要注意几点细节,避免死循环陷阱。