数据结构的二叉树(c语言版)

news2024/10/4 11:27:54

一.二叉树的概念

                                             

1.二叉树的基本概念

二叉树是一种常见的树状数据结构,它由若干个节点组成,这些节点通过边连接起来。每个节点最多可以有两个子节点,分别称为左子节点和右子节点。

二叉树的特点是每个节点最多有两个子节点,而且左子节点和右子节点的位置是固定的。通常,左子节点小于或等于父节点,右子节点大于父节点,这种顺序被称为二叉搜索树。

二叉树的一个重要概念是根节点,它是树的起始节点,其他节点通过边与根节点相连。根节点没有父节点。另外,每个节点除了子节点的连接外,还可以有一个指向父节点的连接,这样就形成了一个双向连接的二叉树。

2.二叉树的特殊形态

二叉树还有一些常见的特殊形态,例如满二叉树,每个节点要么没有子节点,要么有两个子节点;完全二叉树,除了最后一层之外,其他层的节点都必须是满的,并且最后一层的节点都靠左排列。

3.二叉树的应用

二叉树可以用于许多应用,例如在计算机科学中常用的二叉搜索树可以用来高效地存储和查找数据。二叉树还可以用于表示表达式、文件系统、网络路由等各种问题的结构化表示。

4.二叉树的优缺点

优点:

  1. 快速的查找:在二叉搜索树中,由于节点的有序性,可以通过比较节点值的大小来快速定位目标节点,因此查找操作的时间复杂度为 O(log n),其中 n 是树中节点的数量。
  2. 快速的插入和删除:同样由于二叉搜索树的有序性,插入和删除操作只需要对数级别的操作,因此效率较高。
  3. 结构简单:相对于其他更复杂的树状数据结构,二叉树的结构相对简单,易于理解和实现。

缺点:

  1. 可能导致不平衡:如果插入的节点顺序不合适,或者是有序数据的插入顺序,可能会导致二叉树的不平衡,进而影响查找、插入和删除操作的效率,甚至退化为链表。
  2. 有序性限制:二叉搜索树的有序性要求限制了节点的插入和删除操作,需要保持树的有序性,这增加了对树的平衡性的要求,同时也限制了一些特殊操作的实现。
  3. 效率不稳定:在最坏的情况下,二叉搜索树的操作时间复杂度可能达到 O(n),其中 n 是树中节点的数量。这种情况通常出现在树的不平衡或有序性不合适的情况下。

二.二叉树的功能

二叉树作为一种常见的数据结构,具有以下功能:

  1. 查找:二叉搜索树(BST)是一种特殊的二叉树,它的左子节点的值小于等于父节点,右子节点的值大于等于父节点。这种有序性使得在BST中可以高效地进行查找操作。通过比较节点的值,可以快速确定目标节点的位置,从而实现快速查找。

  2. 插入和删除:在二叉树中插入和删除节点通常是相对容易的操作。对于BST,插入操作可以根据节点值的大小关系找到合适的位置进行插入。删除操作需要考虑节点的后继或前驱节点,以保持树的有序性。

  3. 遍历:二叉树的遍历包括三种基本方式:前序遍历、中序遍历和后序遍历。前序遍历先访问根节点,然后递归地遍历左子树和右子树;中序遍历先遍历左子树,然后访问根节点,最后遍历右子树;后序遍历先遍历左子树和右子树,最后访问根节点。

  4. 最值查找:通过遍历二叉树,可以找到树中的最小值和最大值。在二叉搜索树中,最小值一定在最左边的叶子节点,最大值一定在最右边的叶子节点。

  5. 平衡性检查和调整:二叉树的平衡性对于保持操作的效率非常重要。当二叉树不平衡时,可以进行相应的调整操作,如旋转、重建等,使得树保持平衡状态。

  6. 应用领域:二叉树可以用于解决各种问题,例如表达式求值、排序算法(如快速排序中的划分操作)、哈夫曼编码、文件系统的组织结构、数据库索引等。它们提供了一种结构化的方式来组织和操作数据。

三.二叉树的代码实现

                                

1.创建二叉树的结构体

