二叉树

二叉树

定义

在计算机科学中,二叉树是每个节点最多有两个子树的树结构。
通常子树被称作“左子树”(left subtree)和“右子树”(right subtree)。
二叉树常被用于实现二叉查找树和二叉堆。

特点

二叉树的每个结点至多只有二棵子树(不存在度大于2的结点),二叉树的子树有左右之分,次序不能颠倒
二叉树的第i层至多有2^(i-1)个结点;深度为k的二叉树至多有2^k-1个结点
对任何一棵二叉树T,如果其终端结点数为n_0,度为2的结点数为n_2,则n_0=n_2+1

一棵深度为k,且有2^k-1个节点称之为满二叉树;

深度为k,有n个节点的二叉树,当且仅当其每一个节点都与深度为k的满二叉树中,序号为1至n的节点对应时,称之为完全二叉树。

  1. 在非空二叉树中,第i层的结点总数不超过2^(i-1) , i>=1;
  2. 深度为h的二叉树最多有2^h-1个结点(h>=1),最少有h个结点;
  3. 对于任意一棵二叉树,如果其叶结点数为N0,而度数为2的结点总数为N2,则N0=N2+1;
  4. 具有n个结点的完全二叉树的深度为
  5. 有N个结点的完全二叉树各结点如果用顺序方式存储,则结点之间有如下关系:
    若I为结点编号则 如果I>1,则其父结点的编号为I/2;
    如果2I<=N,则其左儿子(即左子树的根结点)的编号为2I;若2I>N,则无左儿子;
    如果2
    I+1<=N,则其右儿子的结点编号为2I+1;若2I+1>N,则无右儿子。
  6. 给定N个节点,能构成h(N)种不同的二叉树。
    h(N)为卡特兰数的第N项。h(n)=C(2*n,n)/(n+1)。
  7. 设有i个枝点,I为所有枝点的道路长度总和,J为叶的道路长度总和J=I+2i[4]

遍历

前序遍历

先访问根,再先序遍历左(右)子树,最后先序遍历右(左)子树

1
2
3
4
5
6
7
8
void PreOrderTraverse(BinaryTreeNode * pRoot)
{
trueif(pRoot == NULL)
truetruereturn;
trueVisit(pRoot); // 访问根节点
truePreOrderTraverse(pRoot->m_pLeft); // 前序遍历左子树
truePreOrderTraverse(pRoot->m_pRight); // 前序遍历右子树
}

中序遍历

首先中序遍历左(右)子树,再访问根,最后中序遍历右(左)子树

1
2
3
4
5
6
7
8
void InOrderTraverse(BinaryTreeNode * pRoot)
{
trueif(pRoot == NULL)
truetruereturn;
trueInOrderTraverse(pRoot->m_pLeft); // 中序遍历左子树
trueVisit(pRoot); // 访问根节点
trueInOrderTraverse(pRoot->m_pRight); // 中序遍历右子树
}

后续遍历

首先后序遍历左(右)子树,再后序遍历右(左)子树,最后访问根

1
2
3
4
5
6
7
8
void PostOrderTraverse(BinaryTreeNode * pRoot)
{
trueif(pRoot == NULL)
truetruereturn;
truePostOrderTraverse(pRoot->m_pLeft); // 后序遍历左子树
truePostOrderTraverse(pRoot->m_pRight); // 后序遍历右子树
trueVisit(pRoot); // 访问根节点
}

层次遍历

即按照层次访问,通常用队列来做。访问根,访问子女,再访问子女的子女(越往后的层次越低)(两个子女的级别相同)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void LevelTraverse(BinaryTreeNode * pRoot)
{
trueif(pRoot == NULL)
truetruereturn;
truequeue<BinaryTreeNode *> q;
trueq.push(pRoot);
truewhile(!q.empty())
true{
truetrueBinaryTreeNode * pNode = q.front();
truetrueq.pop();
truetrueVisit(pNode); // 访问节点
truetrueif(pNode->m_pLeft != NULL)
truetruetrueq.push(pNode->m_pLeft);
truetrueif(pNode->m_pRight != NULL)
truetruetrueq.push(pNode->m_pRight);
true}
truereturn;
}

相关操作算法实现