【数据结构】(C语言):二叉搜索树

二叉搜索树:

  • 树不是线性的,是层级结构。
  • 基本单位是节点,每个节点最多2个子节点。
  • 有序。每个节点,其左子节点都比它小,其右子节点都比它大。
  • 每个子树都是一个二叉搜索树。每个节点及其所有子节点形成子树。
  • 可以是空树。

添加元素:从根节点开始,比对数值。若比它小,往左子树比对;若比它大,往右子树比对;直到找到为空,则为新元素的位置。

删除元素:

  1. 若删除的节点为叶子节点(即无子节点),则直接删除。
  2. 若删除的节点只有左子节点,则左子节点替代删除节点。
  3. 若删除的节点只有右子节点,则右子节点替代删除节点。
  4. 若删除的节点既有左子节点又有右子节点,则找到直接前驱(即删除节点的左子树中的最大值,即删除节点的左子节点的最右节点),直接前驱的值替代删除节点的值,删除直接前驱节点。

遍历元素:(可使用递归)

  • 前序遍历(顺序:根节点、左子节点、右子节点)。
  • 中序遍历(顺序:左子节点、根节点、右子节点)。
  • 后序遍历(顺序:左子节点、右子节点、根节点)。

查找元素:从根节点开始,比对数值。若比它小,往左子树查找;若比它大,往右子树查找;直到找到该元素,则返回1(true),若没有,则返回0(false)。


C语言实现:(使用链表实现)

 创建结构体数据类型(记录二叉搜索树的根节点和数据个数):

typedef struct Link
{LinkNode *root;			// 根节点int length;			    // 统计有多少数据
} LinkBST;                  // 别名

创建二叉搜索树,并初始化:

LinkBST bst;
bst.root = NULL;    // 根节点,初始化为NULL
bst.length = 0;     // 数据个数,初始化为0

创建节点(结构体数据类型),并创建具体节点实例的函数:

// 节点(结构体数据类型)
typedef struct Node
{int value;			    // 数据类型为整型struct Node *left;		// 左子节点struct Node *right;		// 右子节点
}LinkNode;                  // 别名
// 函数:创建节点
LinkNode *createNode(int data)
{LinkNode *node = (LinkNode *)malloc(sizeof(LinkNode));    // 分配节点内存空间if(node == NULL){perror("Memory allocation failed");exit(-1);}node->value = data;    // 数据node->left = NULL;     // 左子节点,初始化为NULLnode->right = NULL;    // 右子节点,初始化为NULLreturn node;
}

添加元素:

void add(LinkBST *bst, int data)	// add element
{// 函数:往二叉搜索树中添加元素	LinkNode *addNode(LinkNode *node, int data){if(node == NULL){LinkNode *newnode = createNode(data);node = newnode;bst->length++;    // 每添加一个元素,length+1return node;}if(data < node->value) node->left = addNode(node->left, data);else if(data > node->value) node->right = addNode(node->right, data);return node;}// 从根节点开始比对,root指针始终指向二叉搜索树的根节点bst->root = addNode(bst->root, data);	
}

删除元素:

void delete(LinkBST *bst, int data)	// delete element
{// 函数:删除节点	LinkNode *del(LinkNode *node){   // 若只有右子节点,则右子节点替代删除节点if(node->left == NULL){bst->length--;        // 每删除一个元素,length-1return node->right;}// 若只有左子节点,则左子节点替代删除节点else if(node->right == NULL){bst->length--;        // 每删除一个元素,length-1return node->left;}// 左右子节点都有,则直接前驱(左子节点的最右节点)替代删除节点,并删除直接前驱else if(node->left && node->right){LinkNode *tmp = node, *cur = node->left;while(cur->right){tmp = cur;cur = cur->right;}node->value = cur->value;if(tmp != node) tmp->right = cur->left;else tmp->left = cur->left;bst->length--;        // 每删除一个元素,length-1return node;}}// 函数:找到将要删除的节点LinkNode *delNode(LinkNode *node, int data){if(node == NULL) return node;if(data == node->value) node = del(node);else if(data < node->value) node->left = delNode(node->left, data);else if(data > node->value) node->right = delNode(node->right, data);return node;}	// 从根节点开始比对。root指针始终指向二叉搜索树的根节点bst->root = delNode(bst->root, data);	
}

遍历元素:(使用递归)

