排序二叉树 SortBinaryTree

排序二叉树 SortBinaryTree

            排序二叉树是比较基本但是重要的算法,它在许多实际编码中都不可缺少,还有不少算法和数据结构都基于此。比如,二叉查找树,平衡二叉树,红黑树等等。  

       SortBinaryTree的源代码见: https://github.com/duankai/SortBinaryTree/

       下面,介绍SortBinaryTree。

1.      SortBinaryTree的节点结构:

struct TREE_NODE_T 
{ 
AnyType * pcData; 
TREE_NODE_T<AnyType> * pstParent; 
TREE_NODE_T<AnyType> * pstLeftChild; 
TREE_NODE_T<AnyType> * pstRightChild; 
};



2.      构造函数

SortBinaryTree(int(* cmpFunc)(AnyType * d1, AnyType * d2))
{m_pstRoot         = NULL;m_pstSmallestNode = NULL;m_cmpFunc         = cmpFunc;
};

 其中,cmpFunc是AnyData的比较函数。


3.      树的插入

        树的插入采用递归的方法,首先寻找插入节点的合适位置,然后插入。

	bool InsertTreeNode(TREE_NODE_T<AnyType> * pstNode, TREE_NODE_T<AnyType> * pstTempRoot){if (!pstNode){return false;}if (NULL != pstTempRoot){if (m_cmpFunc(pstNode->pcData ,pstTempRoot->pcData) > 0){if (NULL != pstTempRoot->pstRightChild){return InsertTreeNode(pstNode, pstTempRoot->pstRightChild);}else{pstTempRoot->pstRightChild = pstNode;pstNode->pstParent = pstTempRoot;}}if (m_cmpFunc(pstNode->pcData ,pstTempRoot->pcData) < 0){if (NULL != pstTempRoot->pstLeftChild){return InsertTreeNode(pstNode, pstTempRoot->pstLeftChild);}else{pstTempRoot->pstLeftChild = pstNode;pstNode->pstParent = pstTempRoot;}}if (m_cmpFunc(pstNode->pcData ,pstTempRoot->pcData) == 0){return false;}}else{m_pstRoot = pstNode;}return true;};

4.      查找

    TREE_NODE_T<AnyType> * SearchNode(void * pvData, TREE_NODE_T<AnyType> * pstRoot){if (NULL == pstRoot || NULL == pvData){return NULL;}if (m_cmpFunc(pstRoot->pcData ,(AnyType *)pvData) == 0){return pstRoot;}else if (m_cmpFunc((AnyType *)pvData, pstRoot->pcData) < 0){return SearchNode(pvData, pstRoot->pstLeftChild);}else if (m_cmpFunc((AnyType *)pvData, pstRoot->pcData) > 0){return SearchNode(pvData, pstRoot->pstRightChild);}else{return NULL;}};

5.      删除最小节点

    首先,用中序遍历的方法得到最小的节点,然后删除。

AnyType * DeleteSmallestNode(){GetSmallestNode(m_pstRoot);if (NULL == m_pstSmallestNode){return NULL;}AnyType * pcData = m_pstSmallestNode->pcData;if (m_pstSmallestNode == m_pstRoot){m_pstRoot = m_pstRoot->pstRightChild;}SetPointerThisNull(m_pstSmallestNode);free(m_pstSmallestNode);m_pstSmallestNode = NULL;return pcData;};

6.      析构函数

         析构函数先用后续遍历节点,再对其进行删除。


7.      删除节点

         删除节点的思路分为以下几种情况。

         1)删除的是叶子节点,那么直接删除。

         2)删除的节点左(右)子树为空,则用右(左)子树替代要删除的节点。

         3)删除的节点左右子树都不为空,则用中序方法寻找此节点的前驱,用前驱替代此节点并删除。

