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

来源:互联网 发布:linux编译环境搭建 编辑:程序博客网 时间:2024/05/24 03:33

二叉树的概念:

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

二叉树的性质:

1. 在二叉树的第i层上最多有2i-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   -2typedef int Status;typedef int TElemType;//--------二叉树二叉链表存储表示---------------typedef struct BiTNode{    TElemType data;                     //数据域    struct BiTNode *lchild;             //左孩子指针域    struct BiTNode *rchild;             //右孩子指针域}BiTNode, *BiTree;//---------基本操作函数的简单实现---------------//构造空的二叉树TStatus InitBiTree(BiTree &T){    T = NULL;                       //直接将根结点赋值为NULL即表示为空树    return OK;}//销毁二叉树TStatus DestroyBiTree(BiTree &T){    /*如果树为空,则直接返回OK, 否则,先递归释放左子树,再递归释放右子树,最后释放根结点*/    if(!T)        return OK;    else{        DestroyBiTree(T->lchild);        DestroyBiTree(T->rchild);        free(T);        T = NULL;        return OK;    }}//先序构造二叉树TStatus 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;}

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