一. 二叉树的遍历
二叉树的遍历是指按某条搜索路径访问树中每个结点,使得每个结点均被访问一次,而且仅被访问一次
1.1 先序遍历
1、访问根节点
2、先序遍历左子树
3、先序遍历右子树
递归算法
#include <vector>
#include <cstdio>
void show(const std::vector<int> &vec){
printf("%c", '{');
for(int i = 0; i < vec.size(); ++i){
if(i != vec.size() - 1)
printf("%d, ", vec[i]);
else
printf("%d}\n", vec[i]);
}
}
void preOrder(const alice::TreeNode *root, std::vector<int> &order){
if(root == nullptr)
return;
order.emplace_back(root->data);
preOrder(root->lchild, order);
preOrder(root->rchild, order);
}
int main(void){
std::vector<int> data = {1, 2, 3, 4, 5};
std::vector<int> index = {0, 1, 1, 1, 1, 1};
alice::Tree tree(data, index);
std::vector<int> order;
preOrder(tree.getRoot(), order);
show(order);
return 0;
}
非递归算法
void preOrder(alice::TreeNode *root, std::vector<int> &order){
if(root == nullptr)
return;
std::stack<alice::TreeNode *> stack;
stack.push(root);
while(! stack.empty()){
alice::TreeNode *top_node = stack.top();
stack.pop();
order.emplace_back(top_node->data);
if(top_node->rchild)
stack.push(top_node->rchild);
if(top_node->lchild)
stack.push(top_node->lchild);
}
}
1.2 中序遍历
1、中序遍历左子树
2、访问根节点
3、中序遍历右子树
递归算法
void inOrder(alice::TreeNode *root, std::vector<int> &order){
if(root == nullptr)
return;
inOrder(root->lchild, order);
order.emplace_back(root->data);
inOrder(root->rchild, order);
}
非递归算法
void inOrder(alice::TreeNode *root, std::vector<int> &order){
if(root == nullptr)
return;
std::stack<alice::TreeNode *> stack;
alice::TreeNode *cur_node = root;
while(cur_node || ! stack.empty()){
if(cur_node){
stack.push(cur_node);
cur_node = cur_node->lchild;
}
else{
cur_node = stack.top();
stack.pop();
order.push_back(cur_node->data);
cur_node = cur_node->rchild;
}
}
}
1.3 后序遍历
1、后序遍历左子树
2、后序遍历右子树
3、访问根节点
递归算法
void postOrder(alice::TreeNode *root, std::vector<int> &order){
if(root == nullptr)
return;
postOrder(root->lchild, order);
postOrder(root->rchild, order);
order.emplace_back(root->data);
}
非递归算法,后序遍历是 “左右中”,因此我们只需将前序遍历转化为 “中右左”,再反转一下就可以了
void postOrder(alice::TreeNode *root, std::vector<int> &order){
if(root == nullptr)
return;
std::stack<alice::TreeNode *> stack;
stack.push(root);
while(! stack.empty()){
alice::TreeNode *top_node = stack.top();
stack.pop();
order.emplace_back(top_node->data);
if(top_node->lchild)
stack.push(top_node->lchild);
if(top_node->rchild)
stack.push(top_node->rchild);
}
std::reverse(order.begin(), order.end());
}
1.4 层次遍历
要进行层次遍历,需要借助一个队列。先将二叉树根节点入队,然后出队,访问出队结点,若它有左子树,则将左子树根节点入队;若它有右子树,则将右子树根节点入队。然后出队,访问出队结点 … 如何反复,直至队列为空
void levelOrder(alice::TreeNode *root, std::vector<int> &order){
if(root == nullptr)
return;
std::queue<alice::TreeNode *> queue;
queue.push(root);
while(! queue.empty()){
alice::TreeNode *front_node = queue.front();
queue.pop();
order.emplace_back(front_node->data);
if(front_node->lchild)
queue.push(front_node->lchild);
if(front_node->rchild)
queue.push(front_node->rchild);
}
}
二. 二叉树
2.1 反转二叉树
递归算法
void reverse(alice::TreeNode *root){
if(root == nullptr)
return;
std::swap(root->lchild, root->rchild);
reverse(root->lchild);
reverse(root->rchild);
}
非递归算法
void reverse(alice::TreeNode *root){
if(root == nullptr)
return;
std::stack<alice::TreeNode *> stack;
stack.push(root);
while(! stack.empty()){
alice::TreeNode *top_node = stack.top();
stack.pop();
std::swap(top_node->lchild, top_node->rchild);
if(top_node->rchild)
stack.push(top_node->rchild);
if(top_node->lchild)
stack.push(top_node->lchild);
}
}
2.2 对称二叉树
递归算法
bool isSymmetric(alice::TreeNode *root){
if(root == nullptr)
return true;
auto inner = [](const auto &inner, alice::TreeNode *lchild, alice::TreeNode *rchild) -> bool{
if(lchild == nullptr && rchild != nullptr)
return false;
else if(lchild != nullptr && rchild == nullptr)
return false;
else if(lchild == nullptr && rchild == nullptr)
return true;
else if(lchild->data != rchild->data)
return false;
else
return inner(inner, lchild->lchild, rchild->rchild) && inner(inner, lchild->rchild, rchild->lchild);
};
return inner(inner, root->lchild, root->rchild);
}
非递归算法
bool isSymmetric(alice::TreeNode *root){
if(root == nullptr)
return true;
std::queue<alice::TreeNode *> queue;
queue.push(root->lchild);
queue.push(root->rchild);
while(! queue.empty()){
alice::TreeNode *node_1 = queue.front();
queue.pop();
alice::TreeNode *node_2 = queue.front();
queue.pop();
if(! node_1 && ! node_2)
return true;
else if(! node_1 || ! node_2 || node_1->data != node_2->data)
return false;
else{
queue.push(node_1->lchild);
queue.push(node_2->rchild);
queue.push(node_1->rchild);
queue.push(node_2->lchild);
}
}
return true;
}
作业
实现对称二叉树的非递归算法