一、递归遍历二叉树
1.前序遍历二叉树
/*递归前序遍历*/
void preRecursive(const T* t){
if(t == nullptr) return;
cout << t->val << " ";
preRecursive(t->left);
preRecursive(t->right);
}
2.中序遍历二叉树
/*递归中序遍历*/
void InorderRecursive(T* t){
if(t == nullptr) return;
InorderRecursive(t->left);
cout << t->val << " ";
InorderRecursive(t->right);
}
3.后序遍历二叉树
/*递归后序遍历*/
void PostRecursive(T* t){
if(t == nullptr) return;
PostRecursive(t->left);
PostRecursive(t->right);
cout << t->val << " ";
}
二、非递归遍历二叉树
1. 非递归前序遍历
/*非递归前序遍历*/
void preorderTraserval(T* t){
if(t==nullptr) return;
stack<T*> q; //需要借助一个进行递归遍历栈
while(!q.empty()){
q.pop();
}
T* p = t;
while(p!=nullptr || !q.empty()){ //这里的判定条件很关键
if(p!=nullptr){
cout << p->val << " "; //因为是前序,所以直接读
q.push(p);
p = p->left;
}else{
p = q.top();
q.pop();
p = p->right;
}
}
cout << endl;
}
2. 非递归中序遍历
/*非递归中序遍历*/
void inorderTraserval(T* t){
stack<T*>q;
while(!q.empty()){
q.pop();
}
T* p = t;
while(p!=nullptr || !q.empty()){
if(p!=nullptr){
q.push(p);
p = p->left;//先沿着左子树把节点入栈
}else{
p = q.top();//当前节点的左子树为空,则把遍历指针p指向栈顶节点
cout << p->val << " ";//因为是中序遍历,所以此时读取节点的val
q.pop();//将遍历过的节点弹出栈
p = p->right;//继续遍历右子树
}
}
cout << endl;
}
3. 非递归后序遍历
非递归后序遍历是这些遍历算法当中最复杂的一个
void postorderTraserval(T* t){
stack<T*>q;//需要借助一个栈进行构建
while(!q.empty())q.pop();
T* p = t;
T* pre;//需要记录上一个访问的节点,后面会有用
while(p!=nullptr || !q.empty()){
if(p!=nullptr){
q.push(p);
p = p->left; //和中序遍历相同,先把左节点都入栈
}else{
T* temp = q.top();//此时左节点为空,按照后序遍历的顺序,应该遍历右节点
if(temp->right!=nullptr && temp->right!=pre){
p = temp->right;//如果右节点不为空且右节点之前未访问过,则向右遍历
}else{
/*
这里有两种情况:
1. 当前栈顶节点的右节点为空,则该节点就是叶子节点,已经遍历到底,所以直接访问该元素;
2. 当前栈顶节点的右节点是pre,也就是刚刚访问过的那个节点,也就是说当前节点的右子树已经访问过了,那么按照后序遍历顺序,该节点的左右子树都已访问过,那么接下来应该访问该节点;
*/
cout << temp->val <<" ";
q.pop();
pre = temp;
p = nullptr;
}
}
}
}
4. 层次遍历二叉树
/*层次遍历*/
void layerTraserval(T* t){
if(t == nullptr) return;
queue<T*> q; //层次遍历需要利用一个队列
while(!q.empty())q.pop();
q.push(t);
T* temp;
while(!q.empty()){
temp = q.front();
q.pop();
cout << temp->val << " ";
if(temp->left!=nullptr){
q.push(temp->left);
}
if(temp->right!=nullptr){
q.push(temp->right);
}
}
cout <<endl;
return;
}
三、完整代码
#include <iostream>
#include <queue>
#include <stack>
#include <string>
using namespace std;
typedef struct TreeNode{
int val;
TreeNode* left;
TreeNode* right;
TreeNode():val(0),left(nullptr),right(nullptr){};
TreeNode(int x):val(x),left(nullptr),right(nullptr){};
}T;
void InorderCreateTree(T*& t){ //前序构建二叉树
string x;
cin >> x;
if(x[0] == '#'){
t = nullptr;
}else{
t = new T;
t->val = stoi(x);
InorderCreateTree(t->left);
InorderCreateTree(t->right);
}
return;
}
void layerCreateTree(T* &t){ //层次顺序构建二叉树
string x;
cin >> x;
queue<T*> q;
while(!q.empty())q.pop();
if(x[0] == '#'){
t = NULL;
return;
}else{
t = new T;
t->val = stoi(x);
q.push(t);
}
T* temp;
while(!q.empty()){
temp = q.front();
if(temp == nullptr) continue;
q.pop();
cin >> x;
if(x[0] == '#'){
temp->left = nullptr;
}else{
temp->left = new T;
temp->left->val = stoi(x);
q.push(temp->left);
}
cin >> x;
if(x[0] == '#'){
temp->right = nullptr;
}else{
temp->right = new T;
temp->right->val = stoi(x);
q.push(temp->right);
}
}
return;
}
/*递归前序遍历*/
void preRecursive(const T* t){
if(t == nullptr) return;
cout << t->val << " ";
preRecursive(t->left);
preRecursive(t->right);
}
/*递归中序遍历*/
void InorderRecursive(T* t){
if(t == nullptr) return;
InorderRecursive(t->left);
cout << t->val << " ";
InorderRecursive(t->right);
}
/*递归后序遍历*/
void PostRecursive(T* t){
if(t == nullptr) return;
PostRecursive(t->left);
PostRecursive(t->right);
cout << t->val << " ";
}
/*非递归前序遍历*/
void preorderTraserval(T* t){
if(t==nullptr) return;
stack<T*> q;
T* p = t;
while(p!=nullptr || !q.empty()){
if(p!=nullptr){
cout << p->val << " ";
q.push(p);
p = p->left;
}else{
p = q.top();
q.pop();
p = p->right;
}
}
cout << endl;
}
/*非递归中序遍历*/
void inorderTraserval(T* t){
stack<T*>q;
while(!q.empty()){
q.pop();
}
T* p = t;
while(p!=nullptr || !q.empty()){
if(p!=nullptr){
q.push(p);
p = p->left;
}else{
p = q.top();
cout << p->val << " ";
q.pop();
p = p->right;
}
}
cout << endl;
}
/*非递归后序遍历*/
void postorderTraserval(T* t){
stack<T*>q;
while(!q.empty())q.pop();
T* p = t;
T* pre;
while(p!=nullptr || !q.empty()){
if(p!=nullptr){
q.push(p);
p = p->left;
}else{
T* temp = q.top();
if(temp->right!=nullptr && temp->right!=pre){
p = temp->right;
}else{
cout << temp->val <<" ";
q.pop();
pre = temp;
p = nullptr;
}
}
}
}
/*层次遍历*/
void layerTraserval(T* t){
if(t == nullptr) return;
queue<T*> q;
while(!q.empty())q.pop();
q.push(t);
T* temp;
while(!q.empty()){
temp = q.front();
q.pop();
cout << temp->val << " ";
if(temp->left!=nullptr){
q.push(temp->left);
}
if(temp->right!=nullptr){
q.push(temp->right);
}
}
cout <<endl;
return;
}
int main(){
T* root;
cout << "层次构建二叉树" << endl;
//InorderCreateTree(root);
layerCreateTree(root);
cout << "树已经创建完毕!" << endl;
cout<< "递归先序遍历" << endl;
preRecursive(root);
cout << endl;
cout<< "递归中序遍历" << endl;
InorderRecursive(root);
cout << endl;
cout<< "递归后序遍历" << endl;
PostRecursive(root);
cout << endl;
cout<< "非递归先序遍历" << endl;
preorderTraserval(root);
cout<< "非递归中序遍历" << endl;
inorderTraserval(root);
cout<< "非递归后序遍历" << endl;
postorderTraserval(root);
cout<<endl;
cout << "层次遍历二叉树" <<endl;
layerTraserval(root);
return 0;
}