叶子结点

选择排序-堆排序

依然范特西╮ 提交于 2020-03-08 16:42:12
文章目录 算法简介 Java 实现 时间复杂度 空间复杂度 算法稳定性 算法简介 二叉堆 一棵完全二叉树,对于大顶堆来说,任何一个结点都要大于等于它左右孩子结点,对于小顶堆,任何一个结点都要小于等于它的左右孩子。 二叉堆与数组的联系 二叉堆一般存储在数组中,有这样的性质,如果我们把二叉堆按照从上到下,从左到右的顺序依次存进数组,如果 index 是某个结点的下标值,那么它左右孩子结点的下标值分别是 2*index+1 和 2*index+2 ,不信的筒子们可以尝试写到数组中看看规律。我在数组中怎么知道这个下标的值是右结点还是左结点呢?我们减去 2 除以 2 除得尽就是右结点,否则是左结点,并且其父节点的下标也可以确定了。这个数组保存着这个二叉堆的所有信息 二叉堆的增删 二叉堆的新增和删除,我们会把一个结点新增到最下一层的最后面,然后与父节点比较,进而上浮或者不动;对于删除来讲,假如我们删除某一个中间结点,我们就需要用最尾部结点对删掉的节点位置进行补位,补上之后,再对这个补位的结点和最小(大)的直接子结点比较,进而选择下沉或不动 堆排序 我们利用二叉堆,上浮下沉的性质每次找到最大的结点上浮到顶端,然后我们再保存到最后面,这样就可以从小到大排序了!详细的说堆排序就是先创建大顶堆或小顶堆,然后把这个堆根和最尾部交换位置,将除了尾部的继续构成堆,这样不断循环就可以实现堆排序了 上浮还是下沉

三分钟带你快速实现二叉树的递归遍历

一曲冷凌霜 提交于 2020-03-08 12:06:07
写在前面: 上一篇文章中我们聊到了队列—— 漫画趣解——队列 相信很多小伙伴都知道了如何实现队列; 那么这次,时光同样采用漫画形式, 给大家聊一聊什么是二叉树,如何实现二叉树的递归遍历; 思维导图: ​ 什么是树? ​ 树是一种非线性结构,有一个直接前驱,但可能有多个直接后继(1:n); 树的定义具有递归性,树中还有树; 树可以为空,即结节点个数为0; 如图: ​ 若干术语: 根:根节点,没有前驱; 叶子:终端结点,没有后继; 双亲:上层的那个结点,就是直接前驱; 孩子:下层结点的子树,就是直接后继; 结点:树的数据元素;(上图的结点数为11) 结点的度:结点挂接的子树数,有几个直接后继就是几度; 树的度:所有结点度中的最大值,Max{各结点的度},(上图树的度为2); 树的深度(或高度):所有结点中最大的层数,(上图数的深度为3层); 什么是二叉树? ​ 二叉树: ​ 特征:每个结点 最多只有两个子结点 (不存在度大于2的结点); ​ 5种形态: ​ 常见的二叉树有两种重要形态, 满二叉树 和 完全二叉树 ; 满二叉树: 叶子结点全部都在最底层; 除叶子结点外,每个结点都有左右两个子节点; ​ 完全二叉树: 叶子结点全都都在最底的两层; 最后一层只缺少右边的叶子结点,左边一定有叶子结点; 除了最后一层,其它层的结点个数均达到最大值; ​ 二叉树的遍历:

小球下落(二叉树编号)

