二叉树的基本操作(先序,中序,后序)(C++)

二叉树(Binary tree)是树形结构的一个重要类型。许多实际问题抽象出来的数据结构往往是二叉树形式,即使是一般的树也能简单地转换为二叉树,而且二叉树的存储结构及其算法都较为简单,因此二叉树显得特别重要。二叉树特点是每个节点最多只能有两棵子树,且有左右之分。

下面我们来看看二叉树的抽象数据类型实现

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

#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -1

typedef char TElemType;
typedef int Status;

typedef struct BiTNode {
    TElemType data;                     //数据域
    struct BiTNode *lChild, *rChild;    //左右孩子指针域
} BiTNode, *BiTree;                     //二叉链表

其中每个结点都含有一个数据域还有两个指针域,用来抽象的表示左右孩子的地址。

下面我们来看看二叉树的几个基本操作。

Status InitBiTree(BiTree &T) { //创建一棵空的二叉树
    T = (BiTree) malloc(sizeof(BiTree));
    if (NULL == T) return OVERFLOW;
    T->data = NULL;
    T->lChild = NULL;
    T->rChild = NULL;
    return OK;
}

BiTree CreateBiTree(char *defBT, int &i) {   //先序创建一个二叉树
    BiTree T;
    TElemType c;
    c = defBT[i++];
    if ('#' == c)
        InitBiTree(T);
    else {
        T = MakeBiTree(c, NULL, NULL);  //构造结点e
        T->lChild = CreateBiTree(defBT, i); //构造左子树
        T->rChild = CreateBiTree(defBT, i); //构造右子树
    }
    return T;
}

BiTree MakeBiTree(TElemType e, BiTree L, BiTree R) { //创建一棵二叉树T,其中根节点的值为e,L和R分别作为左子树和右子树
    BiTree T = (BiTree) malloc(sizeof(BiTree));
    if (NULL == T)
        return NULL;
    T->data = e;
    T->lChild = L;
    T->rChild = R;
    return T;
}

void DestroyBiTree(BiTree &T) {  //销毁二叉树
    if (NULL == T)
        return;
    DestroyBiTree(T->lChild);
    DestroyBiTree(T->rChild);
    free(T);
}

int Depth(BiTree T) {   //树的深度
    if (T == NULL)
        return 0;
    else {
        int m = Depth(T->lChild);
        int n = Depth(T->rChild);
        if (m > n)
            return m + 1;
        else
            return n + 1;
    }
}

Status BiTreeEmpty(BiTree T) {   //对二叉树判空,若为空返回TRUE,否则返回False
    if (NULL == T) return TRUE;
    return FALSE;
}

int NodeCount(BiTree T) {//统计二叉树中结点的个数
    if (T == NULL)
        return 0;
    else
        return NodeCount(T->lChild) + NodeCount(T->rChild) + 1;
}

Status BreakBiTree(BiTree &T, BiTree &L, BiTree &R) {    //将一棵二叉树T分解为成根,左子树和右子树3个部分
    L->rChild = T->lChild;
    R->rChild = T->rChild;
    T->rChild = NULL;
    T->lChild = NULL;
    return OK;
}

Status ReplaceLeft(BiTree &T, BiTree &LT) {  //替换左子树 若T非空,则用RT替换T的左子树,并用LT返回T的原有左子树
    BiTree temp;
    if (NULL == T) return ERROR;
    temp = T->lChild;;
    T->lChild = LT;
    LT = temp;
    return OK;
}

int LeafCount(BiTree T) {//统计二叉树中叶子结点的个数
    if (!T) return 0;
    if (!T->lChild && !T->rChild) { //如果二叉树左子树和右子树皆为空,说明该二叉树根节点为叶子节点,加1.
        return 1;
    } else {
        return LeafCount(T->lChild) + LeafCount(T->rChild);
    }
}

Status ReplaceRight(BiTree &T, BiTree &RT) {    //替换右子树 若T非空,则用RT替换T的右子树,并用LT返回T的原有右子树
    BiTree temp;
    if (NULL == T) return ERROR;
    temp = T->rChild;;
    T->rChild = RT;
    RT = temp;
    return OK;
}

下面是需要重点掌握的使用递归算法的先序,中序,后序遍历二叉树。

Status visit(TElemType e) { //遍历二叉树打印便利的值的函数
    printf("%d", e);
    return OK;
}

Status InorderTraverse(BiTree T, Status(*visit)(TElemType e)) { //中序遍历二叉树T,visit是对数据元素操作的应用函数
    if (NULL == T) return OK;
    if (ERROR == InorderTraverse(T->lChild, visit))
        return ERROR;   //递归遍历T的左子树
    if (ERROR == visit(T->data))
        return ERROR;   //访问结点的数据域
    return InorderTraverse(T->rChild, visit);    //递归遍历T的右子树
}

Status PreOrderTraverse(BiTree T, Status(*visit)(TElemType e)) { //前序遍历二叉树T,visit是对数据元素操作的应用函数
    if (NULL == T) return OK;
    if (ERROR == visit(T->data))
        return ERROR;   //访问结点的数据域
    if (ERROR == PreOrderTraverse(T->lChild, visit))
        return ERROR;   //递归遍历T的左子树
    return PreOrderTraverse(T->rChild, visit);    //递归遍历T的右子树
}

Status PostOrderTraverse(BiTree T, Status(*visit)(TElemType e)) {   //后序遍历二叉树T,visit是对数据元素操作的应用函数
    if (NULL == T) return OK;
    if (ERROR == PostOrderTraverse(T->lChild, visit))
        return ERROR;   //访问结点的数据域
    if (ERROR == PostOrderTraverse(T->rChild, visit))
        return ERROR;   //递归遍历T的左子树
    return visit(T->data);    //递归遍历T的右子树
}
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

low泡程序员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值