数据结构8——二叉树的链式结构

目录

1.二叉树的链式存储结构

[2. 二叉树链式结构的实现](#2. 二叉树链式结构的实现)

[2.1 创建一棵简单的链式二叉树](#2.1 创建一棵简单的链式二叉树)

[1. 创建节点](#1. 创建节点)

[2. 创建一棵简单的链式二叉树](#2. 创建一棵简单的链式二叉树)

[2.2 二叉树的前、中、后序遍历](#2.2 二叉树的前、中、后序遍历)

[1. 前序遍历](#1. 前序遍历)

[2. 中序遍历](#2. 中序遍历)

3.后序遍历

[3. 求二叉树节点个数](#3. 求二叉树节点个数)

[3.1 求总节点个数](#3.1 求总节点个数)

[3.2 求叶子节点个数](#3.2 求叶子节点个数)

[3.3 求第K层节点个数](#3.3 求第K层节点个数)

源代码:


1.二叉树的链式存储结构

二叉树的链式存储结构是指,用链表来表示一棵二叉树,即用链来指示元素的逻辑关系。 通常的方法是链表中每个结点由三个区域组成,数据域和左右指针域,左右指针分别用来给出该结点左孩子和右孩子所在的链结点的存储地址 。

如图:

2. 二叉树链式结构的实现

2.1 创建一棵简单的链式二叉树

注意:相比之下,对普通的链式二叉树进行增删查改其实是非常麻烦的,上篇文章中,我们对堆进行插入和删除的目的是为了找出最大值或最小值,而对于普通的链式二叉树,与其这样漫无目的的进行增删查改,选择顺序表、链表的存储方式反而会更加优雅。所以对于链式二叉树,我们只学习耳熟能详的前序、中序、后序遍历。

1. 创建节点

 //创建链式二叉树节点
typedef int BTDataType;
typedef struct BinaryTreeNode
{
    BTDataType _data;//数据域
    struct BinaryTreeNode* _left;//左孩子
    struct BinaryTreeNode* _right;//右孩子
}BTNode;

2. 创建一棵简单的链式二叉树

BTNode* BuyNode(int x)
{
    BTNode* node = (BTNode*)malloc(sizeof(BTNode));
    if (node == NULL)
    {
        perror("malloc fail");
        exit(-1);
    }

    node->data = x;
    node->left = NULL;
    node->right = NULL;

    return node;
}

BTNode* CreatBinaryTree()
{
    BTNode* node1 = BuyNode(1);
    BTNode* node2 = BuyNode(2);
    BTNode* node3 = BuyNode(3);
    BTNode* node4 = BuyNode(4);
    BTNode* node5 = BuyNode(5);
    BTNode* node6 = BuyNode(6);

    node1->left = node2;
    node1->right = node4;
    node2->left = node3;
    node4->left = node5;
    node4->right = node6;
    return node1;
}

(注意:上述代码并不是创建二叉树的方式,只是为了下面方便遍历二叉树快速生成一棵二叉树)

2.2 二叉树的前、中、后序遍历

二叉树的遍历有:前序/中序/后序的递归结构遍历:

1. 前序遍历(Preorder Traversal 亦称先序遍历)------访问根结点的操作发生在遍历其左右子树之前(左右) (又称先根遍历-NLR)

2. 中序遍历(Inorder Traversal)------访问根结点的操作发生在遍历其左右子树之中(左右)(又称中根遍历-LNR)

3. 后序遍历(Postorder Traversal)------访问根结点的操作发生在遍历其左右子树之后(左右(又称后根遍历-LRN)

1. 前序遍历

//前序遍历
void PrevOrder(BTNode* root)
{
    if (root == NULL) {
        return;
    }
    printf("%d ", root->data);
    PrevOrder(root->left);
    PrevOrder(root->right);
}

2. 中序遍历

//中序遍历
void InOrder(BTNode* root)
{
    if (root == NULL) {
        return;
    }
    InOrder(root->left);
    printf("%d ", root->data);
    InOrder(root->right);
}

3.后序遍历

//后序遍历
void PostOrder(BTNode* root)
{
    if (root == NULL) {
        return;
    }
    PostOrder(root->left);
    PostOrder(root->right);
    printf("%d ", root->data);
}

3. 求二叉树节点个数

3.1 求总节点个数

//求节点个数
int TreeSize(BTNode* root)
{
    return root == NULL ? 0 : TreeSize(root->left) + TreeSize(root->right) + 1;
}

3.2 求叶子节点个数

//求叶子节点个数
int TreeLeafSize(BTNode* root)
{
    if (root == NULL) {
        return 0;
    }

    if (root->left == NULL && root->right == NULL) {
        return 1;
    }

    return TreeLeafSize(root->left) + TreeLeafSize(root->right);
}

3.3 求第K层节点个数

//求第K层的节点个数
int TreeKLevel(BTNode* root, int k)
{
    assert(k > 0);
    if (root == NULL) {
        return 0;
    }
    if (k == 1) {
        return 1;
    }
    return TreeKLevel(root->left, k - 1) + TreeKLevel(root->right, k - 1);
}

源代码:

#include <stdio.h>
#include <assert.h>

//创建链式二叉树节点
typedef int BTDataType;
typedef struct BinaryTreeNode
{
    BTDataType data;//数据域
    struct BinaryTreeNode* left;//左孩子
    struct BinaryTreeNode* right;//右孩子
}BTNode;

BTNode* BuyNode(int x)
{
    BTNode* node = (BTNode*)malloc(sizeof(BTNode));
    if (node == NULL)
    {
        perror("malloc fail");
        exit(-1);
    }

    node->data = x;
    node->left = NULL;
    node->right = NULL;

    return node;
}

BTNode* CreatBinaryTree()
{
    BTNode* node1 = BuyNode(1);
    BTNode* node2 = BuyNode(2);
    BTNode* node3 = BuyNode(3);
    BTNode* node4 = BuyNode(4);
    BTNode* node5 = BuyNode(5);
    BTNode* node6 = BuyNode(6);

    node1->left = node2;
    node1->right = node4;
    node2->left = node3;
    node4->left = node5;
    node4->right = node6;
    return node1;
}

//前序遍历
void PrevOrder(BTNode* root)
{
    if (root == NULL) {
        return;
    }
    printf("%d ", root->data);
    PrevOrder(root->left);
    PrevOrder(root->right);
}

//中序遍历
void InOrder(BTNode* root)
{
    if (root == NULL) {
        return;
    }
    InOrder(root->left);
    printf("%d ", root->data);
    InOrder(root->right);
}

//后序遍历
void PostOrder(BTNode* root)
{
    if (root == NULL) {
        return;
    }
    PostOrder(root->left);
    PostOrder(root->right);
    printf("%d ", root->data);
}

//二叉树的销毁
void TreeDestroy(BTNode* root)
{
    if (root == NULL) {
        return;
    }
    TreeDestroy(root->left);
    TreeDestroy(root->right);
    free(root);
    root = NULL;
}

//求节点个数
int TreeSize(BTNode* root)
{
    return root == NULL ? 0 : TreeSize(root->left) + TreeSize(root->right) + 1;
}

//求叶子节点个数
int TreeLeafSize(BTNode* root)
{
    if (root == NULL) {
        return 0;
    }

    if (root->left == NULL && root->right == NULL) {
        return 1;
    }

    return TreeLeafSize(root->left) + TreeLeafSize(root->right);
}

//求第K层的节点个数
int TreeKLevel(BTNode* root, int k)
{
    assert(k > 0);
    if (root == NULL) {
        return 0;
    }
    if (k == 1) {
        return 1;
    }
    return TreeKLevel(root->left, k - 1) + TreeKLevel(root->right, k - 1);
}

int main()
{
    printf("前序遍历为:");
    PrevOrder(CreatBinaryTree());
    printf("\n前序遍历为:");
    InOrder(CreatBinaryTree());
    printf("\n后序遍历为:");
    PostOrder(CreatBinaryTree());
    printf("\n节点个数为:%d",TreeSize(CreatBinaryTree()));
    printf("\n叶子节点个数为:%d", TreeLeafSize(CreatBinaryTree()));
    printf("\n第%d层节点个数为:%d", 2,TreeKLevel(CreatBinaryTree(),2));
    TreeDestroy(CreatBinaryTree());

	return 0;
}
相关推荐
别NULL3 小时前
机试题——疯长的草
数据结构·c++·算法
ZSYP-S4 小时前
Day 15:Spring 框架基础
java·开发语言·数据结构·后端·spring
唐叔在学习5 小时前
【唐叔学算法】第21天:超越比较-计数排序、桶排序与基数排序的Java实践及性能剖析
数据结构·算法·排序算法
ALISHENGYA5 小时前
全国青少年信息学奥林匹克竞赛(信奥赛)备考实战之分支结构(switch语句)
数据结构·算法
武昌库里写JAVA8 小时前
浅谈怎样系统的准备前端面试
数据结构·vue.js·spring boot·算法·课程设计
S-X-S8 小时前
代码随想录刷题-数组
数据结构·算法
l138494274518 小时前
每日一题(4)
java·数据结构·算法
kyrie_sakura8 小时前
c++数据结构算法复习基础--13--基数算法
数据结构·c++·算法
XWXnb68 小时前
数据结构:顺序表
数据结构·算法
橘颂TA9 小时前
【C++】数据结构 顺序表的实现(详解)
开发语言·数据结构·c++·算法