二叉排序树经典算法速成:”二叉排序树“。

1. 概念:

     <1> 其实很简单,若根节点有左子树,则左子树的所有节点都比根节点小。

                             若根节点有右子树,则右子树的所有节点都比根节点大。

     <2> 如图就是一个”二叉排序树“,然后对照概念一比较比较。

2.实际操作:

我们都知道,对一个东西进行操作,无非就是增删查改,接下来我们就聊聊其中的基本操作。

<1> 插入:相信大家对“排序树”的概念都清楚了吧,那么插入的原理就很简单了。

比如说我们插入一个20到这棵树中。

首先:20跟50比,发现20是老小,不得已,得要归结到50的左子树中去比较。

然后:20跟30比,发现20还是老小。

再然后:20跟10比,发现自己是老大,随即插入到10的右子树中。

最后: 效果呈现图如下:

<2>查找:相信懂得了插入,查找就跟容易理解了。

就拿上面一幅图来说,比如我想找到节点10.

首先:10跟50比,发现10是老小,则在50的左子树中找。

然后:10跟30比,发现还是老小,则在30的左子树中找。

再然后:  10跟10比,发现一样,然后就返回找到的信号。

<3>删除:删除节点在树中还是比较麻烦的,主要有三种情况。

《1》 删除的是“叶节点20“,这种情况还是比较简单的,删除20不会破坏树的结构。如图:

《2》删除”单孩子节点90“,这个情况相比第一种要麻烦一点点,需要把他的孩子顶上去。

《3》删除“左右孩子都有的节点50”,这个让我在代码编写上纠结了好长时间,问题很直白,

我把50删掉了,谁顶上去了问题,是左孩子呢?还是右孩子呢?还是另有蹊跷?这里我就

坦白吧,不知道大家可否知道“二叉树”的中序遍历,不过这个我会在后面讲的,现在可以当

公式记住吧,就是找到右节点的左子树最左孩子。

比如:首先 找到50的右孩子70。

然后  找到70的最左孩子,发现没有,则返回自己。

最后  原始图和最终图如下。

 

