tree.h
#include <iostream>
#include <stack>
#ifndef _TREE
#define _TREE
using namespace std;
struct bioTree {
char val; // 节点的值
bioTree *left, * right; // 节点的左子树,右子树
// 三种构造函数(应对用户的不同输入)
bioTree() : val('#'), left(nullptr), right(nullptr) {}
bioTree(char x) : val(x), left(nullptr), right(nullptr) {}
bioTree(char x, bioTree* left, bioTree* right) : val(x), left(left), right(right) {}
};
class Tree{
private:
public:
void CreateTree(bioTree **T) {
char ch;
cin >> ch;
if (ch == '#') { // 如果输入是#,说明当前节点为空
*T = NULL;
//return; // 并且要跳回上一层
}
else {
*T = (bioTree *)malloc(sizeof(bioTree));
(*T)->val = ch;
CreateTree(&((*T)->left));
CreateTree(&((*T)->right));
}
}
// 递归:前序遍历
void PreOrderTrav(bioTree* T){
if (T == NULL) { // 判断T是否为空树
return;
}
cout << T->val << " "; // 输出中间节点的值
PreOrderTrav(T->left); // 遍历左子树
PreOrderTrav(T->right); // 遍历右子树
}
// 递归:中序遍历
void InOrderTrav(bioTree* T) {
if (T == NULL) { // 判断T是否为空树
return;
}
InOrderTrav(T->left); // 遍历左子树
cout << T->val << " "; // 输出中间节点的值
InOrderTrav(T->right); // 遍历右子树
}
// 递归:后序遍历
void PostOrderTrav(bioTree* T) {
if (T == NULL) { // 判断T是否为空树
return;
}
PostOrderTrav(T->left); // 遍历左子树
PostOrderTrav(T->right); // 遍历右子树
cout << T->val << " "; // 输出中间节点的值
}
// 迭代:前序遍历
void IterPreOrderTrav(bioTree* T) {
stack<bioTree*> s; // 创建一个栈来存放树节点
if (T == NULL) return; // 如果是空树,就直接返回
s.push(T); // 先把根节点放进栈
while (!s.empty()) { // 栈空即遍历完
bioTree* node = s.top(); // 获取栈顶元素并让他出栈(中间节点)
s.pop();
cout << node->val << " "; // 输出中间节点
if (node->right) s.push(node->right); // 如果它有右孩子,先让右孩子入栈(前序遍历左孩子先出)
if (node->left) s.push(node->left); // 如果它有左孩子,再让左孩子入栈
}
}
// 迭代:中序遍历
void IterInOrderTrav(bioTree* T) {
stack<bioTree*> s;
bioTree* cur = T; // 用指针来访问节点
while (cur != NULL || !s.empty()) {
if (cur != NULL) {
s.push(cur); // 将访问的节点放进栈
cur = cur->left; // 左
}
else {
cur = s.top(); // 弹出栈顶元素
s.pop();
cout << cur->val << " "; // 中
cur = cur->right; // 右
}
}
}
// 迭代:后序遍历
// 统一写法,将访问节点放入栈中,把要处理的节点也放入栈中,紧接着一个空指针作为标记
void IterPostOrderTrav(bioTree* T){
stack<bioTree*> s; // 创建一个栈来存放树节点
if (T != NULL) s.push(T); // 如果不是空树,就把根节点放进栈
while (!s.empty()) {
bioTree* node = s.top(); // 取s的堆顶节点
if (node != NULL) { // 如果栈顶不是空节点,说明不是要处理节点
s.pop(); // 让该节点弹出,避免重复操作,
s.push(node); // 添加中节点
s.push(NULL); // 中节点访问过,但是还没有处理,加入空节点做为标记。
if (node->right) s.push(node->right); // 添加右节点
if (node->left) s.push(node->left); // 添加左节点
}
else { // 遇到空节点时,才将下一个节点放进结果集
s.pop();
node = s.top();
s.pop();
cout << node->val << " ";
}
}
}
};
#endif // !TREE
tree.cpp
#include "tree.h"
int main()
{
Tree tree; // 创建一个树
bioTree *T; // T是树的根节点
tree.CreateTree(&T);
cout << "PreOrderTrav: ";
tree.PreOrderTrav(T);
cout << endl;
cout << "InOrderTrav: ";
tree.InOrderTrav(T);
cout << endl;
cout << "PostOrderTrav: ";
tree.PostOrderTrav(T);
cout << endl;
cout << "IterPreorderTrav: ";
tree.IterPreOrderTrav(T);
cout << endl;
cout << "IterInOrderTrav: ";
tree.IterInOrderTrav(T);
cout << endl;
cout << "IterPostOrderTrav: ";
tree.IterPostOrderTrav(T);
cout << endl;
return 0;
}
输入:ABD###C#F##
输出: