数据结构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;
}
相关推荐
历程里程碑5 分钟前
C++ 10 模板进阶:参数特化与分离编译解析
c语言·开发语言·数据结构·c++·算法
晨曦夜月1 小时前
笔试强训day5
数据结构·算法
H_z___1 小时前
Hz的计数问题总结
数据结构·算法
练习时长一年1 小时前
LeetCode热题100(搜索插入位置)
数据结构·算法·leetcode
凌睿马2 小时前
关于复杂数据结构从MySQL迁移到PostgreSQL的可行性
数据结构·数据库·mysql
Fine姐2 小时前
数据结构03——树
数据结构
ChoSeitaku2 小时前
NO17数据结构选择题考点|图
数据结构
断剑zou天涯2 小时前
【算法笔记】线段树SegmentTree
数据结构·笔记·算法
月明长歌3 小时前
【码道初阶】【牛客BM30】二叉搜索树与双向链表:java中以引用代指针操作的艺术与陷阱
java·数据结构·算法·leetcode·二叉树·笔试·字节跳动
小李小李快乐不已3 小时前
数组&&矩阵理论基础
数据结构·c++·线性代数·算法·leetcode·矩阵