二叉树的定义
1. 二叉树种类:
1.1 空的二叉树
1.2 只有根结点的二叉树
1.3 只有左子树或者右子树的二叉树
1.4 左右子树都存在的时候:
(1)满二叉树
(2)完全二叉树:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1~ 2 ( h − 1 ) 2^(h-1) 2(h−1) 个节点。
2. 遍历方式
2.1前序遍历(根在前面)
2.2中序遍历(根在中间)
2.3后序遍历(根在后面)
3.C++代码
struct TreeNode //链式储存二叉树
{
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {
}
};
二叉树之递归遍历
1.前序遍历
题目 难度:简单
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
void Traversal(TreeNode *cur,vector<int> &vec)
{
if(cur==nullptr)
{
return;//相当于中断,意思是只要cur=null,就退出Traversal函数
}
vec.push_back(cur->val);//中
Traversal(cur->left,vec);
Traversal(cur->right,vec);
}
vector<int> preorderTraversal(TreeNode* root)
{
vector<int> vec;
Traversal(root,vec);
return vec;
}
};
2.中序遍历
题目 难度:简单
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
void Traversal(TreeNode *cur,vector<int> &vec)
{
if(cur==nullptr)
{
return;//相当于中断
}
Traversal(cur->left,vec);
vec.push_back(cur->val);//中
Traversal(cur->right,vec);
}
vector<int> preorderTraversal(TreeNode* root)
{
vector<int> vec;
Traversal(root,vec);
return vec;
}
};
3.后序遍历
题目 难度:简单
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
void Traversal(TreeNode *cur,vector<int> &vec)
{
if(cur==nullptr)
{
return;//相当于中断
}
Traversal(cur->left,vec);
Traversal(cur->right,vec);
vec.push_back(cur->val);
}
vector<int> postorderTraversal(TreeNode* root)
{
vector<int> vec;
Traversal(root,vec);
return vec;
}
};
二叉树之统一迭代遍历
1.前序遍历
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
* */
class Solution {
public:
vector<int> result;
stack<TreeNode*> sta;
vector<int> inorderTraversal(TreeNode* root)
{
if (root != nullptr) sta.push(root);
while(!sta.empty())
{
TreeNode *cur=sta.top();
if(cur!=nullptr)
{
sta.pop();//先把根结点弹出,防止重复
if(cur->right!=nullptr)
{
sta.push(cur->right);//右
}
if(cur->left!=nullptr)
{
sta.push(cur->left);//左
}
sta.push(cur);//中
sta.push(nullptr);
}
else
{
sta.pop();
result.push_back(sta.top()->val);
sta.pop();
}
}
return result;
}
};
2.中序遍历
大致可以分为如下四部曲。
-
root压入栈顶。
-
将栈顶节点取出,记为cur
-
判断:栈顶第一个非空节点 是否被视作根节点处理过?(cur是否为null?)
-
如否:进行处理
将当前节点cur作为根节点。
为使出栈时符合左-根-右的顺序,以右-根-左的顺序将节点入栈,具体如下:
(1)将当前节点cur视作根节点,先出栈,以便后续操作
(2)如有右节点则入栈,无则不入
(3)当前节点cur入栈
(4)将空指针nullptr入栈,标志cur已被处理过。同时,如无左节点,结束处理流程。
(5)如有左节点,则左节点进入栈顶,结束处理流程。
注:(2)、(5)确保栈顶始终是cur节点的左节点(若无左节点则为nullptr)。
将重复此步处理,直到cur的左节点为空。此时,cur为下一个应加入result的节点。 -
如是:则该节点无左子树,或是左子树已被访问完毕。无论如何,现在,该节点应被加入result。
(1)将当前节点cur加入result。
(2)弹出栈顶的cur,以表示此节点已被加入result,无需再次被考虑。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
* */
class Solution {
public:
vector<int> result;
stack<TreeNode*> sta;
vector<int> inorderTraversal(TreeNode* root)
{
if (root != nullptr) sta.push(root);
while(!sta.empty())
{
TreeNode *cur=sta.top();
if(cur!=nullptr)
{
sta.pop();//先把根结点弹出,防止重复
if(cur->right!=nullptr)
{
sta.push(cur->right);//右
}
sta.push(cur);//中
sta.push(nullptr);
if(cur->left!=nullptr)
{
sta.push(cur->left);//左
}
}
else
{
sta.pop();
result.push_back(sta.top()->val);
sta.pop();
}
}
return result;
}
};
3.后序遍历
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
vector<int> result;
stack<TreeNode*> sta;
vector<int> postorderTraversal(TreeNode* root)
{
if (root != nullptr) sta.push(root);
while(!sta.empty())
{
TreeNode *cur=sta.top();
if(cur!=nullptr)
{
sta.pop();
sta.push(cur);
sta.push(nullptr);
if(cur->right!=nullptr)
{
sta.push(cur->right);
}
if(cur->left!=nullptr)
{
sta.push(cur->left);
}
}
else
{
sta.pop();
result.push_back(sta.top()->val);
sta.pop();
}
}
return result;
}
};
二叉树之层序遍历
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root)
{
queue<TreeNode*> que;
vector<vector<int>> result;
if(root!=NULL)
{
que.push(root);
}
while(!que.empty())
{
vector<int> vec;
//vec要放在这里定义,如果放在while外面定义,这样他的生存期就在这个函数里面。
//等到下次调用这个while函数就可以得到一个空的vec;
int size=que.size();//本层节点的个数
while(size--)
{
TreeNode *node=que.front();
vec.push_back(node->val);
que.pop();
if(node->left) que.push(node->left);
if(node->right) que.push(node->right);
}
result.push_back(vec);
}
return result;
}
}