西风的数据结构教程(3)——二叉树

2024-02-23 13:18

本文主要是介绍西风的数据结构教程(3)——二叉树,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

今天我们终于要说到计算机界的经典数据结构——树,树是非常良好的一种组织数据的形式,在现实生活中也经常用到。

树的结构,大概就是这个样子:

这里写图片描述

一群树就会组成一个森林

不过,这样并不好管理,所以我们一般会还是使用一个根节点来管理它们。

树结构最大的特点就是,一个节点的情况分析只和父节点和子节点相关,这样管理数据时往往不需要考虑很多。

例如文件系统中,每个文件夹可以视为一个节点,而每个文件夹只显示自己的子节点,结构就非常清晰了。

而二叉树是树结构中的非常常用的一种,往往被用作排序树使用,可以自动排序和判重,可以作为索引使用。

下面我们就来实际写一个二叉排序树,然后增加其平衡性,将其改写为一棵红黑树,不过红黑树的部分十分复杂,可以循序渐进的来学习和理解,不必一下就学习完。

二叉排序树

二叉排序树是简单的排序数据结构,可以支持动态的插入删除数据,对数据快速查找,复杂度只有log(n)

它的实现方法是这样的:

这里写图片描述

原理很简单,对于每一棵子树,左孩子都比自己小,右孩子都比自己大,那么就利用二分的思想,不断寻找这个数所在的位置。

插入时,则需要先考虑好要插入的位置:

这里写图片描述

我们发现,插入操作和查找操作是几乎一样的,只要找到对应的位置,插入很好办。

删除时,确实要复杂一点,因为我们直接将节点从树上拿走,如果叶子节点还好办,但我们考虑非叶子节点的删除,就较为复杂了。那么,如何才能正确的删除一个节点呢?我们来观察一下:

这里写图片描述

通过这张图,我们能看出来,每一个元素的上一个相邻元素是左子树的最右边孩子,下一个元素是右子树的最左孩子,这两个相邻元素都是叶子节点,而且如果左子树没有右孩子节点,那么就用最大的根节点替换。同理,用右子树删除也可以。

这里写图片描述

那好,我们既然知道了树的基本操作,就来简要的模拟一下,二叉排序树是如何运作的。

二叉排序树的实现

让我们来定义一棵树吧

typedef int TreeElementType;typedef struct _bst_node
{TreeElementType data;struct _bst_node *left, *right;
} bst_node;typedef struct _tree
{bst_node* root;
} bstree;

还是类似的方法,bstree存抽象的树对象,bst_node则是树的每个节点,其中存放的元素单独定义出来

为其编写构造函数:


bst_node* TreeNodeCreate() {bst_node* n = (bst_node*) malloc(sizeof(bst_node));n->left = n->right = NULL;
}bstree* BSTreeCreate() {return (bstree*)malloc(sizeof(bstree));
}

下面我们要开始实现这个二叉树了,二叉树的插入十分简单,只需要递归的判断,当前节点是比中值大还是小,如果小就往左走,大就往右走,相同时就直接返回无法插入即可。
但这样实现考虑到函数的调用效率问题,我们采用while循环来实现,只需要用指针模拟两个节点即可:

void TreeInsert(bstree* t, TreeElementType data) {if (t->root == NULL) { t->root = TreeNodeCreate();t->root->data = data; return;}bst_node* p = t->root;bst_node* q = NULL;while(p != NULL) {if (data < p->data) { q = p; p = p->left; continue; }if (data > p->data) { q = p; p = p->right; continue; }if (data ==p->data) return;}bst_node* node = TreeNodeCreate();node->data = data;if (data < q->data)q->left = node;elseq->right = node;
}

而查找方法也将是使用循环实现的:

bst_node* TreeSearch(bstree* t, TreeElementType data) {if (t->root == NULL) return NULL;bst_node* p = t->root;while(p != NULL) {if (data ==p->data) return p;if (data < p->data) { p = p->left; continue; }if (data > p->data) { p = p->right; continue; }}return NULL;
}

二叉树的删除是最复杂的部分,核心思路就是找一个可以和当前节点互换的元素,将那个元素替换上去,当前节点拿下来:

