二叉树

二叉树

是树的一种,其存储结构及其算法都较为简单,因此二叉树显得特别重要。

二叉树是每个结点最多有两个子树的有序树。

注意:在有序树中,虽然一个节点的孩子之间是有左右次序的,但是若该节点只有一个孩子,就无须区

分其左右次序。而在二叉树中,即使是一个孩子也有左右之分。

二叉树的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; 

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值