您的位置:首页 > 理论基础 > 数据结构算法

二叉树的二叉链表表示与实现

2010-03-15 14:03 225 查看
前面几节讲到的结构都是一种线性的数据结构,今天要说到另外一种数据结构——树,其中二叉树最为常用。二叉树的特点是每个结点至多只有两棵子树,且二叉树有左右字子树之分,次序不能任意颠倒。

二叉树的存储结构可以用顺序存储和链式存储来存储。二叉树的顺序存储结构由一组连续的存储单元依次从上到下,从左到右存储完全二叉树的结点元素。对于一般二叉树,应将其与完全二叉树对应,然后给每个结点从1到i编上号,依次存储在大小为i-1的数组中。这种方法只适用于完全二叉树,对非完全二叉树会浪费较多空间,最坏情况一个深度为k的二叉树只有k个结点,却需要长度为2的k次方减一长度的一位数组。事实上,二叉树一般使用链式存储结构,由二叉树的定义可知,二叉树的结点由一个数据元素和分别指向其左右孩子的指针构成,即二叉树的链表结点中包含3个域,这种结点结构的二叉树存储结构称之为二叉链表。

二叉链表的存储结构

[cpp] view
plaincopy

typedef struct tnode {  

    elemtype        data;  

    struct tnode        *lchild;  

    struct tnode        *rchild;  

}*bitree, bitnode;  

创建一棵二叉树(按先序序列建立)

[cpp] view
plaincopy

int create_bitree(bitree *bt)  

{  

    elemtype    data;  

  

    scanf("%d", &data);  

    if (0 == data) {  

        *bt = NULL;  

    } else {  

        *bt = (bitree)malloc(sizeof(bitnode));  

        if (!(*bt))  

            exit(OVERFLOW);  

        (*bt)->data = data;  

        create_bitree(&(*bt)->lchild);  

        create_bitree(&(*bt)->rchild);  

    }  

    return OK;  

}  

按先序次序输入二叉树的结点值,0表示空树。
二叉树的遍历(先序、中序、后序)

[cpp] view
plaincopy

void preorder(bitree bt, int (*visit)(elemtype e))  

{  

    if (bt) {  

        visit(bt->data);  

        preorder(bt->lchild, visit);  

        preorder(bt->rchild, visit);  

    }  

}  

[cpp] view
plaincopy

void inorder(bitree bt, int (*visit)(elemtype e))  

{  

    if (bt) {  

        inorder(bt->lchild, visit);  

        visit(bt->data);  

        inorder(bt->rchild, visit);  

    }  

}  

[cpp] view
plaincopy

void postorder(bitree bt, int (*visit)(elemtype e))  

{  

    if (bt) {  

        postorder(bt->lchild, visit);  

        postorder(bt->rchild, visit);  

        visit(bt->data);  

    }  

}  

二叉树的递归算法较简单,代码简洁清晰,但递归算法效率低,执行速度慢,在下一节将说到二叉树非递归遍历算法。
求二叉树的深度

[cpp] view
plaincopy

int get_tree_depth(bitree bt)  

{  

    int ldepth, rdepth;  

  

    if (!bt)  

        return 0;  

    else if (!bt->lchild && !bt->rchild)  

        return 1;  

    else {  

        ldepth = get_tree_depth(bt->lchild);  

        rdepth = get_tree_depth(bt->rchild);  

  

        return (ldepth > rdepth ? ldepth : rdepth) + 1;  

    }  

}  

树的深度即树的结点中最大层次,分别递归求左右子树的深度,较大子树深度为树的深度。
求叶子结点数

[cpp] view
plaincopy

int get_num_of_leave(bitree bt)  

{  

    if (!bt)  

        return 0;  

    else if (!bt->lchild && !bt->rchild)  

        return 1;  

    else  

        return (get_num_of_leave(bt->lchild) + get_num_of_leave(bt->rchild));  

}  

递归求左右子树的叶子数,左右子树的叶子结点之和为树的叶子结点数。
释放二叉树

[cpp] view
plaincopy

void free_bitree(bitree *bt)  

{  

    if (*bt) {  

        if ((*bt)->lchild)  

            free_bitree(&(*bt)->lchild);  

        if ((*bt)->rchild)  

            free_bitree(&(*bt)->rchild);  

            free(*bt);  

            *bt = NULL;  

    }  

}  

算法实现源码
免费下载:http://download.csdn.net/detail/algorithm_only/3800074
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  数据结构 二叉树