參考https://www.jianshu.com/p/456af5480cee
一、代碼
#include<iostream>
#include<stack>
#include<vector>
#include<algorithm>
using namespace std;
//可參考 https://www.jianshu.com/p/456af5480cee
//二叉樹遍歷(先序、中序、後序) 遞歸和非遞歸
struct TreeNode
{
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x) : val(x),left(NULL),right(NULL){}
};
//先序遍歷 遞歸
void preVisit1(TreeNode* root){
if(!root){
return;
}
cout << root->val << " ";
preVisit1(root->left);
preVisit1(root->right);
}
//先序遍歷 非遞歸
void preVisit2(TreeNode* root){
stack<TreeNode*> s;
vector<int> vec;
TreeNode* node = root;
while(node || !s.empty()){
while(node){
s.push(node);
vec.push_back(node->val);
node = node->left;
}//退出條件爲node空(左子節點遍歷到頭了),然後彈棧往右邊找一個節點
if(!s.empty()){
node = s.top();
s.pop();
node = node->right;
}
}
for(int i=0;i<vec.size();i++){
cout << vec[i] << " ";
}
}
//中序遍歷 遞歸
void midVisit1(TreeNode* root){
if(!root){
return;
}
midVisit1(root->left);
cout << root->val << " ";
midVisit1(root->right);
}
//中序遍歷 非遞歸
void midVisit2(TreeNode* root){
//和先序遍歷非遞歸非常相似
TreeNode* node = root;
stack<TreeNode*> s;
vector<int> vec;
while(node || !s.empty()){
while(node){
s.push(node);
node = node->left;
}
if(!s.empty()){
node = s.top();
s.pop();
vec.push_back(node->val);
node = node->right;
}
}
for(int i=0;i<vec.size();i++){
cout << vec[i] << " ";
}
}
//後序遍歷 遞歸
void postVisit1(TreeNode* root){
if(!root){
return;
}
postVisit1(root->left);
postVisit1(root->right);
cout << root->val << " ";
}
//後序遍歷 非遞歸1
//後序:左右根 ->逆序後變爲:根右左 ->和先序遍歷(根左右)非常相似
void postVisit2(TreeNode* root){
TreeNode* node = root;
stack<TreeNode*> s;
vector<int> vec;
while(node || !s.empty()){
while(node){
s.push(node);
vec.push_back(node->val);
node = node->right;
}
if(!s.empty()){
node = s.top();
s.pop();
node = node->left;
}
}
//將vec逆序輸出
reverse(vec.begin(), vec.end());
for(int i=0;i<vec.size();i++){
cout << vec[i] << " ";
}
}
//後序遍歷 非遞歸2
void postVisit3(TreeNode* root){
TreeNode* node = root;
TreeNode* last_visit = NULL;
stack<TreeNode*> s;
vector<int> vec;
while(node || !s.empty()){
while(node){
s.push(node);
node = node->left;
}
node = s.top();
if(!node->right || node->right==last_visit){//如果右節點爲空,或則右子樹已經訪問完
vec.push_back(node->val);
s.pop(); //訪問節點後才pop
last_visit = node;
node = NULL;
}else{
node = node->right;
}
}
for(int i=0;i<vec.size();i++){
cout << vec[i] << " ";
}
}
int main(){
//構建一個二叉樹
TreeNode* a = new TreeNode(1);
TreeNode* b = new TreeNode(2);
TreeNode* c = new TreeNode(3);
TreeNode* d = new TreeNode(4);
TreeNode* e = new TreeNode(5);
TreeNode* f = new TreeNode(6);
TreeNode* g = new TreeNode(7);
TreeNode* h = new TreeNode(8);
a->left = b;
a->right = c;
b->left = d;
d->right = f;
f->left = g;
f->right = h;
c->right = e;
cout << "preVisit1: ";
preVisit1(a);
cout << "\npreVisit2: ";
preVisit2(a);
cout << "\n\nmidVisit1: ";
midVisit1(a);
cout << "\nmidVisit2: ";
midVisit2(a);
cout << "\n\npostVisit1: ";
postVisit1(a);
cout << "\npostVisit2: ";
postVisit2(a);
cout << "\npostVisit3: ";
postVisit3(a);
}