// 前序遍历(根,左,右)
void pretravel(LinkNode *node)
{if(node == NULL) return ;printf("%d  ", node->value);pretravel(node->left);pretravel(node->right);
}
// 中序遍历(左,根,右)
void midtravel(LinkNode *node)
{if(node == NULL) return ;midtravel(node->left);printf("%d  ", node->value);midtravel(node->right);
}
// 后序遍历(左,右,根)
void posttravel(LinkNode *node)
{if(node == NULL) return ;posttravel(node->left);posttravel(node->right);printf("%d  ", node->value);
}

查找元素:

找到元素,返回1(true);没找到,返回0(false)。

int find(LinkNode *node, int data)
{if(node ==  NULL) return 0;if(data == node->value) return 1;if(data < node->value) find(node->left, data);else if(data > node->value) find(node->right, data);	
}


完整代码:(bst.c)

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>/* structure */
typedef struct Node			// linkedlist node
{int value;			// value type is integerstruct Node *left;		// left child nodestruct Node *right;		// right child node
}LinkNode;typedef struct Link			// binary search tree
{LinkNode *root;			// root node of the treeint length;			// the number of the tree
} LinkBST;/* function prototype */
void add(LinkBST *, int);		// add element to the tree
void delete(LinkBST *, int);		// delete element from the tree
void pretravel(LinkNode *);		// show element one by one,(root,left,right)
void midtravel(LinkNode *);		// show element one by one,(left,root,right)
void posttravel(LinkNode *);		// show element one by one,(left,right,root)
int find(LinkNode *, int);		// if find data,return 1(true),or return 0(false)/* main function */
int main(void)
{// create binary search tree and initializationLinkBST bst;bst.root = NULL;bst.length = 0;printf("isempty(1:true, 0:false): %d, length is %d\n",  bst.root==NULL, bst.length);add(&bst, 15);add(&bst, 8);add(&bst, 23);add(&bst, 10);add(&bst, 12);add(&bst, 19);add(&bst, 6);printf("isempty(1:true, 0:false): %d, length is %d\n",  bst.root==NULL, bst.length);printf("midtravel: ");midtravel(bst.root);printf("\n");printf("pretravel: ");pretravel(bst.root);printf("\n");printf("posttravel: ");posttravel(bst.root);printf("\n");printf("find 10 (1:true, 0:false): %d\n", find(bst.root, 10));printf("find 9 (1:true, 0:false): %d\n", find(bst.root, 9));delete(&bst, 23);delete(&bst, 15);delete(&bst, 6);printf("isempty(1:true, 0:false): %d, length is %d\n",  bst.root==NULL, bst.length);printf("midtravel: ");midtravel(bst.root);printf("\n");printf("pretravel: ");pretravel(bst.root);printf("\n");printf("posttravel: ");posttravel(bst.root);printf("\n");return 0;
}/* subfunction */
LinkNode *createNode(int data)		// create a node
{LinkNode *node = (LinkNode *)malloc(sizeof(LinkNode));if(node == NULL){perror("Memory allocation failed");exit(-1);}node->value = data;node->left = NULL;node->right = NULL;return node;
}void add(LinkBST *bst, int data)	// add element
{// subfunction(recursion): add element to the binary search tree	LinkNode *addNode(LinkNode *node, int data){if(node == NULL){LinkNode *newnode = createNode(data);node = newnode;bst->length++;return node;}if(data < node->value) node->left = addNode(node->left, data);else if(data > node->value) node->right = addNode(node->right, data);return node;}// root node receive the resultbst->root = addNode(bst->root, data);	
}void delete(LinkBST *bst, int data)	// delete element
{// subfunction(recursion): delete element from the binary search tree	LinkNode *del(LinkNode *node){if(node->left == NULL){bst->length--;return node->right;}else if(node->right == NULL){bst->length--;return node->left;}else if(node->left && node->right){LinkNode *tmp = node, *cur = node->left;while(cur->right){tmp = cur;cur = cur->right;}node->value = cur->value;if(tmp != node) tmp->right = cur->left;else tmp->left = cur->left;bst->length--;return node;}}// subfunction: find delete node,return nodeLinkNode *delNode(LinkNode *node, int data){if(node == NULL) return node;if(data == node->value) node = del(node);else if(data < node->value) node->left = delNode(node->left, data);else if(data > node->value) node->right = delNode(node->right, data);return node;}	// root node receive the resultbst->root = delNode(bst->root, data);	
}void pretravel(LinkNode *node)		// show element one by one,(root,left,right)
{if(node == NULL) return ;printf("%d  ", node->value);pretravel(node->left);pretravel(node->right);
}void midtravel(LinkNode *node)		// show element one by one,(left,root,right)
{if(node == NULL) return ;midtravel(node->left);printf("%d  ", node->value);midtravel(node->right);
}void posttravel(LinkNode *node)		// show element one by one,(left,right,root)
{if(node == NULL) return ;posttravel(node->left);posttravel(node->right);printf("%d  ", node->value);
}int find(LinkNode *node, int data)	// if find data,return 1(true),or return 0(false)
{if(node ==  NULL) return 0;if(data == node->value) return 1;if(data < node->value) find(node->left, data);else if(data > node->value) find(node->right, data);	
}

