二叉树

来源:互联网 发布:卖衣服打折怎么计算法 编辑:程序博客网 时间:2024/06/13 03:00
/*******************************************************
  已知先序序列和中序序列,构造二叉树
  先序序列:4 3 1 2 5 6 7
  中序序列:1 3 2 4 6 7 5
  后序序列:1 2 3 7 6 5 4
  层次遍历:4 3 5 1 2 6 7

  二叉树:     4
                     /   \
                   3     5
                   / \     /
                 1   2  6
                            \
                             7
********************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>

typedef int ElemType;

typedef struct BiTree
{
    ElemType        elem;
    struct BiTree    *leftchild;
    struct BiTree    *rightchild;
}BiTreeNode;

void Visit(BiTreeNode *pNode)
{
    printf("%3d", pNode->elem);
}

BiTreeNode * MakeRootNode(ElemType elem)
{
    BiTreeNode *pNode = (BiTreeNode *)malloc(sizeof(BiTreeNode));
    assert(NULL != pNode);

    pNode->elem = elem;
    pNode->leftchild = NULL;
    pNode->rightchild = NULL;

    return    pNode;
}

BiTreeNode * CreateBiTree(const VLR[], const LVR[], int len)
{
    if(len <= 0)
    {
        return NULL;
    }

    int index = 0;

    while(VLR[0] != LVR[index]) /*在LVR[]数组中,找到根结点的位置*/
    {
        index++;
    }

    BiTreeNode *pNode = MakeRootNode(LVR[index]); /*当前结点作为根结点*/
    pNode->leftchild = CreateBiTree(VLR+1, LVR, index); /*LVR[]数组左边的结点作为当前根结点的左子树*/
    /*LVR[]数组右边的结点作为当前根结点的右子树*/
    pNode->rightchild = CreateBiTree(VLR+index+1, LVR+index+1, len-index-1);

    return pNode;
}

void Pre_Order(BiTreeNode *pRootNode)
{
    if(pRootNode)
    {
        Visit(pRootNode);
        Pre_Order(pRootNode->leftchild);
        Pre_Order(pRootNode->rightchild);
    }
}

void In_Order(BiTreeNode *pRootNode)
{
    if(pRootNode)
    {
        In_Order(pRootNode->leftchild);
        Visit(pRootNode);
        In_Order(pRootNode->rightchild);
    }
}

void Post_Order(BiTreeNode *pRootNode)
{
    if(pRootNode)
    {
        Post_Order(pRootNode->leftchild); /*递归的思想实现后序遍历,类似与深度搜索*/
        Post_Order(pRootNode->rightchild);
        Visit(pRootNode);
    }
}

void Lever_Order(BiTreeNode *pNode) /*层次遍历,用队列来实现,类似与广度优先搜索*/
{
    BiTreeNode * array[100];
    unsigned int head = 0;
    unsigned int tail = 0;
    memset(array, 0, sizeof(array));

    if(pNode)
    {
        array[tail++] = pNode; /*根结点不空,则入队列*/
    }

    while(tail != head)
    {
        pNode = array[head++];
        Visit(pNode);
        if(NULL != pNode->leftchild)
        {
            array[tail++] = pNode->leftchild; /*左孩子不空,入队列*/
        }

        if(NULL != pNode->rightchild)
        {
            array[tail++] = pNode->rightchild; /*右孩子不空,入队列*/
        }
    }
}

/*统计结点个数,可以通过刚刚的层次遍历,把tail的值返回就是结点个数*/
unsigned int CountNode(BiTreeNode *pRootNode)
{
    if(NULL == pRootNode)
    {
        return    0;            /*递归的思想统计二叉树的结点个数*/
    }

    return    1 + CountNode(pRootNode->leftchild) + CountNode(pRootNode->rightchild);
}

unsigned int CountDepth(BiTreeNode *pRootNode)
{
    unsigned int left_depth, right_depth;

    if(NULL == pRootNode)
    {
        return    0;            /*递归思想统计二叉树的深度*/
    }

    left_depth = CountDepth(pRootNode->leftchild);
    right_depth = CountDepth(pRootNode->rightchild);

    return    1 + (left_depth > right_depth ? left_depth : right_depth);
}

void DestroyTree(BiTreeNode *pRootNode)
{
    if(pRootNode)
    {
        DestroyTree(pRootNode->leftchild);
        DestroyTree(pRootNode->rightchild);
        free(pRootNode);                        /*后序遍历的思想释放结点空间*/
        pRootNode = NULL;
    }
}

/*************************************************************************
 总的思想就是,用递归的思想构建二叉树,也用递归的思想遍历二叉树
**************************************************************************/

int main(void)
{
    ElemType VLR[] = {4, 3, 1, 2, 5, 6, 7}; /*先序序列*/
    ElemType LVR[] = {1, 3, 2, 4, 6, 7, 5}; /*中序序列*/

    BiTreeNode *pRootNode = CreateBiTree(VLR, LVR, sizeof(VLR)/VLR[0]); /*已知先序序列和中序序列构造二叉树*/

    printf("先序序列: ");
    Pre_Order(pRootNode);
    printf("\n\n");

    printf("中序序列: ");
    In_Order(pRootNode);
    printf("\n\n");

    printf("后序序列: ");
    Post_Order(pRootNode);
    printf("\n\n");

    printf("层次遍历: ");
    Lever_Order(pRootNode);
    printf("\n\n");

    unsigned int node_num = CountNode(pRootNode);
    printf("node_num = %u \n\n", node_num);

    unsigned int tree_depth = CountDepth(pRootNode);
    printf("tree_depth = %u \n\n", tree_depth);

    DestroyTree(pRootNode);
    printf("BiTree Node is free ! \n");

    return    0;
}
0 0
原创粉丝点击