二叉树整理(五)

来源:互联网 发布:宋慧乔长相 知乎 编辑:程序博客网 时间:2024/06/05 08:07

1、由前序遍历序列和中序遍历序列重建二叉树

二叉树前序遍历序列中,第一个元素总是树的根节点的值。中序遍历序列中,左子树的节点的值位于根节点的值的左边,右子树的节点的值位 
于根节点的值的右边。 
递归解法: 
(1)如果前序遍历为空或中序遍历为空或节点个数小于等于0,返回NULL。 
(2)创建根节点。前序遍历的第一个数据就是根节点的数据,在中序遍历中找到根节点的位置,可分别得知左子树和右子树的前序和中序遍 
历序列,重建左右子树。

BinaryTreeNode * RebuildBinaryTree(int* pPreOrder, int* pInOrder, int nodeNum){    if(pPreOrder == NULL || pInOrder == NULL || nodeNum <= 0)        return NULL;    BinaryTreeNode * pRoot = new BinaryTreeNode;    // 前序遍历的第一个数据就是根节点数据    pRoot->m_nValue = pPreOrder[0];    pRoot->m_pLeft = NULL;    pRoot->m_pRight = NULL;    // 查找根节点在中序遍历中的位置,中序遍历中,根节点左边为左子树,右边为右子树    int rootPositionInOrder = -1;    for(int i = 0; i < nodeNum; i++)        if(pInOrder[i] == pRoot->m_nValue)        {            rootPositionInOrder = i;            break;        }    if(rootPositionInOrder == -1)    {        throw std::exception("Invalid input.");    }    // 重建左子树    int nodeNumLeft = rootPositionInOrder;    int * pPreOrderLeft = pPreOrder + 1;    int * pInOrderLeft = pInOrder;    pRoot->m_pLeft = RebuildBinaryTree(pPreOrderLeft, pInOrderLeft, nodeNumLeft);    // 重建右子树    int nodeNumRight = nodeNum - nodeNumLeft - 1;    int * pPreOrderRight = pPreOrder + 1 + nodeNumLeft;    int * pInOrderRight = pInOrder + nodeNumLeft + 1;    pRoot->m_pRight = RebuildBinaryTree(pPreOrderRight, pInOrderRight, nodeNumRight);    return pRoot;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

同样,有中序遍历序列和后序遍历序列,类似的方法可重建二叉树,但前序遍历序列和后序遍历序列不同恢复一棵二叉树,证明略。

2、判断二叉树是不是完全二叉树

若设二叉树的深度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第 h 层所有的结点都连续集中在最左边,这就是完全 
二叉树。 
有如下算法,按层次(从上到下,从左到右)遍历二叉树,当遇到一个节点的左子树为空时,则该节点右子树必须为空,且后面遍历的节点左 
右子树都必须为空,否则不是完全二叉树。

bool IsCompleteBinaryTree(BinaryTreeNode * pRoot){    if(pRoot == NULL)        return false;    queue<BinaryTreeNode *> q;    q.push(pRoot);    bool mustHaveNoChild = false;    bool result = true;    while(!q.empty())    {        BinaryTreeNode * pNode = q.front();        q.pop();        if(mustHaveNoChild) // 已经出现了有空子树的节点了,后面出现的必须为叶节点(左右子树都为空)        {            if(pNode->m_pLeft != NULL || pNode->m_pRight != NULL)            {                result = false;                break;            }        }        else        {            if(pNode->m_pLeft != NULL && pNode->m_pRight != NULL)            {                q.push(pNode->m_pLeft);                q.push(pNode->m_pRight);            }            else if(pNode->m_pLeft != NULL && pNode->m_pRight == NULL)            {                mustHaveNoChild = true;                q.push(pNode->m_pLeft);            }            else if(pNode->m_pLeft == NULL && pNode->m_pRight != NULL)            {                result = false;                break;            }            else            {                mustHaveNoChild = true;            }        }    }    return result;}
0 0
原创粉丝点击