编译链接: gcc -o bst bst.c

执行可执行文件: ./bst

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

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

相关文章

PointNet++论文导读

PointNet论文导读 主要改进网络结构&#xff1a;非均匀采样下的特征学习的鲁棒性利用点特征传播处理数据集分割 论文链接:https://arxiv.org/abs/1612.00593 主要改进 PointNet的基本思想是学习每个点的空间编码&#xff0c;然后将所有单个点的特征聚合成一个全局点云标签&am…

Apache Ranger 2.4.0 集成hadoop 3.X(Kerbos)

1、安装Ranger 参照上一个文章 2、修改配置 把各种plugin转到统一目录&#xff08;源码编译的target目录下拷贝过来&#xff09;&#xff0c;比如 tar zxvf ranger-2.4.0-hdfs-plugin.tar.gz tar zxvf ranger-2.4.0-hdfs-plugin.tar.gz vim install.properties POLICY_MG…

论文阅读:Simple and Efficient Heterogeneous Graph Neural Network

Yang, Xiaocheng, Mingyu Yan, Shirui Pan, Xiaochun Ye and Dongrui Fan. “Simple and Efficient Heterogeneous Graph Neural Network.” AAAI Conference on Artificial Intelligence (2022). 论文地址&#xff1a;[PDF] Simple and Efficient Heterogeneous Graph Neural…

Bytebase 2.20.0 - 支持为工单事件配置飞书个人通知

&#x1f680; 新功能 支持 Databricks。支持 SQL Server 的 TLS/SSL 连接。支持为工单事件配置飞书个人通知。支持限制用户注册的邮箱域名。 &#x1f514; 重大变更 将分类分级同步设置从数据库配置移至工作空间的全局配置。 SQL 编辑器只读模式下只允许执行 Redis 的只读…

着色器预热?为什么 Flutter 需要?为什么原生 App 不需要?那 Compose 呢?Impeller 呢?

依旧是来自网友的问题&#xff0c;这个问题在一定程度上还是很意思的&#xff0c;因为大家可能会想&#xff0c;Flutter 使用 skia&#xff0c;原生 App 是用 skia &#xff0c;那为什么在 Flutter 上会有着色器预热&#xff08;Shader Warmup&#xff09;这样的说法&#xff1…

论文1--ViT

Vision Transformer (ViT) 论文&#xff1a;https://arxiv.org/abs/2010.11929代码&#xff1a;GitHub - google-research/vision_transformer 1.背景 &#xff08;1&#xff09;transformer在NLP很强&#xff0c;但在CV的应用还非常有限&#xff0c;在此之前只有目标检测中…

【轻量化】YOLOv8 更换骨干网络之 MobileNetv4 | 《号称最强轻量化网络》

论文地址:https://arxiv.org/pdf/2404.10518 代码地址:https://github.com/tensorflow/models/blob/master/official/vision/modeling/backbones/mobilenet.py 文章速览 文章摘要 MobileNetV4引入了一个名为Universal Inverted Bottleneck (UIB) 的新搜索模块,这个模块融合…

民用无人机企业招标投标需要资质证书详解

一、基础资质 在民用无人机企业的招标投标过程中&#xff0c;基础资质是首要考虑的因素。这些资质通常包括企业注册资质、税务登记证、组织机构代码证等。 1.1 企业注册资质 企业应具备合法的注册资质&#xff0c;即营业执照。该执照应包含企业名称、注册地址、法定代表人、…

idea集成uglifycss压缩混淆css

Uglifycss介绍 https://www.npmjs.com/package/uglifycss 命令行 $ uglifycss [options] [filename] [...] > output 选项&#xff1a; --max-line-len n每个字符添加一个换行符&#xff08;大约&#xff09;; 表示无换行符&#xff0c;并且是默认值n0 --expand-vars扩…

考研数学|《660》一刷的错题,二刷还错,怎么能做对?