主宰稳场 提交于 2020-03-06 16:42:12
小球下落 有一颗二叉树,最大深度为D,且所有叶子的深度都相同,所有结点从上到下从左到右编号为1,2,3,…,2 ^ D - 1.在结点1处放一个小球,它会往下落。每个内结点上都有一个开关,初始全部关闭,当每次有小球落到一个开关上时,状态都会改变。当小球到达一个内结点时,如果该结点上的开关关闭,则往左走,否则往右走,直到走到叶子结点。 一些小球从结点1处一次开始下落,最后一个小球将会落到哪里?输入叶子深度D和小球个数I,输出第I个小球最后所在的叶子编号。假设I不超过整棵树的叶子个数。D<= 20.输入最多包含1000组数据。 样例输入 4 2 3 4 10 1 2 2 2 128 16 12345 样例输出: 12 7 512 3 255 36358 数组模拟的方法:运算量大 # include <iostream> # include <cstring> using namespace std ; const int N = 20 ; int s [ 1 << N ] ; //二进制下,每乘一个2就向左进一位,1左移N就相当于1 x 2 ^ N;这里存最大结点数 int main ( ) { int D , I ; //叶子深度和小球个数 while ( ~ scanf ( "%d%d" , & D , & I ) ) { memset ( s , 0 , sizeof ( s )

红黑树基础与代码(一)

…衆ロ難τιáo~ 提交于 2020-03-05 23:59:38
一. 定义和性质 红黑树是一种含有红黑结点并能自平衡的二叉查找树,红黑树并不是一个完美平衡二叉查找树,红黑树的左子树和右子树的黑结点的层数是相等的,也即任意一个结点到到每个叶子结点的路径都包含数量相同的黑结点。所以我们叫红黑树这种平衡为黑色完美平衡. 它必须满足下面性质: 性质1:每个节点要么是黑色,要么是红色 性质2:根节点是黑色 性质3:每个叶子节点(NIL)是黑色 性质4:每个红色结点的两个子结点一定都是黑色 性质5:任意一结点到每个叶子结点的路径都包含数量相同的黑结点。(如果一个结点存在黑子结点,那么该结点肯定有两个子结点) 二. 为何很多应用选择红黑树作为平衡树的实现 插入或删除节点时,平衡二叉树为了维持平衡,需要对其进行平衡纠正,这需要较大的开销。 例如,有种AVL树, 是高度平衡树,结构比红黑树更加平衡,这也表示其增删节点时也更容易失衡,失衡就需要纠正,增删节点时开销会比红黑树大。但不可否认的是AVL树搜索的效率是非常稳定的。 因此在大量数据需要插入或者删除时,AVL需要平衡调整的频率会更高。因此,红黑树在需要大量插入和删除节点的场景下,效率更高。自然,由于AVL高度平衡,因此AVL的Search效率略高。 红黑树不是高度平衡树,但平衡的效果已经很好了。所以,可以认为红黑树是一种折中的选择,其综合性能较好。 三.红黑树涉及的基本操作 在进行红黑树基本操作前

《统计学学习方法》阅读笔记2:k近邻算法

牧云@^-^@ 提交于 2020-03-04 21:24:57
k近邻法 1、k近邻算法 输入: 训练集数据 T = { ( x 1 , y 1 ) , ( x 2 , y 2 ) , . . . , ( x N , y N ) } T=\{(x_1,y_1),(x_2,y_2),...,(x_N,y_N)\} T = { ( x 1 ​ , y 1 ​ ) , ( x 2 ​ , y 2 ​ ) , . . . , ( x N ​ , y N ​ ) } 其中, x i ∈ X ⊆ R n x_i \in X \subseteq R^n x i ​ ∈ X ⊆ R n 是实例的特征向量, y i ∈ Y = { c 1 , c 2 , . . . , c K } y_i \in Y = \{c_1,c_2,...,c_K\} y i ​ ∈ Y = { c 1 ​ , c 2 ​ , . . . , c K ​ } 是实例的类别, i = 1 , 2 , . . . , N i=1,2,...,N i = 1 , 2 , . . . , N 输出: 实例 x x x 所属的类 y y y 。 (1)根据给定的 距离度量 ,在训练集 T T T 中找出与 x x x 最邻近的 k k k 个点,涵盖这 k k k 个点的 x x x 的邻域记作 N k ( x ) N_k(x) N k ​ ( x ) ; (2)在 N k ( x ) N_k

