**二叉树概念**:一棵二叉树是结点的一个有限集合,该集合可为空,或者是由一个根节点加上左子树和右子树的二叉树组成。
**二叉树的特点**:
1.每个结点最多有两棵子树,即二叉树不存在度大于2的结点(分支数最大不超过2)
2.二叉树的子树有左右之分,其子树的次序不能颠倒
**满二叉树**:在一棵二叉树中,如果所有分支结点都存在左子树和右子树,并且所有叶子节点都在同一层上。
**完全二叉树**:如果一棵具有N个结点的二叉树的结构与满二叉树的前N个结点的结构相同,称为完全二叉树。
**二叉树的性质**:
1、若规定根节点的层数为0,则一棵非空二叉树的第i层上最多有2^i(i>=0)个结点
2、若规定只有根节点的二叉树的深度为0,则深度为K的二叉树的最大结点数是2^(k+1) -1 (k>=-1)
3、对任何一棵二叉树, 如果其叶结点个数为 n0, 度为2的非叶结点个数为 n2,则有n0=n2+1
4、具有n个结点的完全二叉树的深度k为大于或等于(2为底)log2(n+1)-1的最小整数(向上取整)
5、对于具有n个结点的完全二叉树,如果按照从上至下从左至右的顺序对所有节点从0开始编号,则对于序号为i的结点有:a>:如果i>0,则序号为i结点的双亲结点的序号为(i-1)/2;如果i=0,则序号为i的结点为根节点,
b>:如果2i+1<n(在该树范围内),则序号为i的结点的左孩子结点的序号为2i+1;
c>:如果2i+2<n,则序号为i结点的右孩子结点的序号为2i+2;
Ex1:深度为6的 满二叉树有31个分支节点,有多少叶子节点?
n0=n2+1; 2^6-1=63(总节点个数) --->2n2+1=63--->n2=31--->63-31=32(叶子节点)--->性质3
Ex2:一棵有257个节点的完全二叉树,深度?
log2(257) 向上取整 =9 --->性质4
Ex3:一棵完全二叉树有71个节点,有多少叶子节点?
不难看出节点个数为奇数时,没有度为1的节点,故n0+n1+n2=71--->2n2+1=71--->n2=35--->n0=36;
--------------------------------------------------------
二叉树的创建:
//孩子表示法
template <class T>
struct BinaryTreeNode
{
BinaryTreeNode(const T& value)
:_value(value)
, _pLeft(NULL)
, _pRight(NULL)
{}
T _value;
BinaryTreeNode<T>* _pLeft;
BinaryTreeNode<T>* _pRight;
};
//二叉树的构建
template <class T>
struct BinaryTree
{
typedef BinaryTreeNode<T> Node;
BinaryTree()
:_pRoot(NULL)
{}
BinaryTree(const T array[], size_t size, const T& invalid)
{
size_t index = 0;
_CreateBinaryTree(_pRoot, array, size, index, invalid);
}
BinaryTree(const BinaryTree<T>& bt)
{
_pRoot = _CopyBinaryTree(bt._pRoot);
}
BinaryTree<T>& operator=(const BinaryTree<T>& bt)
{
if (this != &bt)
{
_DestoryBinaryTree(_pRoot);
_pRoot = _CopBinaryTree(bt._pRoot);
}
return *this;
}
~BinaryTree()
{
_DestoryBinaryTree(_pRoot);
}
void _CreateBinaryTree(Node* &pRoot, const T array[], size_t size, size_t & index, const T& invalid)
{
if (index < size && invalid != array[index])
{
pRoot = new Node(array[index]);//创建根节点
_CreateBinaryTree(pRoot->_pLeft, array, size, ++index, invalid);
_CreateBinaryTree(pRoot->_pRight, array, size, ++index, invalid);
}
}
Node* _CopyBinTree(Node* pRoot)
{
Node* pNewRoot = NULL;
if (pRoot)
{
pNewRoot = new Node(pRoot->_value); //拷贝根节点
pNewRoot->_pLeft = _CopyBinTree(pRoot->_pLeft);//拷贝左子树
pNewRoot->_pRight = _CopyBinTree(pRoot->_pRight);//拷贝右子树
}
return pNewRoot;
}
void _DestoryBinaryTree(Node*& pRoot)
{
if (pRoot)
{
_DestoryBinaryTree(pRoot->_pLeft);
_DestoryBinaryTree(pRoot->_pRight);
delete pRoot;
pRoot = NULL;
}
}
二叉树的基本操作:
//递归
//求二叉树结点个数
//1.如果root为空,返回0
//2.返回左子树节点个数+右子树节点个数+1
size_t _Size(Node* root)
{
if (NULL == root)
return 0;
return size_t Size(root->left) + size_t Size(root->right)+1;
}
//求叶子节点的个数
//1.root为空,返回0
//2.只有root 一个节点,返回1
//3.返回左子树叶子个数+右子树节点个数
size_t _LeafSize(Node* root)
{
if (NULL == root)
return 0;
else (NULL == root->left && NULL == root->right)
return 1;
return _LeafSize(root->left) + size_t _LeafSize(root->rihgt);
}
//求第K 层节点的个数
//1.root 为空,返回0
//2.k = 1,返回1
//3.返回左右子树的K-1 层节点个数和
size_t GetKSize(Node* root, size_t k)
{
if (NULL == root)
return 0;
if (k == 1)
return 1;
return GetKSize(root->left, k - 1) + size_t GetKSize(root->right, k - 1);
}
//求二叉树的深度
//1.root 为空,返回0
//2.只有根节点,返回1
//3.返回左右子树深度较大值+1
size_t _Depth(Node* root)
{
if (NULL == root)
return 0;
if (NULL == root->left && NULL == root->right)//只有根节点
return 1;
return _Depth(root->left) > _Depth(root->right) ? _Depth(root->left) + 1 : _Depth(root->right)+1
}
//查找值为 x 的节点
//1.root为空,返回NULL
//2.root->data = x ,返回root
//3.左右子树查找,找到则返回,否则返回NULL
Node* _FindX(Node* root, const T& x)
{
if (NULL == root)
return NULL;
if (root->data == x)
return root;
Node* ret = _FindX(root->left ,x);
if (ret)
return ret;
return _FindX(root->right, x);
}
//求其父亲节点
//(Node->left = pCur || Node->right = pCur ) 则Node 为pCur的父亲节点
Node* _Parent(Node* pRoot, Node* pCur)
{
assert(NULL != pCur)
if (NULL == pRoot || NULL == pCur)
return NULL;
if (pRoot->_pLeft == pCur || pRoot->_pRight == pCur)
return pRoot;
Node* parent = NULL;
if (parent = _Parent(pRoot->_pLeft, pCur))
return parent;
return _Parent(pRoot->_pRight, pCur);
}
//求叶子节点的个数
//左子树叶子节点数 + 右子树节点数
size_t _GetLeeNum(Node* pRoot)
{
if (NULL == pRoot)
return 0;
if (NULL == pRoot->_pLeft && NULL == pRoot->_pRight)
return 1;
return _GetLeeNum(pRoot->_pLeft) + _GetLeeNum(pRoot->_pRight);
}
// 镜像
void _BinarryMirror(Node* pRoot)
{
if (pRoot)
{
std::swap(pRoot->_pLeft, pRoot->_pRight);
_BinarryMirror(pRoot->_pLeft);
_BinarryMirror(pRoot->_pRight);
}
}
// 判断是否为完全二叉树
bool _IsCompeleteBinarryTree()
{
if (NULL == _pRoot)
return true;
bool flag = false;
queue<Node*> q;
q.push(pRoot);
while (!q.empty())
{
Node* pCur = q.front();
if (flag)
{
if (pCur->_pLeft || pCur->_pRight)
return false;
}
else
{
if (pCur->_pLeft && pCur->_pRight)
{
q.push(pCur->_pLeft);
q.push(pCur->_pRight);
}
else if (pCur->_pLeft)
{
q.push(pCur->_pLeft);
flag = true;
}
else if (pCur->_pRight)
{
q.push(pCur->_pRight);
flag = true;
}
else
return false;
}
q.pop();
}
}