struct TreeNode 是用来定义二叉树结点的结构体。它包含以下几个成员:

  1. val:存储结点的值。这个成员变量可以根据实际需要定义为任意类型,这里定义为 int 类型。

  2. left:指向当前结点的左子树的指针。它是一个指针类型,指向另一个 struct TreeNode 结构体,用于表示左子树。

  3. right:指向当前结点的右子树的指针。它也是一个指针类型,指向另一个 struct TreeNode 结构体,用于表示右子树。

通过这样的结构体定义,可以创建二叉树的结点,并通过 left 和 right 指针将这些结点连接起来,形成一个完整的二叉树数据结构。在二叉树的操作中,通过访问结点的 val 成员可以获取结点的值,通过访问 left 和 right 指针可以获取左子树和右子树的结点。这样的结构体定义提供了一种组织和访问二叉树的方式。

// 二叉树结点的定义
struct TreeNode {
int val;
struct TreeNode* left;
struct TreeNode* right;
};

2.创建新结点

createNode(int val):创建新结点

  1. 功能:创建一个新的二叉树结点,并初始化其值。
  2. 输入参数:val:要存储在新结点中的值。
  3. 返回值:指向新创建结点的指针。
// 创建新结点
struct TreeNode* createNode(int val) {
    struct TreeNode* newNode = (struct TreeNode*)malloc(sizeof(struct TreeNode));
    newNode->val = val;
    newNode->left = NULL;
    newNode->right = NULL;
    return newNode;
}

3.插入结点

insertNode(struct TreeNode* root, int val)

  1. 功能:将一个新的结点插入到二叉树中。
  2. 输入参数:val:要插入的值。
  3. root:指向二叉树的根结点的指针。
  4. 返回值:指向更新后的二叉树根结点的指针。运行原理:根据二叉搜索树的性质,如果要插入的值小于当前结点的值,则将其插入到左子树中;如果要插入的值大于等于当前结点的值,则将其插入到右子树中。递归地在合适的子树上调用插入函数,直到找到合适的位置插入新结点。
// 插入结点
struct TreeNode* insertNode(struct TreeNode* root, int val) {
    if (root == NULL) {
        return createNode(val);
    }
    if (val < root->val) {
        root->left = insertNode(root->left, val);
    } else {
        root->right = insertNode(root->right, val);
    }
    return root;
}

4.前序遍历 

​​​​​​​preorderTraversal(struct TreeNode* root)

  1. 功能:对二叉树进行前序遍历,即先访问根结点,然后递归地遍历左子树和右子树。
  2. 输入参数:root:指向二叉树根结点的指针。
  3. 返回值:无。
  4. 运行原理:递归地进行前序遍历,首先输出当前结点的值,然后先递归遍历左子树,再递归遍历右子树。
// 前序遍历
void preorderTraversal(struct TreeNode* root) {
    if (root != NULL) {
        printf("%d ", root->val);
        preorderTraversal(root->left);
        preorderTraversal(root->right);
    }
}

四.二叉树的源码呈现

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

// 二叉树结点的定义
struct TreeNode {
    int val;
    struct TreeNode* left;
    struct TreeNode* right;
};

// 创建新结点
struct TreeNode* createNode(int val) {
    struct TreeNode* newNode = (struct TreeNode*)malloc(sizeof(struct TreeNode));
    newNode->val = val;
    newNode->left = NULL;
    newNode->right = NULL;
    return newNode;
}

// 插入结点
struct TreeNode* insertNode(struct TreeNode* root, int val) {
    if (root == NULL) {
        return createNode(val);
    }
    if (val < root->val) {
        root->left = insertNode(root->left, val);
    } else {
        root->right = insertNode(root->right, val);
    }
    return root;
}

// 前序遍历
void preorderTraversal(struct TreeNode* root) {
    if (root != NULL) {
        printf("%d ", root->val);
        preorderTraversal(root->left);
        preorderTraversal(root->right);
    }
}

