<C语言数据结构五>一篇文章“学废“二叉树(binary tree)

一、基本概念

二叉树:是指树中节点的度不大于2的有序树,它是一种最简单且最重要的树。
常用名词解释:

  • 节点:包含一个数据元素及若干指向子树分支的信息
  • 节点的度:一个节点拥有子树的数目称为节点的度
  • 叶子节点:也称为终端节点,没有子树的节点或者度为零的节点
  • 分支节点:也称为非终端节点,度不为零的节点称为非终端节点
  • 树的度:树中所有节点的度的最大值
  • 节点的层次:从根节点开始,假设根节点为第1层,根节点的子节点为第2层,依此类推,如果某一个节点位于第L层,则其子节点位于第L+1层
  • 树的深度:也称为树的高度,树中所有节点的层次最大值称为树的深度
  • 有序树:如果树中各棵子树的次序是有先后次序,则称该树为有序树
  • 无序树:如果树中各棵子树的次序没有先后次序,则称该树为无序树
  • 森林:由m(m≥0)棵互不相交的树构成一片森林。如果把一棵非空的树的根节点删除,则该树就变成了一片森林,森林中的树由原来根节点的各棵子树构成

特殊的二叉树

  • 满二叉树:如果二叉树中除了叶子结点,每个结点的度都为 2,则此二叉树称为满二叉树
    在这里插入图片描述

  • 完全二叉树:如果二叉树中除去最后一层节点为满二叉树,且最后一层的结点依次从左到右分布,则此二叉树被称为完全二叉树
    在这里插入图片描述

  • 二叉搜索树:

    • 空树是一个二叉搜索树
    • 如果二叉树中的左子树不空,则左子树上所有结点的值均小于它的根结点的值;如果二叉树中右子树不空,则右子树上所有结点的值均大于它的根结点的值;它的左、右子树也分别为二叉搜索树。
      在这里插入图片描述

二、C语言实现一个二叉树

2.1. 二叉树的数据结构定义

typedef struct Node {
    struct Node *p_left;
    struct Node *p_right;
    int data;   // 节点数据
    int cnt;    // 相同数据的个数
} NODE_T;

2.2. 二叉树的创建

NODE_T *create_node(int value)
{
    NODE_T *pnode = (NODE_T *)malloc(sizeof(NODE_T));
    pnode->data = value;
    pnode->cnt = 1;
    pnode->p_left = pnode->p_right = NULL;
    return pnode;
}

2.3. 二叉树添加节点

添加的时候按照二叉搜索树的形式插入节点,完成排序!!!

NODE_T *add_node(int value, NODE_T *pnode)
{
    if (pnode == NULL) {
        return create_node(value);
    }

    if (value == pnode->data) {
        pnode->cnt++;
        return pnode;
    }

    if (value < pnode->data) {
        if (pnode->p_left == NULL) {
            pnode->p_left = create_node(value);
            return pnode->p_left;
        } else {
            return add_node(value, pnode->p_left);
        }
    } else {
        if (pnode->p_right == NULL) {
            pnode->p_right = create_node(value);
            return pnode->p_right;
        } else {
            return add_node(value, pnode->p_right);
        }
    }
}

2.4. 二叉树的遍历

void list_nodes(NODE_T *pnode)
{
    if (pnode != NULL) {
        list_nodes(pnode->p_left);
        while (pnode->cnt--) {
            printf("%d\n", pnode->data);
        }
        list_nodes(pnode->p_right);
    }
}

2.5. 二叉树的深度的获取

使用递归的方式遍历所有节点,计算树的深度!!!

int get_tree_height(NODE_T *pnode)
{
    int LD, RD;
    if (pnode == NULL) {
        return 0;
    } else {
        LD = get_tree_height(pnode->p_left);
        RD = get_tree_height(pnode->p_right);
        return (LD >= RD ? LD : RD) + 1;
    }
}

2.6. 测定demo

int main(void)
{
    int newvalue = 0;
    NODE_T *proot = NULL;
    char answer = 'n';
    do {
        printf("Enter the node value:\n");
        scanf("%d", &newvalue);
        if (proot == NULL) {
            proot = create_node(newvalue);
        } else {
            add_node(newvalue, proot);
        }
        printf("\nDo you want to enter another (y or n)? ");
        scanf(" %c", &answer);
    } while (tolower(answer) == 'y');

    list_nodes(proot);
    printf("\nThe height of tree is %d!", get_tree_height(proot));

    return 0;
}

运行结果:
在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

坚持学习的小王同学

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

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

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

打赏作者

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

抵扣说明:

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

余额充值