0
点赞
收藏
分享

微信扫一扫

栈和队列遍历二叉树


栈深度优先遍历

栈和队列遍历二叉树_出队

算法思想:

1、得到根结点后,若左孩子结点不空,不断地将当前结点的左孩子则入栈,第一步完成后,栈顶结点是叶结点
2、栈不空时,将栈顶元素弹出并保存到返回的答案数组,并查看当前结点是否有右孩子,有则入栈,然后重复步骤1。没有则接着执行步骤2,直到栈空。

class Solution {
public:
vector<int> res;
stack<TreeNode*> s;
vector<int> inorderTraversal(TreeNode* root){
if(root == nullptr) return res;
TreeNode* cur = root;
s.push(cur);
//首先将所有的左孩子压栈
while(cur->left != nullptr){
s.push(cur->left);
cur = cur->left;
}
//退出循环后cur指向叶结点,准备回溯
while(!s.empty()){
cur = s.top();
res.push_back(cur->val);
s.pop();
if(cur->right != nullptr){
s.push(cur->right);
cur = cur->right;
while(cur->left != nullptr){
s.push(cur->left);
cur = cur->left;
}
}
}
return res;
}
};

栈和队列遍历二叉树_递归_02

递归解法

class Solution {
public:
vector<int> res;
vector<int> inorderTraversal(TreeNode* root){
if(root == nullptr) return res;
if(root->left != nullptr){
inorderTraversal(root->left);
}
res.push_back(root->val);
if(root->right != nullptr){
inorderTraversal(root->right);
}
return res;
}
};

队列广度优先遍历

栈和队列遍历二叉树_递归_03

算法思想:
  1. 根结点入队后,然后将所有不为空的子结点入队
  2. 每次循环进行操作时,都要同时处理一层的子结点,即将此时队列中所有结点的子结点全部入队,同时将当前处理完成的父结点出队

vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> res;
if(root == nullptr){
return res;
}
queue<TreeNode*> q;
q.push(root);
while(!q.empty()){
vector<int> temp;
int count = q.size();
for(int i=1; i<=count; i++){
TreeNode* cur = q.front();
if(cur->left != nullptr){
q.push(cur->left);
}
if(cur->right != nullptr){
q.push(cur->right);
}
temp.push_back(cur->val);
q.pop();
}
res.push_back(temp);
}
return res;
}

栈和队列遍历二叉树_结点_04

“之”字型打印结点

栈和队列遍历二叉树_结点_05

双端队列 + 层序遍历
  1. 遍历奇数层时:从队首出队,其子结点 先左后右从队尾入队
  2. 遍历偶数层时:从队尾出队,其子结点 先右后左从队头入队

vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> res;
if(root == nullptr){
return res;
}
deque<TreeNode*> dq;
dq.push_back(root);
bool isOdd = true;
while(!dq.empty()){
vector<int> layer;
int len = dq.size();
// 奇数层
if(isOdd){
while(len-- > 0){
TreeNode* node = dq.front();
layer.push_back(node->val);
dq.pop_front();
if(node->left != nullptr){
dq.push_back(node->left);
}
if(node->right != nullptr){
dq.push_back(node->right);
}
}
}else{
while(len-- > 0){
TreeNode* node = dq.back();
layer.push_back(node->val);
dq.pop_back();
if(node->right != nullptr){
dq.push_front(node->right);
}
if(node->left != nullptr){
dq.push_front(node->left);
}
}
}
res.push_back(layer);
isOdd = !isOdd;
}
return res;
}

N叉树的前序遍历

栈和队列遍历二叉树_递归_06


结点结构

class Node {
public:
int val;
vector<Node*> children;

Node() {}

Node(int _val) {
val = _val;
}

Node(int _val, vector<Node*> _children) {
val = _val;
children = _children;
}
};

递归版1

class Solution {
public:
vector<int> res;

void traverse(Node* root){
if(root == nullptr){
return ;
}
res.push_back(root->val);
for(Node* node : root->children){
preorder(node);
}
}

vector<int> preorder(Node* root) {
tranverse(root);
return res;
}
};

递归版2

class Solution {
public:
vector<int> res;

vector<int> preorder(Node* root) {
if(root == nullptr){
return vector<int>();
}
res.push_back(root->val);
for(Node* node : root->children){
preorder(node);
}
return res;
}
};

迭代版

class Solution {
public:
vector<int> res;

vector<int> preorder(Node* root) {
if(root == nullptr){
return res;
}
stack<Node*> s;
s.push(root);
while(!s.empty()){
Node* cur = s.top();
s.pop();
res.push_back(cur->val);
for(int i = cur->children.size() - 1; i >= 0; i--){
s.push(cur->children[i]);
}
}
return res;
}
};


举报

相关推荐

0 条评论