int main() {
    struct TreeNode* root = NULL;
    root = insertNode(root, 5);
    insertNode(root, 3);
    insertNode(root, 8);
    insertNode(root, 2);
    insertNode(root, 4);
    insertNode(root, 7);
    insertNode(root, 9);
    
    printf("Preorder traversal: ");
    preorderTraversal(root);
    
    return 0;
}

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

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

相关文章

如何根据列值选择DataFrame中的行?

在Python的数据分析库Pandas中&#xff0c;DataFrame是一种非常强大的数据结构&#xff0c;用于存储和操作表格数据。有时&#xff0c;我们可能需要根据某些列的特定值选择DataFrame中的行。本文将介绍如何使用Pandas进行此类操作&#xff0c;并提供一些实用的示例。 基本原理…

商场学习之微服务

前言 寒假前在新电脑上配置了java环境&#xff0c;maven仓库&#xff0c;node,js&#xff0c;navicat&#xff0c;MySQL&#xff0c;linux&#xff0c;vmware等环境&#xff0c;创建了6个mysql数据库&#xff0c;77张表。 如此多的表&#xff0c;字段&#xff0c;去手写基础…

常用网口操作

目录 网卡闪烁识别 查看光口或者电口 电口查看链接 如何去掉ip地址 网卡闪烁识别 装好系统后&#xff0c;不知道哪个名称对应哪个网卡&#xff0c;可以执行下面的命令。此时物理网卡会一闪一闪&#xff0c;按住ctrc&#xff0c;停止闪烁。这样就不担心找错网卡啦。也不用一…

【计算机网络篇】数据链路层(8)共享式以太网的退避算法和信道利用率

文章目录 &#x1f6f8;共享式以太网的退避算法&#x1f95a;截断二进制指数算法 &#x1f354;共享式以太网的信道利用率 &#x1f6f8;共享式以太网的退避算法 在使用CSMA/CD协议的共享总线以太网中&#xff0c;正在发送帧的站点一边发送帧一边检测碰撞&#xff0c;当检测到…

宝塔面板怎么解决nginx跨域问题

1.找到宝塔的nginx配置文件 宝塔有一点不同&#xff0c;nginx配置文件不在nginx的安装目录中&#xff0c;应当去/www/server/panel/vhost/nginx找到 2.添加你要跨域的地址 location /api {proxy_pass http://localhost:8080;proxy_set_header Host $host;proxy_set_header X-…

故障电弧产生的原因以及相关设备介绍-安科瑞 蒋静

1故障电弧的危害 故障电弧是指由于电气线路或设备中绝缘老化破损、电气连接松动、空气潮湿、电压电流急剧升高等原因引起空气击穿所导致的气体游离放电现象。故障电弧发生时&#xff0c;其中心温度可高达3000 ℃左右&#xff0c;并伴随有金属喷溅物&#xff0c;足以引燃任何可…

消息队列——Kafka

1、什么是消息队列&#xff0c;什么是Kafka&#xff1f; 我们通常说的消息队列&#xff0c;简称MQ&#xff08;Message Queue&#xff09;&#xff0c;它其实就指消息中间件&#xff0c;比较流行的开源消息中间件有&#xff1a;Kafka、RabbitMQ、RocketMQ等。今天我们要介绍的…

用balenaEtcher烧录ubuntu的iso文件都失败,所以选用了另一种烧录的软件Rufus,然后烧录成功了+安装ubuntu的坑

https://releases.ubuntu.com/bionic/进入网页下载ubuntu 选择烧录软件将下载的Ubuntu烧录到U盘中 之前用这个U盘烧录过一次&#xff0c;成功了&#xff0c;后来应该是U盘受损或者是什么其他原因使得用这个U盘总是烧录失败 换思路&#xff1a;由于一直使用balenaEtcher烧录ubu…

FileZilla一款免费开源的FTP软件,中文正式版 v3.67.0

01 软件介绍 FileZilla 客户端是一个高效且可信的跨平台应用程序&#xff0c;支持 FTP、 FTPS 和 SFTP 协议&#xff0c;其设计宗旨在于为用户提供一个功能丰富且直观的图形界面。此客户端的核心特性包括一个站点管理器&#xff0c;该管理器能有效地存储和管理用户连接详情及登…

