# 二叉树各种遍历算法

• 先序遍历：先根、后左、再右
• 中序遍历：先左、后根、再右
• 后序遍历：先左、后右、再根

## 递归版先序、中序、后序遍历

#include <iostream>
using namespace std;

// 二叉树节点
struct Node
{
int value;
struct Node* left;
struct Node* right;
Node(int data) : value(data), left(nullptr), right(nullptr) {};
};

// 先序遍历
{
return;
cout << head->value << " ";
}

// 中序遍历
{
return;
cout << head->value << " ";
}

// 后序遍历
{
return;
cout << head->value << " ";
}

int main()
{
Node* n1 = new Node(1);
Node* n2 = new Node(2);
Node* n3 = new Node(3);
Node* n4 = new Node(4);
Node* n5 = new Node(5);
n1->left = n2;
n1->right = n3;
n2->left = n4;
n2->right = n5;
PreOrder(n1);
cout << endl;
InOrder(n1);
cout << endl;
PosOrder(n1);
cout << endl;
delete n1;
delete n2;
delete n3;
delete n4;
delete n5;
system("pause");
return 0;
}


## 非递归版本

### 先序遍历

void PreOrderUnRecur(Node* head)
{
{
stack<Node*> stack;
Node* cur;
while (!stack.empty())
{
cur = stack.top();
stack.pop();
cout << cur->value << " ";
// 右孩子先进栈，后出
if (cur->right)
stack.push(cur->right);
if (cur->left)
stack.push(cur->left);
}
}
}


### 中序遍历

void InOrderUnRecur(Node* head)
{
{
stack<Node*> stack;
while (!stack.empty() || cur != nullptr)
{
while (cur != nullptr)
{
stack.push(cur);
cur = cur->left;
}

cur = stack.top();
stack.pop();
cout << cur->value << " ";
cur = cur->right;
}
}
}


### 后序遍历

void PosOrderUnRecur(Node* head)
{
{
stack<Node*> s1, s2;
Node* cur;
while (!s1.empty())
{
cur = s1.top();
s1.pop();
s2.push(cur);
if (cur->left)
s1.push(cur->left);
if (cur->right)
s1.push(cur->right);
}
while (!s2.empty())
{
cout << s2.top()->value << " ";
s2.pop();
}
}
}


1. 该节点的左右孩子皆为空，即该节点为叶子节点，那么这次遍历就是打印该点。
2. 如果上一次打印的节点为该节点的右孩子，说明该节点的子树处理完毕，这次遍历就是打印该点。
3. 如果上一次打印的节点为该节点的左孩子，且该节点的右孩子为空，说明该节点的子树处理完毕，这次遍历就是打印该点。
4. 否则说明子树没有被访问过，按照右孩子、左孩子的顺序入栈。
void PosOrderUnRecur(Node* head)
{
{
stack<Node*> stack;
Node* last = nullptr;
Node* top;
while (!stack.empty())
{
top = stack.top();
if ((top->left == nullptr && top->right == nullptr) || // 叶子节点
(top->right == nullptr && last == top->left) || // 上个访问为左孩子，且右孩子为空
last == top->right) // 上个访问为右孩子
{
cout << top->value << " ";
last = top;
stack.pop();
}
else
{
if (top->right)
stack.push(top->right);
if (top->left)
stack.push(top->left);
}
}
}
}


## 层次遍历

void LevelOrder(Node* head)
{
{
queue<Node*> queue;
Node* cur;
while (!queue.empty())
{
cur = queue.front();
queue.pop();
cout << cur->value << " ";
if (cur->left)
queue.push(cur->left);
if (cur->right)
queue.push(cur->right);
}
}
}


03-20 1万+

05-25 4万+

04-14 6002

06-08 1万+

08-20 5011

03-18 5498

11-04 2万+

01-24 3021

06-16 2万+

07-06 10万+

#### 二叉树前序、中序、后序遍历非递归写法的透彻解析

©️2020 CSDN 皮肤主题: 技术黑板 设计师: CSDN官方博客

1.余额是钱包充值的虚拟货币，按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载，可以购买VIP、C币套餐、付费专栏及课程。