数据结构——链式二叉树

news2024/11/21 2:23:18

🐶博主主页:@ᰔᩚ. 一怀明月ꦿ 

❤️‍🔥专栏系列:线性代数,C初学者入门训练,题解C,C的使用文章,「初学」C++

🔥座右铭:“不要等到什么都没有了,才下定决心去做”

🚀🚀🚀大家觉不错的话,就恳求大家点点关注,点点小爱心,指点指点🚀🚀🚀

目录

链式二叉树的实现 

链式二叉树的结构创建

链式二叉树节点的创建

链式二叉树的创建

链式二叉树的前序遍历

链式二叉树的中序遍历

链式二叉树的后序遍历

链式二叉树的节点个数

链式二叉树叶子节点个数

链式二叉树的高度

链式二叉树的k层节点个数

链式二叉树中寻找某个值

链式二叉树的层序遍历

链式二叉树的销毁

源码:


链式二叉树的实现 

链式二叉树的结构创建

typedef int BTDataType;
typedef struct BinarytreeNode
{
    struct BinarytreeNode* left;
    struct BinarytreeNode* right;
    BTDataType data;
}BTNode;

链式二叉树节点的创建

BTNode* BuyNodde(BTDataType x)
{
    BTNode* newnode=(BTNode*)malloc(sizeof(BTNode));
    if(newnode==NULL)
    {
        perror("malloc fail");
        return  NULL;
    }
    newnode->data=x;
    newnode->left=NULL;
    newnode->right=NULL;
    return newnode;
}

链式二叉树的创建

这里的二叉树是[1,2,4,3,null,5,6]

 

BTNode* CreatBinaryTree(void)
{
    BTNode* node1=BuyNodde(1);
    BTNode* node2=BuyNodde(2);
    BTNode* node3=BuyNodde(3);
    BTNode* node4=BuyNodde(4);
    BTNode* node5=BuyNodde(5);
    BTNode* node6=BuyNodde(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)
    {
        printf("N ");
        return;
    }
    printf("%d ",root->data);
    PrevOrder(root->left);
    PrevOrder(root->right);
}

链式二叉树的中序遍历

void InOrder(BTNode* root)
{
    if(root==NULL)
    {
        printf("N ");
        return;
    }
    PrevOrder(root->left);
    printf("%d ",root->data);
    PrevOrder(root->right);
}

链式二叉树的后序遍历

