前/中/后序遍历
递归版本
//前序遍历
void PreOrder(Node* root) {
if(root == nullptr) {
return;
}
//TODO 遍历当前节点
PreOrder(root->left);
PreOrder(root->right);
}
//中序遍历
void MiddleOrder(Node* root) {
if(root == nullptr) {
return;
}
MiddleOrder(root->left);
//TODO 遍历当前节点
MiddleOrder(root->right);
}
//后序遍历
void AfterOrder(Node* root) {
if(root == nullptr) {
return;
}
AfterOrder(root->left);
AfterOrder(root->right);
//TODO 遍历当前节点
}
非递归版本
前序
- 从根节点向左走,将经历过的节点遍历并压栈,直到走到最后一个节点
- 拿出栈顶的节点,将cur该为该节点的右孩子
- 重复此过程,直到cur为空且栈为空
void NRPreOrder(Node* root) {
std::stack<Node*> st;
Node* cur = root;
while(cur != nullptr || !st.empty()) {
while(cur != nullptr) {
//TODO 遍历cur节点
st.push(cur);
cur = cur->left;
}
if(!st.empty()) {
cur = st.top();
st.pop();
cur = cur->right;
}
}
}
中序
- 从根节点一直向左走,将经历过的节点压栈,直到最后一个节点
- 拿出栈顶节点,并进行遍历,将cur该为该节点的右孩子
- 重复此过程,直到cur为空且栈为空
void NRMiddleOrder(Node* root) {
std::stack<Node*> st;
Node* cur = root;
while(cur != nullptr || !st.empty()) {
while(cur != nullptr) {
st.push(cur);
cur = cur->left;
}
if(!st.empty()) {
cur = st.top();
//TODO 遍历cur节点
st.pop();
cur = cur->right;
}
}
}
后序
- 从根节点一直向右走
- 当cur不为空,则将cur压入st和output
- 如果cur为空,拿出st栈中的栈顶元素并将该元素出栈,将cur该为该节点的左孩子
- 重复此过程,当cur为空且st栈为空时,output栈的出栈顺序即为后序遍历顺序
void NRAfterOrder(Node* root) {
std::stack<Node*> st;
std::stack<Node*> output;
Node* cur = root;
while(cur != nullptr || !st.empty()) {
if(cur != nullptr) {
st.push(cur);
output.push(cur);
cur = cur->right;
}
else {
cur = st.top();
st.pop();
cur = cur->left;
}
}
while(!output.empty()) {
cur = output.top();
output.pop();
//TODO 遍历cur节点
}
}
层序
- 如果根节点为空,则返回
- 将根节点入队列,并进入循环
- 当队列中元素不为空时,取出队列头部的元素,并进行遍历
- 若该元素有左子树,将左子树入队列
- 若该元素有右子树,将右子树入队列
void LeverOrder(Node* root) {
if(root == nullptr) {
return;
}
std::queue<Node*> qe;
Node* cur = root;
qe.push(cur);
while(!qe.empty()) {
cur = qe.front();
qe.pop();
//TODO 遍历cur节点
if(cur->left) {
qe.push(cur->left);
}
if(cur->right) {
qe.push(cur->right);
}
}
}