bool DeleteTreeNode(void * pvData){if (NULL == pvData){return false;}TREE_NODE_T<AnyType> * pstTreeNode = SearchNode(pvData, GetRootNode());if (!pstTreeNode){return false;}if (pstTreeNode->pstLeftChild != NULL && pstTreeNode->pstRightChild != NULL){TREE_NODE_T<AnyType> * pstForeNode = GetForeNodeMiddleOrder(pstTreeNode);if (!pstForeNode){return false;}memcpy(pstTreeNode->pcData, pstForeNode->pcData, sizeof(AnyType));SetPointerThisNull(pstForeNode);free(pstForeNode);pstForeNode = NULL;return true;}if (pstTreeNode->pstLeftChild == NULL && pstTreeNode->pstRightChild != NULL){if (m_pstRoot == pstTreeNode){m_pstRoot = pstTreeNode->pstRightChild;pstTreeNode->pstRightChild->pstParent = NULL;}else{if (pstTreeNode == pstTreeNode->pstParent->pstLeftChild){pstTreeNode->pstParent->pstLeftChild = pstTreeNode->pstRightChild;}if (pstTreeNode == pstTreeNode->pstParent->pstRightChild){pstTreeNode->pstParent->pstRightChild = pstTreeNode->pstRightChild;}}}if (pstTreeNode->pstRightChild == NULL && pstTreeNode->pstLeftChild != NULL){if (m_pstRoot == pstTreeNode){m_pstRoot = pstTreeNode->pstLeftChild;pstTreeNode->pstLeftChild->pstParent = NULL;}else{if (pstTreeNode == pstTreeNode->pstParent->pstLeftChild){pstTreeNode->pstParent->pstLeftChild = pstTreeNode->pstLeftChild;}if (pstTreeNode == pstTreeNode->pstParent->pstRightChild){pstTreeNode->pstParent->pstRightChild = pstTreeNode->pstLeftChild;}}}SetPointerThisNull(pstTreeNode);free(pstTreeNode);pstTreeNode = NULL;return true;};


总结:

       除了SortBinaryTree提供的以上方法,大家还可以在此基础上进行适合自己项目的针对性扩展。由于做此排序二叉树是在写定时器时用来查找最先到时间的那个定时器,从而避免了对每个定时器进行扫描。因此,SortBinaryTree提供了一个删除最小节点的方法。

       后续,将继续开源项目中抽象出的工具代码,请大家关注github上的源代码以及CSDN博客上的讲解。同时,也欢迎各路高手留下您宝贵的意见和建议。




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

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

相关文章

使用postman操作ElasticSearch

下载安装好postman之后 添加索引blog1&#xff08;因为ElasticSearch是restful请求所以我们用postman发送http请求给ElasticSearch&#xff09; { "mappings":{ "article":{ "properties":{ "i…

图像处理基本算法-形态学

形态学一般是使用二值图像&#xff0c;进行边界提取&#xff0c;骨架提取&#xff0c;孔洞填充&#xff0c;角点提取&#xff0c;图像重建。基本的算法:膨胀腐蚀&#xff0c;开操作&#xff0c;闭操作&#xff0c;击中击不中变换 几种算法进行组合&#xff0c;就可以实现一些非…

定时器Timer的实现

定时器Timer的实现 定时器在实际项目中会用的比较平凡。因此&#xff0c;本文首先介绍定时器Timer的windows版本&#xff0c;跨平台的定时器将在下一篇文章中介绍。它们的源代码均用C编写。源代码详见&#xff1a;https://github.com/duankai/Timer。 1. 定时器结构体类型…

使用kibana客户端工具操作ElasticSearch(增删改查一)

&#xff08;因为ElasticSearch是restful请求所以 get post put delete这四种常见的请求&#xff09; put添加数据 get获取数据 #创建索引库lib 并且对索引库做了分片和备份&#xff08;由于这里是单机的ElasticSearch备份0&#xff09; PUT /lib/ {"settings"…

[恢]hdu 1040

2011-12-15 23:42:25 地址&#xff1a;http://acm.hdu.edu.cn/showproblem.php?pid1040 题意&#xff1a;给n个数&#xff0c;排序后输出。 代码&#xff1a; # include <stdio.h># include <stdlib.h>int a[1010] ;int cmp(const void *a, const void *b){return…

C++发送邮件

C 发送邮件 在许多应用程序中&#xff0c;都会或多或少地用到邮件发送程序。本文首先介绍发送邮件必须用到的协议SMTP&#xff0c;然后给出用C写的一个邮件发送类。 邮件发送要用到邮件服务器和一个邮箱账户&#xff0c;这样你就可以用本文的demo程序进行邮件发送了。 邮件发送…

kibana客户端工具操作ElasticSearch(增删改查二)

#不指定id情况下 ElasticSearch自动生成id PUT /lib/user/ {"first_name":"Douglas","last_name":"Fir","age":23,"about":"I like to build cabinets","interests":["forestry"] …

机器学习笔记(一) : 线性建模——最小二乘法

讨论这个方法之前&#xff0c;先说些题外话。首先&#xff0c;我感觉机器学习是一门值得我们去了解和学习的一门技术&#xff0c;它不仅仅应用于我们的生活&#xff0c;而且不断地在改变着我们的方方面面。虽然很早就已经接触它&#xff0c;并开始学习&#xff0c;但是总体感觉…

