二叉树的简单介绍和二叉树的二叉链表存储表示

二叉树的概念:

二叉树是度不大于2的有序树,二叉树的每个结点最多有两个子树,分别称为“左子树”和“右子树”。二叉树还常被用于实现二叉查找树和二叉堆。

二叉树的性质:

1.  在二叉树的第 i 层上最多有 2 i-1 个结点( i ≥ 1
2. 深度为d的二叉树最多有2^d-1个结点(d ≥ 1)
3. 对于任意一个二叉树,如果度为0的结点个数为n个,度为2的结点为m个,则n = m + 1。
4. 含n个结点的完全二叉树深度为log2n +1 。
5. 若对含 n 个结点的完全二叉树从上到下且从左至右进行1至n的编号,则对完全二叉树中编号为i的结点:
(1) 若i=1,则该结点是二叉树的根,无双亲,否则,编号为 i/2⌋ 的结点为其双亲结点;
(2) 若2i>n,则该结点无左孩子,否则,编号为2i 的结点为其左孩子结点;
(3) 若2i+1>n,则该结点无右孩子,否则,编号为2i+1 的结点为其右孩子结点。

二叉树的二叉链表存储结构的定义及基本操作的实现:

//库函数头文件包含
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <queue>

using namespace std;

//函数状态码的定义
#define TRUE        1
#define FALSE       0
#define OK          1
#define ERROR       0
#define OVERFLOW   -2

typedef int Status;
typedef int TElemType;

//--------二叉树二叉链表存储表示---------------
typedef struct BiTNode{
    TElemType data;                     //数据域
    struct BiTNode *lchild;             //左孩子指针域
    struct BiTNode *rchild;             //右孩子指针域
}BiTNode, *BiTree;


//---------基本操作函数的简单实现---------------

//构造空的二叉树T
Status InitBiTree(BiTree &T){
    T = NULL;                       //直接将根结点赋值为NULL即表示为空树
    return OK;
}

//销毁二叉树T
Status DestroyBiTree(BiTree &T){
    /*如果树为空,则直接返回OK, 否则,先递归释放左子树,再递归释放右子树,最后释放根结点*/
    if(!T)
        return OK;
    else{
        DestroyBiTree(T->lchild);
        DestroyBiTree(T->rchild);
        free(T);
        T = NULL;
        return OK;
    }
}

//先序构造二叉树T
Status CreateBiTree(BiTree &T){
    /*若输入为0,则创建一个空树,否则创建根结点,递归创建左子树,递归创建右子树。*/
    TElemType e;
    scanf("%d", &e);
    if(e == 0)
        T = NULL;
    else{
        T = (BiTNode *)malloc(sizeof(BiTNode));
        if(!T)
            exit(OVERFLOW);
        T->data = e;
        CreateBiTree(T->lchild);
        CreateBiTree(T->rchild);
    }
    return OK;
}

//判断树是否为空
bool BiTreeEmpty(BiTree T){
    if(T == NULL)           //根结点为空时表示树为空,返回true,否则返回false
        return true;
    return false;
}

//返回树的深度
int BiTreeDepth(BiTree T){
    int depth = 0;
    int depthl, depthr;
    if(!T)
        depth = 0;
    else{
        depthl = BiTreeDepth(T->lchild);
        depthr = BiTreeDepth(T->rchild);
        if(depthl > depthr)
            depth = depthl + 1;
        else
            depth = depthr + 1;
    }
    return depth;
}

//求二叉树叶子结点的个数
int LeafCount(BiTree T){
    if(!T)
        return 0;
    else if(!T->lchild && !T->rchild)
        return 1;
    else
        return LeafCount(T->lchild) + LeafCount(T->rchild);
}

//统计所有结点数
int NodeCount(BiTree T){
    if(!T)
        return 0;
    else
        return 1 + NodeCount(T->lchild) + NodeCount(T->rchild);
}

//visit()函数
Status Print(TElemType e){
    printf(" %d", e);
}

//中遍历二叉树
Status InorderTraversal(BiTree T, Status (*visit)(TElemType)){
    /*若树空则误操作,若树不空,则先递归地中序遍历左子树,后访问根结点,再递归地中序遍历右子树*/
    if(!T)
        return OK;
    else{
        InorderTraversal(T->lchild, visit);
        visit(T->data);
        InorderTraversal(T->rchild, visit);
    }
}

//先序遍历二叉树
Status PreorderTraversal(BiTree T, Status (*visit)(TElemType)){
    /*树空无操作,若树不空,则先访问根结点,后递归地先序遍历左子树,再递归地先序遍历右子树 */
    if(!T)
        return OK;
    else{
        visit(T->data);
        PreorderTraversal(T->lchild, visit);
        PreorderTraversal(T->rchild, visit);
    }
}

//后序遍历二叉树
Status PostorderTraversal(BiTree T, Status (*visit)(TElemType)){
    /*若树空无操作,若树不空,则先递归地后序遍历左子树,后递归地后序遍历,再访问根结点*/
    if(!T)
        return OK;
    else{
        PostorderTraversal(T->lchild, visit);
        PostorderTraversal(T->rchild, visit);
        visit(T->data);
    }
}

//层序遍历二叉树
Status LevelorderTraversal(BiTree T, Status (*visit)(TElemType)){
    /*如果树空,则不做任何操作,否则,利用队列,将每个结点的左右孩子入队,由于队列的性质,可按层序遍历二叉树*/
    if(!T){
        printf(" This binary tree is empty!");
        return OK;
    }
    queue<BiTNode*> TreeQueue;

    BiTree p = T;
    TreeQueue.push(p);

    while(!TreeQueue.empty()){
        p = TreeQueue.front();
        visit(p->data);
        if(p->lchild)
            TreeQueue.push(p->lchild);
        if(p->rchild)
            TreeQueue.push(p->rchild);
        TreeQueue.pop();
    }
    return OK;
}

//主函数
int main(){
    BiTree T;
    InitBiTree(T);
    CreateBiTree(T);
    printf("The number of nodes in this binary tree is: %d\n", NodeCount(T));
    printf("The inorder traversal sequence of the binary tree is:");
    InorderTraversal(T, Print);
    printf("\nThe preorder traversal sequence of the binary tree is:");
    PreorderTraversal(T, Print);
    printf("\nThe postorder traversal sequence of the binary tree is:");
    PostorderTraversal(T, Print);
    printf("\nThe levelorder traversal sequence of the binary tree is:");
    LevelorderTraversal(T, Print);
    printf("\nThe number of leaves in this binary tree is: %d", LeafCount(T));
    printf("\nThe depth of this binary tree is: %d", BiTreeDepth(T));
    printf("\nIs the binary empty? ");
    if(BiTreeEmpty(T))
        printf("YES\n");
    else
        printf("NO\n");
    DestroyBiTree(T);
    return 0;
}

下面是对代码的简单测试结果:
输入的二叉树为下图:
运行结果如下图:

  • 16
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值