-
Notifications
You must be signed in to change notification settings - Fork 0
/
二叉树遍历.cpp
144 lines (141 loc) · 4.02 KB
/
二叉树遍历.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#include<stdio.h>
#include<iostream>
#include<bits/stdc++.h>
#include<algorithm>
using namespace std;
void printArr(vector<int> & nums){
for(auto e:nums){
cout<<e<<' ';
}
cout<<endl;
}
struct TreeNode{
int val;
TreeNode * lchild;
TreeNode *rchild;
TreeNode(int x):val(x),lchild(nullptr),rchild(nullptr){}
};
void printTree(TreeNode * node){
// DFS
if(node==nullptr)return ;
printTree(node->lchild);
cout<<node->val<<' ';
printTree(node->rchild);
}
void whilePrintTreeIn(TreeNode * node){
// InOrder
stack<TreeNode *> nodeStack;
// node不为空,或Stack不为空
while(node||!nodeStack.empty()){
if(node){
// 当node不为空时访问左节点
nodeStack.push(node);
node = node->lchild;
}else{
node = nodeStack.top();
nodeStack.pop();
cout<<node->val<<' ';
node = node->rchild;
}
}
}
void whilePrintTreePre(TreeNode * node){
// PreOrder
stack<TreeNode *> nodeStack;
// node不为空,或Stack不为空
while(node||!nodeStack.empty()){
if(node){
// 当node不为空时访问左节点
nodeStack.push(node);
cout<<node->val<<' ';
node = node->lchild;
}else{
node = nodeStack.top();
nodeStack.pop();
node = node->rchild;
}
}
}
void whilePrintTreePost(TreeNode * node){
// PostOrder
stack<TreeNode *> nodeStack;
TreeNode * pre = nullptr;
while(node || !nodeStack.empty()){
if(node){
// 循环访问左孩子并入栈
nodeStack.push(node);
node = node->lchild;
}else{
// 左孩子为空,访问栈顶回到不为空的上一个节点,此时不能出栈,还不到输出该节点值的时候
node = nodeStack.top();
// 此时已知该节点的左孩子为空,访问右孩子
node = node->rchild;
if(node && node != pre){
// 当前节点(右孩子)不为空,进栈
nodeStack.push(node);
// 继续访问当前节点左孩子
node = node->lchild;
}else{
// 若当前节点(右孩子)为空,则表明上一个节点(栈顶节点)为叶子节点,是需要输出值的节点,此时出栈访问叶子节点
node = nodeStack.top();
nodeStack.pop();
cout<<node->val<<' ';
// 叶子节点访问完成之后记录当前节点已经访问,下次避免访问该节点。
pre = node;
// 将node置为空指针,避免下次循环继续访问左孩子
node = nullptr;
}
}
}
}
TreeNode* buildTreeOnLevel(vector<int> & arr){
// 层次构建
if(arr.size()<1) return nullptr;
TreeNode * root = new TreeNode(arr[0]);
queue<TreeNode *> nodeQueue;
nodeQueue.push(root);
TreeNode * ptr = nullptr;
// 左孩子是否需要设置的标志
bool lNodeSet = true;
for(int i =1;i<arr.size();i++){
// 当指针为空的时候从队列中取出一个节点
if(ptr==nullptr){
ptr = nodeQueue.front();
nodeQueue.pop();
}
if(arr[i]==-1){
if(ptr->lchild==nullptr){
lNodeSet=false;
continue;
}
if(ptr->rchild==nullptr){
lNodeSet=true;
ptr=nullptr;
continue;
}
}
// 从左往右构建节点,并将节点放入队列中。
if(ptr->lchild==nullptr){
if(lNodeSet){
ptr->lchild = new TreeNode(arr[i]);
nodeQueue.push(ptr->lchild);
continue;
}
}
// 当构建右节点完成的时候,将节点放入队列中,并将当前ptr置为空,以便下次循环开始时指向新节点
if(ptr->rchild==nullptr){
ptr->rchild = new TreeNode(arr[i]);
nodeQueue.push(ptr->rchild);
lNodeSet=true;
ptr = nullptr;
continue;
}
}
return root;
}
int main(){
vector<int> nums1 = {1,2,3,-1,4,5,-1,6,7,8,9};
TreeNode * root = buildTreeOnLevel(nums1);
whilePrintTreePost(root);
return 0;
}