3.说了这么多,上代码说话。

  1 using System;  2 using System.Collections.Generic;  3 using System.Linq;  4 using System.Text;  5 using System.Diagnostics;  6   7 namespace TreeSearch  8 {  9     class Program 10     { 11         static void Main(string[] args) 12         { 13             List<int> list = new List<int>() { 50, 30, 70, 10, 40, 90, 80 }; 14  15             //创建二叉遍历树 16             BSTree bsTree = CreateBST(list); 17  18             Console.Write("中序遍历的原始数据:"); 19  20             //中序遍历 21             LDR_BST(bsTree); 22  23             Console.WriteLine("\n---------------------------------------------------------------------------n"); 24  25             //查找一个节点 26             Console.WriteLine("\n10在二叉树中是否包含:" + SearchBST(bsTree, 10)); 27  28             Console.WriteLine("\n---------------------------------------------------------------------------n"); 29  30             bool isExcute = false; 31  32             //插入一个节点 33             InsertBST(bsTree, 20, ref isExcute); 34  35             Console.WriteLine("\n20插入到二叉树,中序遍历后:"); 36  37             //中序遍历 38             LDR_BST(bsTree); 39  40             Console.WriteLine("\n---------------------------------------------------------------------------n"); 41  42             Console.Write("删除叶子节点 20, \n中序遍历后:"); 43  44             //删除一个节点(叶子节点) 45             DeleteBST(ref bsTree, 20); 46  47             //再次中序遍历 48             LDR_BST(bsTree); 49  50             Console.WriteLine("\n****************************************************************************\n"); 51  52             Console.WriteLine("删除单孩子节点 90, \n中序遍历后:"); 53  54             //删除单孩子节点 55             DeleteBST(ref bsTree, 90); 56  57             //再次中序遍历 58             LDR_BST(bsTree); 59  60             Console.WriteLine("\n****************************************************************************\n"); 61  62             Console.WriteLine("删除根节点 50, \n中序遍历后:"); 63             //删除根节点 64             DeleteBST(ref bsTree, 50); 65  66             LDR_BST(bsTree); 67  68         } 69  70         ///<summary> 71 /// 定义一个二叉排序树结构 72 ///</summary> 73         public class BSTree 74         { 75             public int data; 76             public BSTree left; 77             public BSTree right; 78         } 79  80         ///<summary> 81 /// 二叉排序树的插入操作 82 ///</summary> 83 ///<param name="bsTree">排序树</param> 84 ///<param name="key">插入数</param> 85 ///<param name="isExcute">是否执行了if语句</param> 86         static void InsertBST(BSTree bsTree, int key, ref bool isExcute) 87         { 88             if (bsTree == null) 89                 return; 90  91             //如果父节点大于key,则遍历左子树 92             if (bsTree.data > key) 93                 InsertBST(bsTree.left, key, ref isExcute); 94             else 95                 InsertBST(bsTree.right, key, ref isExcute); 96  97             if (!isExcute) 98             { 99                 //构建当前节点100                 BSTree current = new BSTree()101                   {102                       data = key,103                       left = null,104                       right = null105                   };106 107                 //插入到父节点的当前元素108                 if (bsTree.data > key)109                     bsTree.left = current;110                 else111                     bsTree.right = current;112 113                 isExcute = true;114             }115 116         }117 118         ///<summary>119 /// 创建二叉排序树120 ///</summary>121 ///<param name="list"></param>122         static BSTree CreateBST(List<int> list)123         {124             //构建BST中的根节点125             BSTree bsTree = new BSTree()126             {127                 data = list[0],128                 left = null,129                 right = null130             };131 132             for (int i = 1; i < list.Count; i++)133             {134                 bool isExcute = false;135                 InsertBST(bsTree, list[i], ref isExcute);136             }137             return bsTree;138         }139 140         ///<summary>141 /// 在排序二叉树中搜索指定节点142 ///</summary>143 ///<param name="bsTree"></param>144 ///<param name="key"></param>145 ///<returns></returns>146         static bool SearchBST(BSTree bsTree, int key)147         {148             //如果bsTree为空,说明已经遍历到头了149             if (bsTree == null)150                 return false;151 152             if (bsTree.data == key)153                 return true;154 155             if (bsTree.data > key)156                 return SearchBST(bsTree.left, key);157             else158                 return SearchBST(bsTree.right, key);159         }160 161         ///<summary>162 /// 中序遍历二叉排序树163 ///</summary>164 ///<param name="bsTree"></param>165 ///<returns></returns>166         static void LDR_BST(BSTree bsTree)167         {168             if (bsTree != null)169             {170                 //遍历左子树171                 LDR_BST(bsTree.left);172 173                 //输入节点数据174                 Console.Write(bsTree.data + "");175 176                 //遍历右子树177                 LDR_BST(bsTree.right);178             }179         }180 181         ///<summary>182 /// 删除二叉排序树中指定key节点183 ///</summary>184 ///<param name="bsTree"></param>185 ///<param name="key"></param>186         static void DeleteBST(ref BSTree bsTree, int key)187         {188             if (bsTree == null)189                 return;190 191             if (bsTree.data == key)192             {193                 //第一种情况:叶子节点194                 if (bsTree.left == null && bsTree.right == null)195                 {196                     bsTree = null;197                     return;198                 }199                 //第二种情况:左子树不为空200                 if (bsTree.left != null && bsTree.right == null)201                 {202                     bsTree = bsTree.left;203                     return;204                 }205                 //第三种情况,右子树不为空206                 if (bsTree.left == null && bsTree.right != null)207                 {208                     bsTree = bsTree.right;209                     return;210                 }211                 //第四种情况,左右子树都不为空212                 if (bsTree.left != null && bsTree.right != null)213                 {214                     var node = bsTree.right;215 216                     //找到右子树中的最左节点217                     while (node.left != null)218                     {219                         //遍历它的左子树220                         node = node.left;221                     }222 223                     //交换左右孩子224                     node.left = bsTree.left;225 226                     //判断是真正的叶子节点还是空左孩子的父节点227                     if (node.right == null)228                     {229                         //删除掉右子树最左节点230                         DeleteBST(ref bsTree, node.data);231 232                         node.right = bsTree.right;233                     }234                     //重新赋值一下235                     bsTree = node;236 237                 }238             }239 240             if (bsTree.data > key)241             {242                 DeleteBST(ref bsTree.left, key);243             }244             else245             {246                 DeleteBST(ref bsTree.right, key);247             }248         }249     }250 }

运行结果:

值的注意的是:二叉排序树同样采用“空间换时间”的做法。

突然发现,二叉排序树的中序遍历同样可以排序数组,呵呵,不错!

PS:  插入操作:O(LogN)。

删除操作:O(LogN)。

查找操作:O(LogN)

转载于:https://www.cnblogs.com/xiaopohou/archive/2012/01/18/2325601.html

二叉排序树经典算法速成相关推荐

  1. 前端笔试常考设计模式,操作系统,数据结构,ACM模板,经典算法,正则表达式,常用方法

    考试时允许使用草稿纸,请提前准备纸笔.考试过程中允许上厕所等短暂离开,但请控制离开时间 笔试得分60%一般通过,面试答对80%才能通过 合集:2023年最全前端面试题考点HTML5+CSS3+JS+V ...

  2. 数据挖掘的一些经典算法

    数据挖掘能做以下七种不同事情 (分析方法): 数据挖掘能做以下七种不同事情 · 分类 (Classification) · 估计(Estimation) · 预测(Prediction) · 相关性分 ...

  3. 经典算法研究系列:二、Dijkstra 算法初探

    经典算法研究系列:二.Dijkstra 算法初探  July   二零一一年一月 ====================== 本文主要参考:算法导论 第二版.维基百科. 写的不好之处,还望见谅. 本 ...

  4. 经典算法书籍推荐以及算法书排行【算法四库全书】

    经典算法书籍推荐以及算法书排行[算法四库全书] 作者:霞落满天   https://linuxstyle.blog.csdn.net/    https://blog.csdn.net/21aspne ...

  5. 经典算法题每日演练——第六题 协同推荐SlopeOne 算法

    原文:经典算法题每日演练--第六题 协同推荐SlopeOne 算法 相信大家对如下的Category都很熟悉,很多网站都有类似如下的功能,"商品推荐","猜你喜欢&quo ...

  6. 白话经典算法系列之七 堆与堆排序

     堆排序与高速排序,归并排序一样都是时间复杂度为O(N*logN)的几种常见排序方法.学习堆排序前,先解说下什么是数据结构中的二叉堆. 二叉堆的定义 二叉堆是全然二叉树或者是近似全然二叉树. 二叉堆满 ...

  7. 免费技术直播:唐宇迪带你一节课了解机器学习经典算法

    常常有小伙伴在后台反馈:机器学习经典算法有哪些? 自学难度大又没有效果,该怎么办? CSDN为了解决这个难题,联合唐宇迪老师为大家带来了一场精彩的直播[一节课掌握机器学习经典算法-线性回归模型].本次 ...

  8. 一文了解迁移学习经典算法

    来源 | linolzhang的CSDN博客 作者 | linolzhang ▌一. 了解迁移学习 迁移学习(Transfer Learning)目标是将从一个环境中学到的知识用来帮助新环境中的学习任 ...

  9. 调包侠福音!机器学习经典算法开源教程(附参数详解及代码实现)

    Datawhale 作者:赵楠.杨开漠.谢文昕.张雨 寄语:本文针对5大机器学习经典算法,梳理了其模型.策略和求解等方面的内容,同时给出了其对应sklearn的参数详解和代码实现,帮助学习者入门和巩固 ...

最新文章

  1. Tomcat init 脚本并添加服务自启动
  2. 网页制作之html基础学习3-css样式表
  3. 漫画:原来,我是备胎!!!
  4. 2021年春季学期-信号与系统-第十五次作业参考答案-第一小题参考答案
  5. HDU 4023 (博弈 贪心 模拟) Game
  6. python可以取代excel吗_10条Python命令全面取代Excel,妈妈再也不用担心我变成黑眼圈大表哥啦...
  7. Mysql高级命令与概念
  8. java joda 获取utc时间_Java获取时间与系统时间相差8小时终极解决方案
  9. Nature综述:宏基因组测序研究耐药基因的方法和资源
  10. 面试了十个应届生九个都是秒杀系统,你确定你们那是秒杀?
  11. SpringBoot用MultipartFile.transferTo传递相对路径的问题
  12. 计算机电影制作专业,影视制作专业是学什么的
  13. 19年读100本书之第一本--《人生效率手册》
  14. 基于ssm java健身俱乐部网站
  15. 【实验】Oracle 10g RAC生产数据库RMAN方式恢复到异地单机数据库全程记录
  16. 详解kerberos认证原理
  17. (首发)SixTool多功能代挂助手
  18. 前端例程20221102:黑暗模式(Dark Mode)
  19. 安卓系统dicom阅读器_0元车又来了!柠檬M1阅读器上手体验,180天打卡免费领
  20. 由串口驱动分析rt-thread设备驱动框架

热门文章

  1. 【深度学习】Tensorflow搭建卷积神经网络实现情绪识别
  2. python【蓝桥杯vip练习题库】BASIC-23芯片测试(统计)
  3. 阿里云服务器(Ubuntu16.04 64位)远程连接
  4. JAVA中NEXTLINE()与NEXT()的区别
  5. jdbc 自增id 原理_给“小白”漫画+图示讲解MyBatis原理,就问香不香!
  6. ajax往CJJTable传值,jQuery+ajax怎么样实现动态数据分页
  7. 深圳网络推广是如何提高网站的收录比的?
  8. 开展企业网站建设如何做到保质保量?
  9. seo网站营销与内容营销不可分割
  10. 网站内链的6大常见形式你了解多少?