二叉树:学习三种遍历(前、中、后)及层次遍历,并完成leetcode上的验证二叉搜索树(98)及二叉树 层次遍历(102,107)
一。二叉树特点
二叉树是树的一种特殊结构,它具有三个特点:
1.每个结点最多有两个子树,结点的度可以为0,1,2
2.左子树和右子树是由顺序的,次序不能颠倒
3.即使某结点只有一个子树,也要区分左右子树
二。二叉树性质
1.一般二叉树性质
(1)在非空二叉树的i层上,至多有2i-1个节点(i>=1)。通过归纳法论证。
(2)在深度为K的二叉树上最多有2k-1个结点(k>=1)。通过归纳法论证。
(3)对于任何一棵非空的二叉树,如果叶节点个数为n0,度数为2的节点个数为n2,则有: n0 = n2 + 1
在一棵二叉树中,除了叶子结点(度为0)之外,就剩下度为2(n2)和1(n1)的结点了。则树的结点总数为T = n0+n1+n2;在二叉树中结点总数为T,而连线数为T-1.所以有:n0+n1+n2-1 = 2*n2 +n1;最后得到n0 = n2+1;
2.完全二叉树性质
(1)具有n的结点的完全二叉树的深度为log2n+1.
满二叉树是完全二叉树,对于深度为k的满二叉树中结点数量是2k-1 = n,完全二叉树结点数量肯定最多2k-1,同时完全二叉树倒数第二层肯定是满的(倒数第一层有结点,那么倒是第二层序号和满二叉树相同),所以完全二叉树的结点数最少大于少一层的满二叉树,为2k-1-1。
根据上面推断得出: 2k-1-1< n=<2k-1,因为结点数Nn为整数那么n<=2k-1可以推出n<=2k ,n>2k-1-1可以推出 n>=2k-1,所以2k-1<n<=2k 。即可得k-1<=log2n<k 而k作为整数因此k=[log2n]+1。
(2)如果有一颗有n个节点的完全二叉树的节点按层次序编号,对任一层的节点i(1<=i<=n)有
1.如果i=1,则节点是二叉树的根,无双亲,如果i>1,则其双亲节点为[i/2],向下取整
2.如果2i>n那么节点i没有左孩子,否则其左孩子为2i
3.如果2i+1>n那么节点没有右孩子,否则右孩子为2i+1
三。二叉树遍历
1.前序遍历
思想:先访问根结点,再遍历左子树,最后遍历右子树
2.中序遍历
思想:先访问左子树,再遍历根结点,最后遍历右子树
3.后序遍历
思想:先访问左子树,再遍历右子树,最后遍历根结点
4.层次遍历
思想:从上到下从左到右一层一层的遍历
四。LeetCode刷题(98,102,107)
98. Validate Binary Search Tree
Given a binary tree, determine if it is a valid binary search tree (BST).
Assume a BST is defined as follows:
- The left subtree of a node contains only nodes with keys less than the node's key.
- The right subtree of a node contains only nodes with keys greater than the node's key.
- Both the left and right subtrees must also be binary search trees.
Example1:
Example2:
思想:题目要做的是判断二叉树是否是二叉搜索树,即左子树比根节点小,右子树比根节点大,那如果是二叉搜索树,把这棵树按照中序遍历后,会得到一个递增的序列,所以利用中序遍历可以解决这题。
class Solution {
public:
void midorder(TreeNode*root,vector<int>&arr)
{
if(root)
{
midorder(root->left,arr);
arr.push_back(root->val);
midorder(root->right,arr);
}
}
bool isValidBST(TreeNode* root) {
vector<int> arr;
midorder(root,arr);
for(int i=1;i<arr.size();i++)
{
if(arr[i]<=arr[i-1])
return false;
}
return true;
}
};
102. Binary Tree Level Order Traversal
Given a binary tree, return the level order traversal of its nodes' values. (ie, from left to right, level by level).
For example:
Given binary tree [3,9,20,null,null,15,7]
,
return its level order traversal as:
完整代码:
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
int count;
TreeNode* temp;
vector<int> a;
vector<vector<int>> b;
queue<TreeNode*> q;
if(!root) return b;
q.push(root);
while(q.size()){ //第一个循环给count赋值
count=q.size();
a.clear();
while(count--){ //第二个循环开始往二位数组输入
temp=q.front();
if(temp->left) q.push(temp->left);
if(temp->right) q.push(temp->right);
q.pop();
a.push_back(temp->val);
}
b.push_back(a);
}
return b;
}
};
107.Binary Tree Level Order Traversal II
Given a binary tree, return the bottom-up level order traversal of its nodes' values. (ie, from left to right, level by level from leaf to root).
For example:
Given binary tree [3,9,20,null,null,15,7]
,
return its bottom-up level order traversal as:
完整代码:比102题多了一个逆序。
class Solution {
public:
vector<vector<int>> levelOrderBottom(TreeNode* root) {
vector<vector<int>> res;
if(!root) return res;
queue<TreeNode*> que;
que.push(root);
while(que.size()!=0){
vector<int> tmpRes;
queue<TreeNode*> tmpQue;
while(que.size()!=0){
TreeNode *node = que.front();
que.pop();
if(node->left) tmpQue.push(node->left);
if(node->right) tmpQue.push(node->right);
tmpRes.push_back(node->val);
}
res.push_back(tmpRes);
que = tmpQue;
}
reverse(res.begin(),res.end());
return res;
}
};
五。参考资料:
2.二叉树的层次遍历