660这本习题册的难度不小&#xff0c;它不仅考察你对知识点的掌握程度&#xff0c;还考察你的解题思路和方法。很多题目会同时涉及多个知识点&#xff0c;而且对概念的挖掘非常深入&#xff0c;甚至在一些容易出错的地方还设置了陷阱&#xff0c;这对于基础不扎实的同学来说&am…

商城积分系统的代码实现(下)-- 积分订单的退款与结算

一、接着上文 用户在消耗积分的时候&#xff0c;需要根据一定的逻辑&#xff0c;除了扣减账户的当前余额&#xff0c;还需要依次消费积分订单的余额。 private void updatePointsOrderByUse(Integer schoolId, Long userId, String pointsType, int usingPoints) {List<Po…

Web攻防基础篇-文件上传漏洞

文件解析安全问题上&#xff0c;格式解析是一对一的&#xff08;不能jpg解析php&#xff09;&#xff0c;换句话来说有解析错误配置或后缀解析漏洞时才能实现格式差异解析。 文件上传漏洞 程序或系统未对上传文件作全面的限制&#xff0c;导致用户可以上传某些非法文件&#…

Jetson系列机载电脑创建热点模式配置方法

Jetson nano为例—— 创建热点模式配置方法 1.1、新建一个 WiFi 在屏幕右上角找到网络图标&#xff0c;点击后选择“Edit Connections”选项&#xff0c;进入选择网络连接页面&#xff0c;然后点击左下角加号&#xff0c;新建一个连接&#xff0c;类型选择 WiFi 后点击 “cre…

在TkinterGUI界面显示WIFI网络(ESP32s3)摄像头画面

本实验结合了之前写过的两篇文章Python调用摄像头&#xff0c;实时显示视频在Tkinter界面以及ESP32 S3搭载OV2640摄像头释放热点&#xff08;AP&#xff09;工作模式–Arduino程序&#xff0c;当然如果手头有其他可以获得网络摄像头的URL即用于访问摄像头视频流的网络地址&…

【笔记】从零开始做一个精灵龙女-拆uv阶段

目录 先回顾一下拆uv的基础流程吧 肩部盔甲分UV示例 手环UV部分 腰带UV部分 其它也差不多&#xff0c;需要删掉一半的就先提前删掉一半&#xff0c;然后把不需要的被遮挡的面也删掉 龙角UV 胸甲UV 侧边碎发UV 马尾UV 脸部/耳朵UV 特殊情况&#xff1a;如果要删一半再…

MacOS 安装 Maven 并配置环境变量

一、简介 Maven 是一款基于 Java 平台的项目管理和整合工具&#xff0c;用来构建项目的。也就是清理、编译、测试、运行、打包、安装整个过程都交给 Maven 管理&#xff0c;整个过程就是构建。 二、安装 Java JDK Maven 依赖 Java JDK&#xff0c;如果本机没有安装过 Java 的…

Web后端开发之前后端交互

http协议 http ● 超文本传输协议 &#xff08;HyperText Transfer Protocol&#xff09;服务器传输超文本到本地浏览器的传送协议 是互联网上应用最为流行的一种网络协议,用于定义客户端浏览器和服务器之间交换数据的过程。 HTTP是一个基于TCP/IP通信协议来传递数据. HTT…

智慧校园-办公管理系统总体概述

智慧校园行政办公系统是专为高校及教育机构定制的数字化办公解决方案&#xff0c;它整合了众多办公应用与服务&#xff0c;旨在全面提升校园行政管理的效率与便捷性&#xff0c;推动信息的自由流动&#xff0c;实现绿色无纸化办公环境。该系统作为一个综合平台&#xff0c;将日…

VMware中的三种虚拟网络模式

虚拟机网络模式 1 主机网络环境2 VMware中的三种虚拟网络模式2.1 桥接模式2.2 NAT模式2.3 仅主机模式 3 网络模式选择及配置NAT模式3.1 VMware虚拟网络配置3.2 虚拟机选择网络模式3.3 Windows主机网络配置 4 配置静态IP 虚拟机联网方式为桥接模式&#xff0c;这种模式下&#x…

c++ 设计模式 的课本范例(下)

&#xff08;19&#xff09; 桥接模式 Bridge&#xff0c;不是采用类继承&#xff0c;而是采用类组合&#xff0c;一个类的数据成员是类对象&#xff0c;来扩展类的功能。源码如下&#xff1a; class OS // 操作系统负责绘图 { public:virtual ~OS() {}virtual void draw(cha…