30、B-树与B+树的异同

…衆ロ難τιáo~ 提交于 2020-03-03 10:20:56
前面已经介绍过B-树,接下来,我们主要介绍一下B+树。 1、B+树的概念 B+树是应文件系统所需而生的一种B-树和变形树。一棵m阶B+树和m阶的B-树的差异在于: (1)有n棵子树的结点中含有n个关键字。 (2)所有的叶子结点中包含了全部关键字的信息,及指向含有这些关键字记录的指针,且叶子结点本身关键字的大小自小而大顺序链接。 (3)所有的非终端节点可以看成是索引部分,结点 中仅含有其子树(根结点)中的最大(小)关键字。 B+树通常有两个指针,一个指向根结点,另一个指向关键字最小的叶子结点。因些,对于B+树进行查找两种运算:一种是从最小关键字起顺序查找,另一种是从根结点开始,进行随机查找。 2、B+树的查找 跟B树的查找类似,但是也有不同。由于跟记录有关的信息存放在叶结点中,查找时若在上层已找到待查的关键码,并不停止,而是继续沿指针向下一直查到叶结点层的关键码。因此,在B+树中,不管查找成功与否,每次查找都是走了一条从根到叶子结点的路径。此外,B+树的所有叶结点构成一个有序链表,可以按照关键码排序的次序遍历全部记录。上面两种方式结合起来,使得B+树非常适合范围检索。 3、B+树的插入 B+树的插入与B树的插入过程类似。不同的是B+树在叶结点上进行,如果叶结点中的关键码个数超过m,就必须分裂成关键码数目大致相同的两个结点,并保证上层结点中有这两个结点的最大关键码。 4、B+树的删除

29、B-树的插入、查找、删除

吃可爱长大的小学妹 提交于 2020-03-03 10:16:30
前面讨论的查找都是内查询算法,被查询的数据都在内存。当查询的数据放在外存,用平衡二叉树作磁盘文件的索引组织时,若以结点为内外存交换的单位,则找到需要的关键字之前,平均要进行lgn次磁盘读操作,而磁盘、光盘的读写时间要比随机存取的内存代价大得多。其二,外存的存取是以“页”为单位的,一页的大小通常是1024字节或2048字节。 针对上述特点,1972年R.Bayer和E.M.Cright提出了一种B-树的多路平衡查找树,以适合磁盘等直接存取设备上组织动态查找表。B-树上算法的执行时间主要由读、写磁盘的次数来决定,故一次I/O操作应读写尽可能多的信息。因此B-树的结点规模一般以一个磁盘页为单位。一个结点包含的关键字及其孩子个数取决于磁盘页的大小。 一、基本概念 B-树又称为多路平衡查找树。 一棵度为m的B-树称为m阶B_树。一个结点有k个孩子时,必有k-1个关键字才能将子树中所有关键字划分为k个子集。B-树中所有结点的孩子结点最大值称为B-树的阶,通常用m表示。从查找效率考虑,一般要求m≥3。一棵m阶的B-树或者是一棵空树,或者是满足下列要求的m叉树: (1)根结点或者为叶子,或者至少有两棵子树,至多有m棵子树。 (2)除根结点外,所有非终端结点至少有ceil(m/2)棵子树,至多有m棵子树。 (3)所有叶子结点都在树的同一层上。 (4)每个结点的结构为: (n,A0,K1,A1,K2

赫夫曼树

血红的双手。 提交于 2020-03-03 08:09:31
基本介绍 给定n个权值作为n个叶子结点,构造一棵二叉树,若该树的带权路径长度(wpl)达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree), 还有的书翻译为霍夫曼树。 赫夫曼树是带权路径长度最短的树,权值较大的结点离根较近 重要概念说明 路径和路径长度 :在一棵树中,从一个结点往下可以达到的孩子或孙子结点之间的通路,称为路径。通路中分支的数目称为路径长度。若规定根结点的层数为1,则从根结点到第L层结点的路径长度为L-1 结点的权及带权路径长度 :若将树中结点赋给一个有着某种含义的数值,则这个数值称为该结点的权。结点的带权路径长度为:从根结点到该结点之间的路径长度与该结点的权的乘积 树的带权路径长度 :树的带权路径长度规定为所有叶子结点的带权路径长度之和,记为WPL(weighted path length) ,权值越大的结点离根结点越近的二叉树才是最优二叉树。 WPL最小的就是赫夫曼树 如图:中间一棵树的wpl最小,它就是赫夫曼树 赫夫曼树创建 赫夫曼树创建步骤 给定一个数组 {13, 7, 8, 3, 29, 6, 1} 从小到大进行排序, 将每一个数据,每个数据都是一个节点 , 每个节点可以看成是一颗最简单的二叉树 取出根节点权值最小的两颗二叉树 组成一颗新的二叉树, 该新的二叉树的根节点的权值是前面两颗二叉树根节点权值的和 再将这颗新的二叉树

