二叉树的三种遍历
首先,二叉树的三种遍历使用递归来解决非常简单。下面只给出代码。
第二,如果不能使用递归来做,就要自己用queue或者stack这样的数据结构来实现递归的过程。
下面的代码是用stack来实现的。先序遍历用stack实现很简单,写了一种方法。中序遍历和后序遍历就要有点思考的过程了。
中序遍历我写了三种,后序遍历写了两种方法。
struct treenode {
treenode *left, *right;
int val;
treenode(int x,treenode *l=nullptr,treenode *r=nullptr) { val = x;left = l;right = r; }
};
//二叉树遍历用递归和非递归
void preorderRecu(treenode *head,vector<int> &res) {
if (head == nullptr)
return;
res.push_back(head->val);
preorderRecu(head->left, res);
preorderRecu(head->right, res);
}
void inorderRecu(treenode *head, vector<int> &res) {
if (head == nullptr)
return;
inorderRecu(head->left, res);
res.push_back(head->val);
inorderRecu(head->right, res);
}
void postorderRecu(treenode *head, vector<int> &res) {
if (head == nullptr)
return;
postorderRecu(head->left, res);
postorderRecu(head->right, res);
res.push_back(head->val);
}
void preorderStack(treenode *head, vector<int> &res) {
if (head == nullptr) return;
stack<treenode *> sta;
sta.push(head);
while (!sta.empty()) {
treenode *out = sta.top();
sta.pop();
res.push_back(out->val);
if (out->right) sta.push(out->right);
if (out->left) sta.push(out->left);
}
return;
}
void inorderStack(treenode *head, vector<int> &res) {
if (head == nullptr) return;
stack<treenode *> sta;
sta.push(head);
while (!sta.empty()) {
treenode *top = sta.top();
while (top->left) {
sta.push(top->left);
top = top->left;
}
while (!sta.empty()) {
top = sta.top();
sta.pop();
res.push_back(top->val);
if (top->right) {
sta.push(top->right);
break;
}
}
}
}
void inorderStack_2(treenode *head, vector<int> &res) {
if (!head) return;
stack<treenode *> sta;
while (!sta.empty() || head) {
if (head) {
sta.push(head);
head = head->left;
}
else {
head = sta.top();
sta.pop();
res.push_back(head->val);
head = head->right;
}
}
}
void inorderStack_3(treenode *head, vector<int> &res) {
if (!head) return;
stack<treenode *> s;
s.push(head);
//treenode *pre = nullptr;
while (!s.empty()) {
treenode *top = s.top();
s.pop();
if (!top->left && !top->right) {
res.push_back(top->val);
//pre = top;
}
else if (top->left && !top->right) {
if (s.top() == nullptr) {
s.pop();
res.push_back(top->val);
}
else {
s.push(nullptr);//用一个空指针来标志右孩子节点
s.push(top);
s.push(top->left);
}
}
else if (!top->left && top->right) {
if (s.top() == top->right) {
res.push_back(top->val);
}
else {
s.push(top->right);
s.push(top);
}
}
else {
if (!s.empty()&&s.top() == top->right) {
res.push_back(top->val);
}
else {
s.push(top->right);
s.push(top);
s.push(top->left);
}
}
}
}
void postorderStack(treenode *head, vector<int> &res) {
//第一种方法 用两个栈 s2起收集作用 s1的压入弹出表示了遍历过程
if (head == nullptr)
return;
stack<treenode *> s1, s2;
s1.push(head);
while (s1.empty() != true) {
treenode *top = s1.top();
s1.pop();
s2.push(top);
if (top->left) s1.push(top->left);
if (top->right) s1.push(top->right);
}
while (!s2.empty()) {
treenode *top = s2.top();
s2.pop();
res.push_back(top->val);
}
}
void postorderStack_2(treenode *head, vector<int> &res) {
if (!head) return;
stack<treenode *> s;
s.push(head);
treenode *pre = nullptr;
while (!s.empty()) {
treenode *top = s.top();
if (!top->left && !top->right) {
s.pop();
res.push_back(top->val);
pre = top;
}
else {
if (pre != nullptr && ((pre == top->left) || (pre == top->right))) {
s.pop();
res.push_back(top->val);
pre = top;
}
else {
if (top->right) s.push(top->right);
if (top->left) s.push(top->left);
}
}
}
}