二叉树的类型定义与基本操作

二叉树的类型定义与基本操作

树结构是一类重要的非线性数据结构,在客观世界中广泛存在。树在计算机领域中也得到了广泛的应用,尤以二叉树最为常用。本文重点讨论二叉树的基本操作。

1. 二叉树的类型定义

二叉树通常由三个域组成:数据域左孩子指针域和右孩子指针域

其类型定义为:

typedef struct BiNode
{
    char data;                       // 数据域
    struct BiNode* lchild, * rchild; // 左右孩子指针域
}BiTNode, *BiTree;

2. 二叉树的基本操作

二叉树的操作数目繁多,本文给出以下 16 种常用操作的代码实现:

(1) 二叉树的初始化
(2) 二叉树的建立
(3) 二叉树的判空
(4) 二叉树的销毁
(5) 先序遍历二叉树
(6) 中序遍历二叉树
(7) 后序遍历二叉树
(8) 求二叉树的深度
(9) 求二叉树的结点数
(10) 求二叉树的叶子数
(11) 求根结点的数据域
(12) 求某结点的双亲的数据域
(13) 求某结点的左孩子的数据域
(14) 求某结点的右孩子的数据域
(15) 返回指定数据的结点
(16) 修改指定结点的数据域

下面为具体的代码实现:

算法1:二叉树的初始化

【代码实现】

void InitBiTree(BiTree &T)
{
    T = NULL;
}

算法2:二叉树的建立

【代码实现】

 void CreateBiTree(BiTree &T)
{
    char ch;
    cin >> ch;
    if (ch == '#') T = NULL;
    else
    {
        T = new BiTNode;
        T->data = ch;
        CreateBiTree(T->lchild);
        CreateBiTree(T->rchild);
    }
}

算法3:二叉树的判空

【代码实现】

Status BiTreeEmpty(BiTree T)
{
    if (T)
        return FALSE;
    else
        return TRUE;
}

算法4:二叉树的销毁

【代码实现】

void DestroyBiTree(BiTree T)
{
    if (T)
    {
        if (T->lchild)
            DestroyBiTree(T->lchild);
        if (T->rchild)
            DestroyBiTree(T->rchild);
        free(T);
        T = NULL;
    }
}

算法5:先序遍历二叉树

【代码实现】

void PreOrderTraverse(BiTree T)
{
    cout << T->data;
    if(T->lchild)
        PreOrderTraverse(T->lchild);
    if(T->rchild)
        PreOrderTraverse(T->rchild);
}

算法6:中序遍历二叉树

【代码实现】

void InOrderTraverse(BiTree T)
{
    if (T->lchild)
        PreOrderTraverse(T->lchild);
    cout << T->data;
    if (T->rchild)
        PreOrderTraverse(T->rchild);
}

算法7:后序遍历二叉树

【代码实现】

void PostOrderTraverse(BiTree T)
{
    if (T->lchild)
        PreOrderTraverse(T->lchild);
    if (T->rchild)
        PreOrderTraverse(T->rchild);
    cout << T->data;
}

算法8:求二叉树的深度

【代码实现】

Status BiTreeDepth(BiTree T)
{
    if (BiTreeEmpty(T))
        return 0;
    else
    {
        int m = BiTreeDepth(T->lchild);
        int n = BiTreeDepth(T->rchild);
        if (m > n) return (m + 1);
        else return (n + 1);
    }
}

算法9:求二叉树的结点数

【代码实现】

Status NodeCount(BiTree T)
{
    if (BiTreeEmpty(T))
        return 0;
    else return NodeCount(T->lchild) + NodeCount(T->rchild) + 1;
}

算法10:求二叉树的叶子数

【代码实现】

Status LeafCount(BiTree T)
{
    if (BiTreeEmpty(T))
        return 0;
    if (BiTreeEmpty(T->lchild) && BiTreeEmpty(T->rchild))
        return 1;
    else
        return LeafCount(T->lchild) + LeafCount(T->rchild);
}

算法11:求根结点的数据域

【代码实现】

char Root(BiTree T)
{
    if (BiTreeEmpty(T))
        return ' ';
    else
        return T->data;
}

算法12:求某结点的双亲的数据域

【代码实现】

char Parent(BiTree T, char e)
{
    if (T)
    {
        if (T->lchild && T->lchild->data == e || T->rchild && T->rchild->data == e)
            return T->data;
        else
        {
            char c = Parent(T->lchild, e);
            if (c)
                return c;
            else
                return ' ';
            c = Parent(T->rchild, e);
            if (c)
                return c;
            else
                return ' ';
        }
    }
}

算法13:求某结点的左孩子的数据域

【代码实现】

char LeftChild(BiTree T, char e)
{
    p = Point(T, e);
    if (p->lchild)
        return p->lchild->data;
    else return ' ';
}

算法14:求某结点的右孩子的数据域

【代码实现】

char RightChild(BiTree T, char e)
{
    p = Point(T, e);
    if (p->rchild)
        return p->rchild->data;
    else return ' ';
}

算法15:返回指定数据的结点

【代码实现】

BiNode* Point(BiTree T, char e)
{
    if (T)
    {
        if (T->data == e)
            return T;
        BiNode* node = Point(T->lchild, e);
        if (node)
            return node;
        node = Point(T->rchild, e);
        if (node)
            return node;
        else
            return NULL;
    }
}

算法16:修改指定结点的数据域

【代码实现】

void Assign(BiTree &p, char e)
{
    p->data = e;
}

二叉树还有许多高阶操作,但万变不离其宗,其本质还是数种基本操作的组合,读者可自己编写完成。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值