二叉树
是树的一种,其存储结构及其算法都较为简单,因此二叉树显得特别重要。
二叉树是每个结点最多有两个子树的有序树。
注意:在有序树中,虽然一个节点的孩子之间是有左右次序的,但是若该节点只有一个孩子,就无须区
分其左右次序。而在二叉树中,即使是一个孩子也有左右之分。
二叉树的5种表现形式
1、空树
2、只有一个根节点的二叉树
3、只有一个左子树的二叉树
4、只有一个右子树的二叉树
5、有左右子树的二叉树
二叉树的特性
1、二叉树的每个结点至多只有二棵子树(不存在度大于2的结点)。
2、二叉树的子树有左右之分,次序不能颠倒。
3、二叉树的第i层至多有2的 i -1次方个结点。
4、深度为k的二叉树至多有2^(k) -1个结点。
5、任意一棵二叉树中,如果度为2的节点数为n,度为0的节点数为m,m = n + 1。
满二叉树
是二叉树的一种特殊的情况
满二叉树的特性
1、二叉树中第i层上的节点数必须为2的i次方个节点
2、二叉树如果高度为k,这个二叉树中的节点数量必须为2的(k+1)次方-1个
3、在满二叉树中不存在度为1的节点,每一个分支节点都有2棵高度一致的子树,所有的叶节点都在最
下一层
完全二叉树
也是二叉树的一种特殊情况
若一棵二叉树最多只有最下面的两层,其节点的度数可以小于2,并且最下一层上的节点都集中在该层最
左边的若干位置上,则此二叉树称为完全二叉树。
满二叉树是完全二叉树,完全二叉树不一定是满二叉树。
完全二叉树的特性1、从一棵满二叉树的最下一层(叶节点那一层),从右往左依次删除若干(0-n)节点后形成的树叫完
全二叉树
2、在一棵完全二叉树中,如果一个节点没有左子树,这个节点必然没有右子树,这个节点是叶节点
完全二叉树中的下标规律
1、根节点下标默认为0
2、树中的任意一个节点它的下标为i,那么这个节点的父节点下标必然为(i - 1)>> 1
3、树中的任意一个节点它的下标为i,那么这个节点的左子树下标必然是2 * i + 1;右子树的下标必然是2 *
i + 2
4、除开根节点,左子树的下标为奇数,右子树的下标为偶数
二叉树的遍历方式
1、先序(根)
2、中序(根)
3、后序(根)
顺序存储示例
template<typename T>
class CMyTree_Arr
{
T *pBuff;
size_t len;
size_t maxSize;
public:
CMyTree_Arr();
~CMyTree_Arr();
void clear();
public:
bool find(T const& findVal) const;
void appendNode(T const& data);
void initTree(T arr[], int length);
void printfTree();
T GetParentVal(int index) const;
T GetLeftVal(int index) const;
private:
int _find(T const& findVal) const;
void _printfTree(int index);
};
template<typename T>
T CMyTree_Arr<T>::GetLeftVal(int index) const
{
if (2 * index + 1 >= len || index < 0)
throw "out_range";
return pBuff[2 * index + 1];
}
template<typename T>
T CMyTree_Arr<T>::GetParentVal(int index) const{
return pBuff[(index - 1) >> 1];
}
template<typename T>
void CMyTree_Arr<T>::_printfTree(int index)
{
if (index < (int)len)
{
_printfTree(2 * index + 1);
_printfTree(2 * index + 2);
printf("%d\n", pBuff[index]);
}
}
template<typename T>
void CMyTree_Arr<T>::printfTree()
{
_printfTree(0);
}
template<typename T>
void CMyTree_Arr<T>::initTree(T arr[], int length)
{
clear();
if (length > 0)
{
maxSize = len = length;
pBuff = new T[maxSize];
for (size_t i = 0; i < maxSize; ++i)
pBuff[i] = arr[i];
}
}
template<typename T>
void CMyTree_Arr<T>::appendNode(T const& data)
{
if (len >= maxSize)
{
maxSize = maxSize + ((maxSize >> 1) > 1 ? (maxSize >> 1) : 1);
T *tempBuff = new T[maxSize];
for (size_t i = 0; i < len; ++i)
tempBuff[i] = pBuff[i];
if (pBuff)
delete[] pBuff;
pBuff = tempBuff;
}
pBuff[len++] = data;
}
template<typename T>
int CMyTree_Arr<T>::_find(T const& findVal) const
{
for (size_t i = 0; i < len; ++i)
{if (pBuff[i] == findVal)
return i;
}
return -1;
}
template<typename T>
bool CMyTree_Arr<T>::find(T const& findVal) const
{
return _find(findVal) != -1;
}
template<typename T>
void CMyTree_Arr<T>::clear()
{
if (pBuff)
delete[] pBuff;
pBuff = nullptr;
len = maxSize = 0;
}
template<typename T>
CMyTree_Arr<T>::~CMyTree_Arr()
{
clear();
}
template<typename T>
CMyTree_Arr<T>::CMyTree_Arr()
{
pBuff = nullptr;
len = maxSize = 0;
}