堆排序

若如初见. 提交于 2020-03-02 21:01:35
一 初识堆 堆 数据结构是一种数组,它可以视为一颗完全二叉树。如下图: 图中的树是数组,A={16, 14, 10, 8, 7, 9, 3, 7},圈内表示数值,圈外红色的数字表示数组的下标。 array_size是数组的大小(此时是8),heap_size是构建堆的元素的多少。满足 heap_size<= array_size 给定某结点的下表i,其父结点下标为PARENT(i), 左儿子下标为LEFT(i), 右儿子下标为RIGHT(i)。满足 PARENT(i) = int((i-1)/2) ; LEFT(i) = 2*i+1; RIGHT(i)=2*i+2 最大堆满足:对于任何结点(除根节点)PARENT(i) > i 最小堆满足:对于任何结点(除根节点)PARENT(i) <i 叶子节点(下标):int(i/2), int(i/2)+1......array_size 下面的介绍以 最大堆 为例 二 保持堆的性质 最大堆的性质为 PARENT(i) > i,因此对于特定的结点,应满足比左右儿子都大 、 在上图中下标为1的结点值为2,左孩子为4,右孩子为1,1结点比左孩子小,就让1结点和3结点数值换过来。若此时4结点大于4,就把1结点和4结点数值换过来。 参考程序: void MAX_HEAPIFY(int *A, int heap_size, int i) //i

数据结构相关

白昼怎懂夜的黑 提交于 2020-03-02 16:58:18
记录一下数据结构的一些东西,方便复习应用 二叉树 结点的度:结点拥有的子树的数目 叶子结点:度为0的结点 分支结点:度不为0的结点 树的度:树中结点的最大的度 层次:根结点的层次为1,其余结点的层次等于该结点的双亲结点的层次加1 树的高度:树中结点的最大层次 森林:0个或多个不相交的树组成。对森林加上一个根,森林即成为树;删去根,树即成为森林。 满二叉树 定义:高度为h,并且由2h-1个结点组成的二叉树,称为满二叉树 完全二叉树 定义:一棵二叉树中,只有最下面两层结点的度可以小于2,并且最下层的叶结点集中在靠左的若干位置上,这样的二叉树称为完全二叉树。 树的遍历 详解链接 前序遍历-根左右 中序遍历-左根右 后序遍历-左右根 根据前序遍历中序遍历推导树的结构、根据树的中序遍历后序遍历推导树的结构 详细讲解 链表 详细讲解 注意 区分 node 和 node.val 链表和数组的区别: 两者的区别: 数组静态分配内存,链表动态分配内存。 数组在内存中是连续的,链表是不连续的。 数组利用下标定位,查找的时间复杂度是O(1),链表通过遍历定位元素,查找的时间复杂度是O(N)。 数组插入和删除需要移动其他元素,时间复杂度是O(N),链表的插入或删除不需要移动其他元素,时间复杂度是O(1)。 JS查找算法 https://www.cnblogs.com/zhuochong/p