void PostOrder(BTNode* root)
{
    if(root==NULL)
    {
        printf("N ");
        return;
    }
    PostOrder(root->left);
    PostOrder(root->right);
    

链式二叉树的节点个数

int BinaryTreeSize(BTNode* root)
{
    if(root==NULL)
        return 0;
    return BinaryTreeSize(root->left)+BinaryTreeSize(root->right)+1;
}

链式二叉树叶子节点个数

int BinaryTreeleafSize(BTNode* root)
{
    if(root==NULL)
        return 0;
    if(root->left==NULL&&root->right==NULL)
        return 1;
    return BinaryTreeleafSize(root->left)+BinaryTreeSize(root->right);
}

链式二叉树的高度

int BinaryTreeHeight(BTNode* root)
{
    if(root==NULL)
        return 0;
    int ret1=BinaryTreeSize(root->left);
    int ret2=BinaryTreeSize(root->right);
    return ret1>ret2?ret1+1:ret2+1;
}

链式二叉树的k层节点个数

int KLevelBinaryTreeSize(BTNode* root,int k)
{
    if(root==NULL)
        return 0;
    if(k==1)
        return 1;
    return KLevelBinaryTreeSize(root->left,k-1)+KLevelBinaryTreeSize(root->right,k-1);
}

链式二叉树中寻找某个值

BTNode* BinaryTreeFind(BTNode* root,int x)
{
    if(root==NULL)
        return NULL;
    if(root->data==x)
        return root;
    BTNode* ret1=BinaryTreeFind(root->left, x);
    if(ret1)
        return ret1;
    BTNode* ret2=BinaryTreeFind(root->right, x);
    if(ret2)
        return ret2;
    return NULL;
}

链式二叉树的层序遍历

链式二叉树的层序遍历需要借助队列的性质,所以需要使用队列的源码

void LevelOreder(BTNode* root)
{
    Queue q;
    QueueInit(&q);
    if(root)
        QueuePush(&q, root);
    while(!QueueEmpty(&q))
    {
        BTNode* front=QueueFront(&q);
        QueuePop(&q);
        printf("%d ",front->data);
        if(front->left)
            QueuePush(&q, front->left);
        if(front->right)
            QueuePush(&q, front->right);
    }
    printf("\n");
}

链式二叉树的销毁

void DestroyBinaryTree(BTNode* root)
{
    if(root==NULL)
        return;
    DestroyBinaryTree(root->left);
    DestroyBinaryTree(root->right);
    free(root);
}

源码:

#ifndef Queue_h
#define Queue_h

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

#endif /* Queue_h */

typedef struct BinarytreeNode* QDataType;
typedef struct QueueNode
{
    struct QueueNode* next;
    QDataType data;
}QNode;

typedef struct Queue
{
    QNode* phead;
    QNode* ptail;
    int size;
}Queue;

//队列的初始化
void QueueInit(Queue* pq);
//队列的销毁
void QueueDestroy(Queue* pq);
//进队列(尾插)
void QueuePush(Queue* pq,QDataType x);
//出队列(头删)
void QueuePop(Queue* pq);
//队头数据
QDataType QueueFront(Queue* pq);
//队尾数据(伏笔)
QDataType QueueBack(Queue* pq);
//返回队列的数据个数
int QueueSize(Queue* pq);
//判断队列是否为空
bool QueueEmpty(Queue* pq);



void QueueInit(Queue* pq)
{
    assert(pq);
    pq->phead=NULL;
    pq->ptail=NULL;
    pq->size=0;
}
void QueueDestroy(Queue* pq)
{
    assert(pq);
    QNode* cur=pq->phead;
    while(cur)
    {
        QNode* next=cur->next;
        free(cur);
        cur=next;
    }
    pq->phead=pq->ptail=NULL;
    pq->size=0;
}
void QueuePush(Queue* pq,QDataType x)
{
    assert(pq);
    QNode* newnode=(QNode*)malloc(sizeof(QNode));
    if(newnode==NULL)
    {
        perror("malloc fail\n");
        return;
    }
    newnode->data=x;
    newnode->next=NULL;
    if(pq->phead==NULL)//当链表为空的时候
    {
        assert(!pq->ptail);//当链表为空的时候,pq->ptail也是空
        pq->phead=newnode;
        pq->ptail=newnode;
    }
    //链表不为空的时候进队列插入数据(尾插)
    else
    {
        pq->ptail->next=newnode;
        pq->ptail=newnode;
    }
    pq->size++;
}
void QueuePop(Queue* pq)
{
    assert(pq);
    assert(!QueueEmpty(pq));//判断队列是否为空,断言为真程序继续
    //一个节点的时候
    //if(pq->phead->next==NULL)
    if(pq->phead==pq->ptail)
    {
        free(pq->phead);
        pq->phead=NULL;
        pq->ptail=NULL;
    }
    //多个节点的时候
    else
    {
        //相当于头删
        QNode* next=pq->phead->next;
        free(pq->phead);
        pq->phead=next;
    }
    pq->size--;
}
QDataType QueueFront(Queue* pq)
{
    assert(pq);
    assert(!QueueEmpty(pq));//判断队列是否为空,断言为真程序继续
    return pq->phead->data;
}
QDataType QueueBack(Queue* pq)
{
    assert(pq);
    assert(!QueueEmpty(pq));
    return pq->ptail->data;
}
bool QueueEmpty(Queue* pq)
{
    assert(pq);
    return pq->phead==NULL;
}
int QueueSize(Queue* pq)
{
    assert(pq);
    return pq->size;
}


typedef int BTDataType;
typedef struct BinarytreeNode
{
    struct BinarytreeNode* left;
    struct BinarytreeNode* right;
    BTDataType data;
}BTNode;
BTNode* BuyNodde(BTDataType x)
{
    BTNode* newnode=(BTNode*)malloc(sizeof(BTNode));
    if(newnode==NULL)
    {
        perror("malloc fail");
        return  NULL;
    }
    newnode->data=x;
    newnode->left=NULL;
    newnode->right=NULL;
    return newnode;
}
BTNode* CreatBinaryTree(void)
{
    BTNode* node1=BuyNodde(1);
    BTNode* node2=BuyNodde(2);
    BTNode* node3=BuyNodde(3);
    BTNode* node4=BuyNodde(4);
    BTNode* node5=BuyNodde(5);
    BTNode* node6=BuyNodde(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)
    {
        printf("N ");
        return;
    }
    printf("%d ",root->data);
    PrevOrder(root->left);
    PrevOrder(root->right);
}
//中序遍历
void InOrder(BTNode* root)
{
    if(root==NULL)
    {
        printf("N ");
        return;
    }
    PrevOrder(root->left);
    printf("%d ",root->data);
    PrevOrder(root->right);
}
//后序遍历
void PostOrder(BTNode* root)
{
    if(root==NULL)
    {
        printf("N ");
        return;
    }
    PostOrder(root->left);
    PostOrder(root->right);
    printf("%d ",root->data);
}

//求二叉树的个数
int BinaryTreeSize(BTNode* root)
{
    if(root==NULL)
        return 0;
    return BinaryTreeSize(root->left)+BinaryTreeSize(root->right)+1;
}

//求二叉树的叶子节点

int BinaryTreeleafSize(BTNode* root)
{
    if(root==NULL)
        return 0;
    if(root->left==NULL&&root->right==NULL)
        return 1;
    return BinaryTreeleafSize(root->left)+BinaryTreeSize(root->right);
}

//求二叉树的高度

int BinaryTreeHeight(BTNode* root)
{
    if(root==NULL)
        return 0;
    int ret1=BinaryTreeSize(root->left);
    int ret2=BinaryTreeSize(root->right);
    return ret1>ret2?ret1+1:ret2+1;
}

//求树的k层节点
int KLevelBinaryTreeSize(BTNode* root,int k)
{
    if(root==NULL)
        return 0;
    if(k==1)
        return 1;
    return KLevelBinaryTreeSize(root->left,k-1)+KLevelBinaryTreeSize(root->right,k-1);
}

//树中节点的寻找,找到返回这个节点
BTNode* BinaryTreeFind(BTNode* root,int x)
{
    if(root==NULL)
        return NULL;
    if(root->data==x)
        return root;
    BTNode* ret1=BinaryTreeFind(root->left, x);
    if(ret1)
        return ret1;
    BTNode* ret2=BinaryTreeFind(root->right, x);
    if(ret2)
        return ret2;
    return NULL;
}
//层序遍历
void LevelOreder(BTNode* root)
{
    Queue q;
    QueueInit(&q);
    if(root)
        QueuePush(&q, root);
    while(!QueueEmpty(&q))
    {
        BTNode* front=QueueFront(&q);
        QueuePop(&q);
        printf("%d ",front->data);
        if(front->left)
            QueuePush(&q, front->left);
        if(front->right)
            QueuePush(&q, front->right);
    }
    printf("\n");
}

//二叉树的销毁
void DestroyBinaryTree(BTNode* root)
{
    if(root==NULL)
        return;
    DestroyBinaryTree(root->left);
    DestroyBinaryTree(root->right);
    free(root);
}
int main()
{
    //创建链式二叉树
    BTNode* root=NULL;
    root=CreatBinaryTree();
    
    printf("前序遍历:");
    PrevOrder(root);
    printf("\n");
    
    printf("中序遍历:");
    InOrder(root);
    printf("\n");
    
    printf("后序遍历:");
    PostOrder(root);
    printf("\n");
    
    printf("树的节点个数:%d\n",BinaryTreeSize(root));
    
    printf("树的叶子节点的个数:%d\n",BinaryTreeleafSize(root));
    
    printf("树的高度为:%d\n",BinaryTreeHeight(root));
    
    printf("树的第三层的节点个数:%d\n",KLevelBinaryTreeSize(root, 3));
    
    printf("树中的数值5:%d\n",BinaryTreeFind(root, 5)->data);
    
    printf("层序遍历:\n");
    LevelOreder(root);
    
    return 0;
}

🌸🌸🌸如果大家还有不懂或者建议都可以发在评论区,我们共同探讨,共同学习,共同进步。谢谢大家! 🌸🌸🌸  

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/590909.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【云原生|探索 Kubernetes 系列 7】探究 Pod 有什么用,为什么需要它

前言 大家好&#xff0c;我是秋意零。 前一篇&#xff0c;我们介绍了如何从 0 到 1 搭建 Kubernetes 集群。现在我们可以正式了解&#xff0c;Kubernetes 核心特征了。 今天我们来探究 Pod&#xff0c;为什么需要 Pod&#xff1f; &#x1f47f; 简介 &#x1f3e0; 个人主页…

编程示例:求排列的逆,反序表,以及从反序表计算排列

编程示例&#xff1a;求排列的逆&#xff0c;反序表&#xff0c;以及从反序表计算排列 计算机程序设计艺术的第三卷 第五章排序中&#xff0c;第5.1.1节中 提到了排列的反序&#xff0c;反序表&#xff0c;逆的概念。 首先&#xff0c;简单地介绍一下这两个概念。例如一个排列…

RK3566 ALC5616录音调试

1.硬件原理图 MIC_P&#xff0c;MIC_N&#xff1a;mic输入。 I2S&#xff1a;总共有5根线&#xff08;这里不是指 i2s 标准接口&#xff09;&#xff1a;两根音频数据线&#xff08;输入/输出&#xff09;、三根时钟线 其中&#xff1a; I2S_LRCK 是指示当前数据线传输的是左声…

【网络】UDP的应用场景

文章目录 翻译功能命令行解析网络聊天室UDP之Windows与Linux 翻译功能 我们写的UDP服务端并不是只接收到数据就完了&#xff0c;还需要进行处理任务。 我们可以在服务端udpServer.hpp中设置一个回调函数 _callback&#xff0c;具体的逻辑通过udpServer.cc中由外部进行传入 代…

Windows系统安全基线

文章目录 前言一、安全基线概述1.操作系统安全基线 二、系统账户安全1.控制密码安全2.密码策略3.账户锁定策略例&#xff1a;密码策略应用例&#xff1a;账户锁定策略应用 三、本地策略1.审核策略2.用户权限分配3.安全选项配置例&#xff1a;审核策略应用例&#xff1a;用户权限…

软件测试理论----软件测试六大测试类型

1、功能测试&#xff1a;关注功能是否正确 常见的关注点 1&#xff09;是否有不正确或者遗漏的功能 2&#xff09;是否满足用户的需求和系统隐藏的需求 3&#xff09;输入能否正确接收&#xff0c;能否输出正确结果 2、可用性测试&#xff1a;关注产品是否好用 常见的关注点…

03灰度变换与空间滤波

文章目录 3灰度变换与空间滤波3.1背景知识3.1.1灰度变换和空间滤波基础 3.2一些基本的灰度变换函数3.2.1图像反转3.2.2对数变换3.2.3幂律&#xff08;伽马&#xff09;变换3.2.4分段线性变换函数 3.3直方图处理3.3.1直方图均衡3.3.2直方图匹配&#xff08;规定化&#xff09;3.…

webpack配置排除打包

webpack配置排除打包 思路 打包时&#xff0c;不要把类似于element-ui第三方的这些包打进来 从网络上&#xff0c;通过url地址直接引入这些包 操作 &#xff08;1&#xff09;先找到 vue.config.js&#xff0c; 添加 externals 项&#xff0c;具体如下&#xff1a; config…

【JavaSE】异常 (异常抛出 异常的捕获 异常声明throws try-catch捕获并处理 finally 自定义异常)

文章目录 异常概念异常结构 异常处理异常抛出异常的捕获异常声明throwstry-catch捕获并处理finally 自定义异常 异常 概念 在程序运行过程中&#xff0c;可能会存在一些奇怪问题&#xff0c;例如&#xff1a;网络不畅&#xff0c;内存报警等等。所以在java中&#xff0c;将程…

NLP:文本预处理总览

1 用n-gram语言模型过滤低质量内容 使用n-gram语言模型对文本进行评估&#xff0c;从而过滤掉低质量的内容。具体来说&#xff0c;可以通过以下步骤进行&#xff1a; 1 将文本分成n-gram序列&#xff0c;其中n是一个整数。 2 使用已经训练好的n-gram语言模型对每个n-gram序列…

面试4年经验的测试员,开口就要25k,却连基础都不会,还不如招应届生!

公司前段缺人&#xff0c;也面了不少测试&#xff0c;结果竟然没有一个合适的。一开始瞄准的就是中级的水准&#xff0c;也没指望来大牛&#xff0c;提供的薪资在10-25k&#xff0c;面试的人很多&#xff0c;但平均水平很让人失望。看简历很多都是4年工作经验&#xff0c;但面试…

冒泡排序实现(c++)

目录 冒泡排序简介&#xff1a; 冒泡排序原理&#xff1a; 动图演示&#xff1a; 代码实现&#xff1a; 冒泡排序简介&#xff1a; 冒泡排序&#xff0c;最优时间复杂度O(N)&#xff0c;平均时间复杂度O(N^2)&#xff0c;最差空间复杂度O(N)&#xff0c;平均时间复杂度O(1)…

基于ISIC数据集的皮肤病黑色素瘤分类研究与实现

摘要&#xff1a; 本项目利用残差网络结构对皮肤病图像进行分类&#xff0c;提高了皮肤病诊断的准确度。并结合Flask框架实现一个简单的Web应用&#xff0c;用户可以上传图像文件&#xff0c;经过预处理最后将预测结果显示在界面上。通过该系统&#xff0c;医生和研究人员可以快…

STM32单片机(三)第三节:GPIO输入

❤️ 专栏简介&#xff1a;本专栏记录了从零学习单片机的过程&#xff0c;其中包括51单片机和STM32单片机两部分&#xff1b;建议先学习51单片机&#xff0c;其是STM32等高级单片机的基础&#xff1b;这样再学习STM32时才能融会贯通。 ☀️ 专栏适用人群 &#xff1a;适用于想要…

【计算机网络】 1.4——计算机网络的性能指标(重要!含计算)

计算机网络的性能指标 速率 数据量单位 bit Byte KB(2^10B) MB GB TB 数据量比较特别&#xff0c;使用2进制 kB210B而不是103&#xff0c;注意计算题 比特率/数据率单位 bpskb/s(10^3bps) Mb/s Gb/s Tb/s 带宽 *带宽在模拟信号系统中的意义 信号所包含的各种不同频率成…

WebSocket的那些事(4-Spring中的STOMP支持详解)

目录 一、序言二、Spring对STOMP支持的相关注解三、聊天Demo代码示例1、前端页面chat.html2、相关实体(1) 请求消息参数(2) 响应消息内容(3) 自定义认证用户信息 3、自定义用户认证拦截器4、WebSocket消息代理配置5、ChatController控制器 四、测试用例1、指定用户定时消息推送…

【实用篇】SpringCloud02

文章目录 SpringCloud020.学习目标1.Nacos配置管理1.1.统一配置管理1.1.1.在nacos中添加配置文件1.1.2.从微服务拉取配置 1.2.配置热更新1.2.1.方式一1.2.2.方式二 1.3.配置共享1&#xff09;添加一个环境共享配置2&#xff09;在user-service中读取共享配置3&#xff09;运行两…

TCP通信(复习)

目录 TCP通信实现过程 1、socket函数与通信域 socket函数 参 数 bind函数 与 通信结构体 bind函数 参数 通信地址族与同届结构体 通用地址族结构体 IPV4地址族结构体 listen函数与accept函数 listen函数 accept函数 参 数 作 用 要实现进程间的通信必备&#xff1…

Map、Set和哈希表(数据结构系列14)

目录 前言&#xff1a; 1.搜索树 1.1概念 1.2插入 1.3查找 1.4删除 1.5二叉搜索树整体代码展示 2. Map和Set的讲解 2.1 Map的说明 2.1.1Map的方法 2.2 Set 的说明 2.2.1Set的方法 3.哈希表 3.1哈希表的概念 3.2哈希冲突 3.3冲突的避免 3.4哈希冲突的解决 3.4…

企业物资管理系统的设计与实现(ASP.NET,SQL)

论文阐述了企业物资管理系统的设计与实现&#xff0c;并对该系统的需求分析及系统需要实现的设计方法作了介绍。该系统的基本功能包括用户登录&#xff0c;修改密码&#xff0c;物资的基本信息管理&#xff0c;出入库和损坏的管理已经综合查询等功能。 4.1 用户登录模块的实现 …