Penpad 品牌升级为Pencils Protocol,提供用户“一鱼多吃”

Penpad是Scroll生态中最大综合平台之一&#xff0c;目前其得到了Scroll官方以及社区的支持&#xff0c;是Scroll包括成就系统、忠诚度积分等系列计划的首批合作伙伴&#xff0c;同时其也得到了OKX Wallet在内的行业伙伴的长期支持。 目前Penpad正在开启生态通证的Launch活动&am…

centos7同步银河麒麟服务器SP系列外网yum源包同步不完整问题

centos7同步银河麒麟服务器SP系列外网yum源包同步不完整问题 一 问题描述二 解决方法三 外网源配置步骤 一 问题描述 Red 7.7 x86架构同步银河麒麟服务器SP arm架构外网源的yum包不完整问题&#xff0c;yum repolist查看源里面有15000左右的包&#xff0c;使用reposync命令同步…

C++新特性-线程

主要内容 thread、condition、mutexatomicfunction、bind使用新特性实现线程池&#xff08;支持可变参数列表&#xff09;异常协程其他 1 C11多线程thread 重点&#xff1a; join和detach的使用场景thread构造函数参数绑定c函数绑定类函数线程封装基础类互斥锁mutexconditi…

鲜活很有感染力的女生图片_活力满满有生命力女生图片

鲜活很有感染力的女生图片_活力满满有生命力女生图片

Vue中CSS动态样式绑定与注意事项

vue中css使用动态变量_vue css变量 动态-CSDN博客 需求&#xff1a; vue使用el-select&#xff0c;下拉选择值时‘输入框’的背景图片就改变为对应所选项的背景图 分析 &#xff1a; 每次下拉选择&#xff0c;值发生变化&#xff0c;背景图与值一一对应绑定&#xff0c;为动态…

nuxt3.0+scrollreveal动画插件实现页面滚动加载动画效果

项目安装 npm install scrollreveal --save 在src下创建plugins文件夹&#xff0c;写入名为scrollreveal.client.ts的文件。 import { defineNuxtPlugin } from "#app"; import scrollReveal from scrollrevealexport default defineNuxtPlugin((nuxtApp) > {l…

STL中的优先级队列

目录 1.引言 2.简介 3.基本操作 4.实现原理 5.自定义优先级比较 6.相关题目 7.能特点 8.总结 1.引言 在C标准库中&#xff0c;优先级队列是一种非常有用的数据结构&#xff0c;它允许我们根据元素的优先级来对其进行排序和访问。这种数据结构在多种应用场景中都发挥着重…

WordPress插件Show IDs by Echo,后台显示文章、页面、分类、标签、媒体库、评论、用户的ID

WordPress的这款Show IDs by Echo插件&#xff0c;可以让我们设置是增加一列ID还是直接在“编辑 |快速编辑 |查看”操作后面增加ID&#xff0c;而且支持展示以下内容的ID&#xff1a; 文章页面类别标签评论自定义帖子类型自定义分类法用户媒体 Show IDs by Echo插件的安装及启…

ARM 交叉编译搭建SSH

一、源码下载 zlib&#xff1a;zlib-1.3.1.tar.xz openssl&#xff1a;openssl-0.9.8d.tar.gz openssh&#xff1a;openssh-4.6p1.tar.gz 二、交叉编译 1、zlib 编译参考这里 2、openssl tar -xf openssl-0.9.8d.tar.gz ./Configure --prefix/opt/ssh/openssl os/compile…

uabntu pcl spdlog安装位置和版本查看那

查看pcl默认安装版本 pkg-config --modversion pcl_io 查看pcl路径 pkg-config --libs pcl_io

Chrome的常用操作总结

Chrome的常用操作总结 最近的自己真的好忙啊,好久真好久没有写博客了,今天我就趁着周末的这段时间总结一下最近自己的用的Chrome浏览器常用的命令 不得不说: 就是特么的丝滑!吊打一切浏览器(不接受反驳哈哈哈)因为反驳我也不听嘻嘻 用好快捷键,就是事半功倍!!!重要的事儿说一遍…