一、二叉树的概念
在计算机科学中,二叉树是每个节点最多有两个子树的树结构。通常子树被称作“左子树”(left subtree)和“右子树”(right subtree),二叉树常被用于实现二叉查找树和二叉堆.(摘自百度百科)
1、什么是满二叉树?
除了最后一层无任何子节点外,每一层上的所有节点都有两个子节点二叉树。
2、什么是完全二叉树?
一棵二叉树中,只有最下面两层结点的度可以小于2,并且最下层的叶结点集中在靠左的若干位置上,这样的二叉树称为完全二叉树。
3、什么是二叉查找树?
二叉查找树又被称为二叉搜索树。设x为二叉查找树中的一个结点,x结点包含关键字key,结点x的key值计为key[x]。如果y是x的左子树中的一个结点,则key[y]<=key[x];如果y是x的右子树的一个结点,则key[y]>=key[x]
在二叉查找树中:
(1)若任意结点的左子树不空,则左子树上所有结点的值均小于它的根结点的值。
(2)任意结点的右子树不空,则右子树上所有结点的值均大于它的根结点的值。
(3)任意结点的左、右子树也分别为二叉查找树。
(4)没有键值相等的结点。
二、二叉树的性质
性质1:二叉树第i层上的结点数目最多为2i-1(i>=1)
性质2:深度为k的二叉树至多有2k-1个结点(k>=1)
性质3:包含n个结点的二叉树的高度至少为(log2n)+1
性质4:在任意一棵二叉树中,若终端结点的个数为n0,度为2的结点数为n2,则n0=n2+1
三、二叉树的常用接口实现
- 结构体定义:
struct TreeNode
{
int val;
TreeNode *left;
TreeNode* right;
TreeNode(int x):val(x),left(NULL),right(NULL)
{}
};
- 以下是先序遍历递归与非递归接口
- 中序遍历的递归与非递归接口
- 后序遍历的递归与非递归接口
- 层次遍历二叉树
- 求二叉树的深度递归与非递归
- 判断一棵树是否为平衡二叉树
//先序遍历
//递归版本
void PreTraversal(vector<int> &v, TreeNode* root)
{
if (!root)
return;
v.push_back(root);
PreTraversal(v, root->left);
PreTraversal(v, root->right);
}
//非递归版本
void PreTraversal(vector<int> &v, TreeNode* root)
{
stack<TreeNode*> s;
s.push(root);
while (!s.empty())
{
TreeNode *cur = s.top();
s.pop();
if (temp)
{
v.push_back(cur->val);
s.push(root->right);
s.push(root->left);
}
}
}
//中序遍历 //左根右
void InorderTraversal(vector<int> &v, TreeNode* root)
{
if (!root) return;
InorderTraversal(v, root->left);
v.push(root->val);
InorderTraversal(v, root->right);
}
//非递归遍历
void InorderTraversal(vector<int> &v, TreeNode* root)
{
TreeNode* cur = root;
stack<TreeNode*> s;
while (root||!s.empty())
{
while (root)
{
s.push(root);
root = root->left;
}
TreeNode* cur = s.top();
s.pop();
v.push_back(cur->val);
root = cur->right;
}
}
//后序遍历
void PostorderTraversal(vector<int> &v, TreeNode* root)
{
if (!root) return;
PostorderTraversal(v, root->left);
PostorderTraversal(v, root->right);
v.push(root->val);
}
//非递归版本
void postOrderTraversal(vector<int> &store, TreeNode *root) {
stack<TreeNode *> S;
S.push(root);
while (!S.empty()) {
TreeNode *curr_node = S.top();
S.pop();
if (curr_node) {
store.push_back(curr_node->val);
S.push(curr_node->left); //右孩子优先,所以左孩子先入栈
S.push(curr_node->right);
}
}
std::reverse(store.begin(), store.end()); //逆序列即为所求
return;
}
//层次遍历
void LevelOrderTraversal(vector<int> &v, TreeNode *root)
{
queue<TreeNode*> q;
q.push(root);
while (!q.empty())
{
TreeNode* ret = q->front();
q.pop();
if (ret)
{
v.push_back(ret->val);
q.push(ret->_left);
q.push(ret->right);
}
}
}
//二叉树的深度
int TreeDeepTh(TreeNode* root)
{
//递归法
return root ? 1 + max(TreeDeepth(root->left), TreeDeepth(root->right)):0;
}
//迭代法 用到层次遍历,层次就是我们的深度
int TreeDeepTh(TreeNode* root)
{
if (!root)
{
return 0;
}
int depth = 0;
queue<TreeNode*> q;
q.push(root);
while (!q.empty())
{
int length = q.size();
++depth;
while (length--)
{
TreeNode* ret = q->front();
q.pop();
if (ret)
{
v.push_back(ret->val);
q.push(ret->_left);
q.push(ret->right);
length++;
}
}
}
return length;
}
//判断一棵树是否为平衡二叉树:平衡二叉树是指:它是一颗空树
//或者左右子树的高度差不超过1,并且左右子树都是一颗平衡二叉树
bool Isbalanced(TreeNode * root,int &Deepth)
{
if (!root)
{
Deepth = 0;
return true;
}
int left_depth, right_depth;
if (Isbalanced(root->left, left_depth) && Isbalanced(root->right, right_depth))
{
int diff = left_depth - right_depth;
if (diff <= 1 && diff >= -1)
{
Deepth = 1 + ((left_depth > right_depth) ? left_depth : right_depth);
return true;
}
}
return false;
}
bool IsBlancedTree(TreeNode* root)
{
int Deepth = 0;
return Isbalanced(root, Deepth);
}