void TreeDelete(bstree* t, TreeElementType data) {if (t->root == NULL) return;bst_node* p = t->root;bst_node* q = NULL;while(p != NULL) {if (data ==p->data) break;if (data < p->data) { q = p; p = p->left; continue; }if (data > p->data) { q = p; p = p->right; continue; }}if (p == NULL) return;if (p->left == NULL) { // 若p没有左孩子,直接用它的右孩子取代q->right = p->right;Free(p);} else { // 否则先找到做子树中最大的元素ptemp, 用它交换p, 然后ptemp由ptemp的左孩子代替(因为它一定没有右孩子)bst_node* ptemp = p->left;bst_node* qtemp = NULL;while(ptemp->right != NULL) {qtemp = ptemp;ptemp = ptemp->right;}q->right = ptemp;qtemp->right = ptemp->left;ptemp->left = p->left;ptemp->right = p->right;Free(p);}
}

本系列教程由 西风逍遥游 原创,转载请注明出处:http://blog.csdn.net/xfxyy_sxfancy

这篇关于西风的数据结构教程(3)——二叉树的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/738764

相关文章

Window Server创建2台服务器的故障转移群集的图文教程

《WindowServer创建2台服务器的故障转移群集的图文教程》本文主要介绍了在WindowsServer系统上创建一个包含两台成员服务器的故障转移群集,文中通过图文示例介绍的非常详细,对大家的... 目录一、 准备条件二、在ServerB安装故障转移群集三、在ServerC安装故障转移群集,操作与Ser

windos server2022的配置故障转移服务的图文教程

《windosserver2022的配置故障转移服务的图文教程》本文主要介绍了windosserver2022的配置故障转移服务的图文教程,以确保服务和应用程序的连续性和可用性,文中通过图文介绍的非... 目录准备环境:步骤故障转移群集是 Windows Server 2022 中提供的一种功能,用于在多个

龙蜥操作系统Anolis OS-23.x安装配置图解教程(保姆级)

《龙蜥操作系统AnolisOS-23.x安装配置图解教程(保姆级)》:本文主要介绍了安装和配置AnolisOS23.2系统,包括分区、软件选择、设置root密码、网络配置、主机名设置和禁用SELinux的步骤,详细内容请阅读本文,希望能对你有所帮助... ‌AnolisOS‌是由阿里云推出的开源操作系统,旨

PyTorch使用教程之Tensor包详解

《PyTorch使用教程之Tensor包详解》这篇文章介绍了PyTorch中的张量(Tensor)数据结构,包括张量的数据类型、初始化、常用操作、属性等,张量是PyTorch框架中的核心数据结构,支持... 目录1、张量Tensor2、数据类型3、初始化(构造张量)4、常用操作5、常用属性5.1 存储(st

Java操作PDF文件实现签订电子合同详细教程

《Java操作PDF文件实现签订电子合同详细教程》:本文主要介绍如何在PDF中加入电子签章与电子签名的过程,包括编写Word文件、生成PDF、为PDF格式做表单、为表单赋值、生成文档以及上传到OB... 目录前言:先看效果:1.编写word文件1.2然后生成PDF格式进行保存1.3我这里是将文件保存到本地后

windows系统下shutdown重启关机命令超详细教程

《windows系统下shutdown重启关机命令超详细教程》shutdown命令是一个强大的工具,允许你通过命令行快速完成关机、重启或注销操作,本文将为你详细解析shutdown命令的使用方法,并提... 目录一、shutdown 命令简介二、shutdown 命令的基本用法三、远程关机与重启四、实际应用

python库fire使用教程

《python库fire使用教程》本文主要介绍了python库fire使用教程,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录1.简介2. fire安装3. fire使用示例1.简介目前python命令行解析库用过的有:ar

LinuxMint怎么安装? Linux Mint22下载安装图文教程

《LinuxMint怎么安装?LinuxMint22下载安装图文教程》LinuxMint22发布以后,有很多新功能,很多朋友想要下载并安装,该怎么操作呢?下面我们就来看看详细安装指南... linux Mint 是一款基于 Ubuntu 的流行发行版,凭借其现代、精致、易于使用的特性,深受小伙伴们所喜爱。对

使用Nginx来共享文件的详细教程

《使用Nginx来共享文件的详细教程》有时我们想共享电脑上的某些文件,一个比较方便的做法是,开一个HTTP服务,指向文件所在的目录,这次我们用nginx来实现这个需求,本文将通过代码示例一步步教你使用... 在本教程中,我们将向您展示如何使用开源 Web 服务器 Nginx 设置文件共享服务器步骤 0 —

Golang使用minio替代文件系统的实战教程

《Golang使用minio替代文件系统的实战教程》本文讨论项目开发中直接文件系统的限制或不足,接着介绍Minio对象存储的优势,同时给出Golang的实际示例代码,包括初始化客户端、读取minio对... 目录文件系统 vs Minio文件系统不足:对象存储:miniogolang连接Minio配置Min