昨天、今天、明天

三天&#xff1a;昨天、今天、明天。人的一生&#xff0c;用这简单的6个字概括&#xff0c;形成了人生的一条“经”线&#xff0c;富有哲理&#xff0c;令人遐思。 今天处于昨天与明天的交接点上&#xff0c;我们每一天都在告别昨天&#xff0c;每一天又都在迎接明天。如果…

ElasticSearch快速入门(一)介绍

Devops运维 ● Node(节点):单个的装有Elasticsearch服务并且提供故障转移和扩展的服务 器。 ●Cluster (集群) :一-个集群就是由一个或多个node组织在一 起&#xff0c;共同工作&#xff0c; 共同分享整个数据具有负载均衡功能的集群。 ● Document (文档) : -一个文档是-一个可…

flash遨游缓存问题

来源&#xff1a;http://leftice.iteye.com/blog/806605 Flash需要和JS交互,但是在ie外壳浏览器下,有时候缓存会导致页面刷新后flash无法工作. 会报出SecurityError. 这是因为Flash并没有完全准备好,就尝试和JS交互导致的问题. 解决的问题方式有几种: 1.在页面上设置不缓存,网上…

机器学习笔记(二)——多变量最小二乘法

在上一节中&#xff0c;我们介绍了最简单的学习算法——最小二乘法去预测奥运会男子100米时间。但是可以发现&#xff0c;它的自变量只有一个&#xff1a;年份。通常&#xff0c;我们所面对的数据集往往不是单个特征&#xff0c;而是有成千上万个特征组成。那么我们就引入特征的…

ElasticSearch快速入门二(Restful介绍)

本节课从三个方便讲解 什么是restful ? API: Application Programming Interface的缩写&#xff0c;中文意思就是应用程序接口. ●XML: . 可扩展标记语言&#xff0c;是一种程序与程序之间传输数据的标记语言 ●JSON: 英文javascript object notation的缩写&#xff0c;它是一…

机器学习笔记(三)——正则化最小二乘法

一. 模型的泛化与过拟合 在上一节中&#xff0c;我们的预测函数为&#xff1a; f(x;ω)ωTx其中&#xff0c; x[x1],ω[ω1ω0]x=\begin{bmatrix} x\\ 1 \end{bmatrix}, \omega=\begin{bmatrix} \omega_1\\ \omega_0 \end{bmatrix}上述称为线性模型&#xff0c;我们也可以将x…

严谨,保证,职业。

上午在教室上的课&#xff0c;老师对我们这些VB初学者又“耐着性子”侃了半天&#xff0c;具体讲的内容虽然不多&#xff0c;但是说来奇怪&#xff0c;总能从中得到动力。教育的艺术在于激励。 经过三天的学习&#xff0c;对VB感觉慢慢入门&#xff0c;这两天一遍看着视频一遍做…

ElasticSearch快速入门三(curl命令讲解)

API测试工具_微博开放平台&#xff1a;https://open.weibo.com/tools/console# 感兴趣是可以使用这个工具玩一下restful接口调用&#xff0c;可以更形象的了解restful 下面我们就继续下面的内内容讲解curl命令 什么是CURL&#xff1f; 就是以命令的方式来执行HTTP协议的请求…

机器学习笔记(四)——最大似然估计

一、最大似然估计的基本思想 最大似然估计的基本思想是&#xff1a;从样本中随机抽取n个样本&#xff0c;而模型的参数估计量使得抽取的这n个样本的观测值的概率最大。最大似然估计是一个统计方法&#xff0c;它用来求一个样本集的概率密度函数的参数。 二、似然估计 在讲最…

Log4j 入门总结

一、Log4j介绍 log4j是类似于java.util.logging的日志作用&#xff0c;即记录一些有用信息&#xff0c;是一个日志框架&#xff1b; log4j log for Java 日志框架的作用&#xff1a; (1)函数参数是否正确&#xff1b; (2)软件发布后&#xff0c;记录用户的每一步操作&#xff…

ElasticSearch API文档查看

elastic官方API文档&#xff1a;https://www.elastic.co/guide/en/elasticsearch/reference/current/docs.html

机器学习笔记(五)——朴素贝叶斯分类

一、分类问题 分类实际上是我们在日常生活中经常使用的。比如说&#xff0c;在工作中&#xff0c;把自己手头的任务分为轻重缓急&#xff0c;然后按照优先级去完成它们。 朴素贝叶斯法是基于贝叶斯定理与特征条件独立假设的分类方法。 从数学的角度看C{c1,c2,…,ck}是类别的…