二叉树的遍历
二叉树的DFS(栈和递归)
前序遍历
方法一:递归
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root) {
vector<int> res;
preorderTraversal(root, res);
return res;
}
private:
void preorderTraversal(TreeNode* node, vector<int> &res){
if(node){
res.push_back(node->val);
preorderTraversal(node->left, res);
preorderTraversal(node->right, res);
}
}
};
方法二:模拟系统栈
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
// My Non-Recursive
// Time Complexity: O(n), n is the node number in the tree
// Space Complexity: O(h), h is the height of the tree
class Solution {
private:
struct Command{
string s; // go, print
TreeNode* node;
Command(string s, TreeNode* node): s(s), node(node){}
};
public:
vector<int> preorderTraversal(TreeNode* root) {
vector<int> res;
if(root == NULL)
return res;
stack<Command> stack;
stack.push(Command("go", root));
while(!stack.empty()){
Command command = stack.top();
stack.pop();
if(command.s == "print")
res.push_back(command.node->val);
else{
assert(command.s == "go");
if(command.node->right)
stack.push(Command("go",command.node->right));
if(command.node->left)
stack.push(Command("go",command.node->left));
stack.push(Command("print", command.node));
}
}
return res;
}
};
方法三:迭代法(栈)
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root) {
vector<int> vec;
stack<TreeNode*> s;
if(root) s.push(root);
while(!s.empty()){
TreeNode* node=s.top();
s.pop();
vec.push_back(node->val);
if(node->right) s.push(node->right);
if(node->left) s.push(node->left);
}
return vec;
}
};
中序遍历
方法一:递归
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
vector<int> res;
inorderTraversal(root,res);
return res;
}
private:
void inorderTraversal(TreeNode* node, vector<int> &res){
if(node){
inorderTraversal(node->left,res) ;
res.push_back(node->val);
inorderTraversal(node->right,res);
}
}
};
方法二:迭代法(栈)
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
vector<int> res;
if(root==NULL)
return res;
stack<TreeNode*> stack;
TreeNode* cur=root;
while(cur!=NULL||!stack.empty()){
while(cur!=NULL){
stack.push(cur);
cur=cur->left;
}
cur=stack.top();
stack.pop();
res.push_back(cur->val);
cur=cur->right;
}
return res;
}
};
后序遍历
方法一:递归
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root) {
vector<int> res;
postorderTraversal(root,res);
return res;
}
private:
void postorderTraversal(TreeNode* node,vector<int> &res){
if(node){
postorderTraversal(node->left,res);
postorderTraversal(node->right,res);
res.push_back(node->val);
}
}
};
#(难)方法二:迭代法(栈)
思路:这道题的难点在于仅利用栈去判断该节点是否为父结点,创新性思路是每次在栈中压入父节点后压入nullptr,之后再依次压入右子节点和左子节点。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root) {
vector<int> vec;
stack<TreeNode*> s;
TreeNode* cur=root;
if(root) s.push(root);
while(!s.empty()){
TreeNode* node=s.top();
if(node==NULL){
s.pop();
vec.push_back(s.top()->val);
s.pop();
continue;
}
s.push(NULL);
if(node->right) s.push(node->right);
if(node->left) s.push(node->left);
}
return vec;
}
};
二叉搜索树的第k小的结点
方法一:中序遍历——递归
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};
*/
class Solution {
public:
int m;
TreeNode* ans;
TreeNode* KthNode(TreeNode* pRoot, int k)
{ ans=NULL;
if (pRoot==NULL)return ans;
//vector<TreeNode*> vec;
m=k;
midOrder(pRoot);
return ans;
}
void midOrder(TreeNode* node){
if(node==NULL||m==0) return;
midOrder(node->left);
//vec.push_back(node);
if(m==1) ans=node;
m--;
if(m > 0) midOrder(node->right);
}
};
方法二:中序遍历——栈
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};
*/
class Solution {
public:
TreeNode* KthNode(TreeNode* pRoot, int k)
{
stack<TreeNode*> s;
TreeNode* cur=pRoot;
int c=k;
while(cur||(!s.empty())){
while(cur){
s.push(cur);
cur=cur->left;
}
cur=s.top();
s.pop();
if (c==1) return cur;
c--;
cur=cur->right;
}
return NULL;
}
};
中序遍历的下一个节点
给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。
/*
struct TreeLinkNode {
int val;
struct TreeLinkNode *left;
struct TreeLinkNode *right;
struct TreeLinkNode *next;
TreeLinkNode(int x) :val(x), left(NULL), right(NULL), next(NULL) {
}
};
*/
class Solution {
public:
TreeLinkNode* GetNext(TreeLinkNode* pNode)
{ TreeLinkNode* nextNode;
if(pNode&&pNode->right){
nextNode=pNode->right;
while(nextNode&&nextNode->left)
nextNode=nextNode->left;
return nextNode;
}
if(pNode&&pNode->next&&pNode->next->left==pNode){
return pNode->next;
}
if(pNode&&pNode->next&&pNode->next->right==pNode){
nextNode=pNode->next;
while(nextNode&&nextNode->next&&nextNode->next->right==nextNode)
nextNode=nextNode->next;
return nextNode->next;
}
return NULL;
}
};
二叉树的层序遍历BFS(队列)
二叉树的层序遍历(队列)
方法一:利用pair引入数的层序号
方法二:利用递归,分层插入vector<vector>
自底向上的层次打印二叉树
按照之字形打印二叉树
牛客:剑指offer
请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推。