堆排序

堆排序的时间复杂度

匿名 (未验证) 提交于 2019-12-02 23:43:01
1 引言 2 堆排序 大根堆 ,任意一节点的值小于子节点的值称为 小根堆 。一般来说,堆可以用一个一维数组 A [ n ] A[n] A [ n ] 表示。 2.1 基本操作 2.1.1 获取父、子节点 Θ ( 1 ) \Theta(1) Θ ( 1 ) PARENT(i) return i/2 LEFT(i) return 2i RIGHT(i) return 2i+1 2.1.2 维护堆的性质 i i i 的子树都是大根堆的情况下,使以 i i i 为根节点的子树遵循大根堆的性质;此操作的伪代码如下: MAX-HEAPIFY(A,i) i = LEFT(i) r = RIGHT(i) if l <= A.heap-size and A[l] > A[i] largest = l else largest = i if r <= A.heap-size and A[r] > A[largest] largest = r if largest != i exchange A[i] with A[largest] MAX-HEAPIFY(A,largest) Θ ( 1 ) \Theta(1) Θ ( 1 ) ;那么MAX-HEAPIFY对于子树的时间代价最多为多少呢,可以用如下递归式表示: T ( n ) ≤ T ( 2 n / 3 ) + Θ ( 1 ) T(n) \leq T

堆排序

匿名 (未验证) 提交于 2019-12-02 23:34:01
(初稿) 堆排序,毋庸置疑,是根据堆的数据特性进行排序,所以,首先我们需要了解一下关于堆的性质。 堆,一种二叉树,一般分为有序堆(大顶堆(最大堆),小顶堆(最小堆)),无序堆。 这里以大顶堆为例,特点有: 父节点i总是大于左(2 i+1)右(2 i+2)节点。 节点t的父节点为Math.floor(t/2)。 代码书写参考自这位大神: 作者: dreamcatcher-cx 出处: http://www.cnblogs.com/chengxiao/ 开始排序: 先上代码: 运行结果: 说一下自己的理解过程以及棘手的处理: 首先,拿到数组对象,我们把它当作一个无序二叉树,以这个为数据基础,我们建造成大顶堆的数据格式:父节点大于左右节点。为此,在buildBigHeap方法处理之前,以节点 t 的父节点为主要的参数,初次这个节点 t就是 数组最后的一个元素,随着循环的递减,节点以二叉树的特点越往“上”走,直到到根节点处。在buildBigHeap中,我们对父节点,左节点和右节点进行比较并且交换。在为什么在这里要循环的问题,刚开始有点卡顿,是为了保障在修改当前的节点,还是得保证之前“下面”节点的数据结构还是满足着我们的大顶堆的特点。创建成功后,进行排序。将大顶堆根节点的元素跟最低叶节点(数组最大的下标处)进行交换,交换完再一次规整好大顶堆结构,以此类推,完成最终的排序。这样下来

排序算法之堆排序【小二讲堂】

匿名 (未验证) 提交于 2019-12-02 23:32:01
版权声明:本文为博主原创文章,转载请注明出处!!!小二学堂:https://blog.csdn.net/Mirror_w https://blog.csdn.net/Mirror_w/article/details/89789477 【排序思想】: 大顶堆:堆的每个父节点都大于其孩子节点 小顶堆:堆的每个度节点都小于其孩子节点 堆排序的概要:首先对于一组数据,将这组数据填入到一个二叉树中,这是构成了初始堆 A. 将初始堆进行排序,排序成一个大顶堆(或小顶对),将子节点与其父节点进行比较数据大的放在父节点的位置,直到生成一个大顶堆. B. 进行排序输出,规则,将跟节点上的数据进行与子节点中最小的数进行比较,将较小的数据交换至根节点,将最大的数进行输出, C. 将最大的数进行输出后,进行筛选调整,根据A中排大顶堆的方法,进行排序,将根节点上的数据放到被输出数的孩子树枝上,然后进行交换输出, 。。。由上几步可以得出排序结果 堆排序图示: 构建初始堆: 开始排序: 【代码演示】 public static void sort ( int [] array ) { init ( array ); // 这个过程就是不断的从堆顶移除,调整 for ( int i = 1 ; i < array . length ; i ++) { int temp = array [ 0 ]; int end

Python堆排序

匿名 (未验证) 提交于 2019-12-02 22:51:30
def adjust_deap(arr, p, b): while True: if 2 * p + 1 > b - 1: break elif 2 * p + 2 < b and arr[2 * p + 2] > arr[2 * p + 1] and arr[2 * p + 2] > arr[p]: arr[p], arr[2 * p + 2] = arr[2 * p + 2], arr[p] p = 2 * p + 2 elif arr[2 * p + 1] > arr[p]: arr[p], arr[2 * p + 1] = arr[2 * p + 1], arr[p] p = 2 * p + 1 else: break return arr def create_heap(arr): m = len(arr) / 2 - 1 while m > -1: arr = adjust_deap(arr, m, len(arr)) m -= 1 return arr def heap_sort(arr): m = len(arr) - 1 while m: arr[0], arr[m] = arr[m], arr[0] arr = adjust_deap(arr, 0, m) m -= 1 return arr a = [4, 2, 4, 7, 5, 3, 6, 8, 9, 35,

python_二叉查找树 堆排序 优先级队列

匿名 (未验证) 提交于 2019-12-02 22:11:45
Task5 【二叉树】 实现一个二叉查找树,并且支持插入、删除、查找操作 实现查找二叉查找树中某个节点的后继、前驱节点 实现二叉树前、中、后序以及按层遍历 【堆】 实现一个小顶堆、大顶堆、优先级队列 实现堆排序 利用优先级队列合并 K 个有序数组 求一组动态数据集合的最大 Top K 二叉查找树(内部函数已实现BFS与三种DFS算法): class Node ( object ) : def __init__ ( self , value ) : self . value = value self . lchild = None self . rchild = None class BinarySearchTree ( object ) : def __init__ ( self , value ) : self . root = Node ( value ) def find ( self , value , node , parent , nodetype ) : if node is None : return False , node , parent , nodetype elif node . value == value : return True , node , parent , nodetype elif node . value < value :

堆排序算法

不想你离开。 提交于 2019-12-02 20:04:47
排序---堆排序 一:定义 作为选择排序的改进版,堆排序可以把每一趟元素的比较结果保存下来,以便我们在选择最小/大元素时对已经比较过的元素做出相应的调整。 二:堆排序算法 作为选择排序的改进版,堆排序可以把每一趟元素的比较结果保存下来,以便我们在选择最小/大元素时对已经比较过的元素做出相应的调整。 堆排序是一种树形选择排序,在排序过程中可以把元素看成是一颗完全二叉树,每个节点都大(小)于它的两个子节点,当每个节点都大于等于它的两个子节点时,就称为大顶堆,也叫堆有序; 当每个节点都小于等于它的两个子节点时,就称为小顶堆。 下面是我们要保存在数组中的堆的形式 二:堆排序算法 1.将长度为n的待排序的数组进行堆有序化构造成一个大顶堆 2.将根节点与尾节点交换并输出此时的尾节点 3.将剩余的n -1个节点重新进行堆有序化 4.重复步骤2,步骤3直至构造成一个有序序列 三:图解演示,构造堆(大顶堆) {5, 2, 6, 0, 3, 9, 1, 7, 4, 8} 在构造有序堆时,我们开始只需要扫描一半的元素(n/2-1 ~ 0)即可,为什么? 因为(n/2-1)~0的节点才有子节点,如图1,n=8,(n/2-1) = 3 即3 2 1 0这个四个节点才有子节点 第一次找到[n/2]处,进行构造: 我们比较父节点,左右孩子结点的大小,将最大的作为堆顶 第二次,我们对上次找到位置-1即可

浅谈排序算法之堆排序(5)

◇◆丶佛笑我妖孽 提交于 2019-12-02 11:01:43
近日,笔者忙里偷闲,学习了下堆排序(Heap-Sort)。堆排序算法,就时间复杂度而言,堆排序跟 合并排序 (Merge-Sort)算法是一样的,都是O(n * log(n));就排序方式而言,堆排序跟 插入排序 (Insertion-Sort)一样,都具有空间原址性。 这里首先介绍下堆的概念。堆,或者称为二叉堆,可以看作是一棵近似的 完全二叉树 。在这棵树中,除了最底层以外,该树是完全充满的,而且是从左至右填充的(这里笔者手画了几个栗子)。 在二叉堆中,通常使用两个属性:length表示数组长度,heap_size表述还有多少个元素存储在二叉堆中。二叉堆一般具有两种形式:最大堆和最小堆。在最大堆中,除了根结点以外的所有结点i均满足 A [ parent ( i ) ] >= A [ i ] 即某个结点的值,至多与父结点的值相等,最大堆的最大元素存储在根结点上。而最小堆则满足 A [ parent ( i ) ] <= A [ i ] 即某个结点的值,至少都与父结点的值相等,其最小元素存储在根结点上。 在堆排序算法中,一般考虑实现最大堆。考虑随机数组排序成升序数组的栗子,堆排序算法大致流程如下: 首先将随机数组建成一个最大堆。 从数组最后一位开始向前迭代,直到第二个元素。迭代过程中,将当前最大堆的最大值(数组首)依次从数组最后一位开始向前放置。同时,heap_size自减一

堆排序

若如初见. 提交于 2019-12-02 06:12:20
堆排序 什么是堆? 堆是具有以下性质的完全二叉树: 每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆 或者每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆。 如下图所示: 那么话又说回来了,什么是完全二叉树呢? 要想知道什么是完全二叉树,首先得知道什么满二叉树。 满二叉树 :高度为h,并且由 2^h-1个结点的二叉树,被称为满二叉树,其实不难看出,满二叉树的结点的度要么为0(叶子结点),要么为2(非叶子结点) 完全二叉树 :一棵二叉树中,只有最下面两层结点的度可以小于2,并且最下一层的叶结点集中在靠左的若干位置上。这样的二叉树称为完全二叉树。 特点:叶子结点只能出现在最下层和次下层,且最下层的叶子结点集中在树的左部。显然,一棵满二叉树必定是一棵完全二叉树,而完全二叉树未必是满二叉树。 堆与一维数组的映射关系 同时,我们对堆中的结点按层进行编号,将这种逻辑结构映射到数组中就是下面这个样子 简单的说对于二叉树中的任意一个节点,假设它的下标为i,那么它左孩子的节点在数组中的下标就是2i+1,而其左孩子节点的下标就是2i+2 因此对于大顶堆来说满足一下的条件: 大顶堆:arr[i] >= arr[2i+1] && arr[i] >= arr[2i+2] 对于小顶堆来说满足 小顶堆:arr[i] <= arr[2i+1] && arr[i] <= arr[2i+2] 来源:

2019-2020-1学期 20192406 《网络空间安全专业导论》第三周学习总结

纵饮孤独 提交于 2019-12-01 23:31:49
第六章 低级程序设计语言与伪代码 6.1 计算机操作 我们所用的程序设计语言都必须反映出计算机能够执行的操作类型。让我们通过重述计算机的定义来开始新的讨论:计算机是能够存储、检索和处理数据的可编程电子设备。 这个定义中的操作字包括 可编程的 、 存储 、 检索 和 处理 。上一章指出了数据和操作数据的指令逻辑上是相同的,它们存储在相同的地方。这就是“可编程的”这个词的意义所在。操作数据的指令和数据一起存储在机器中。要改变计算机对数据的处理,只需要改变指令即可。 存储、检索和处理 是计算机能够对数据执行的动作。也就是说,控制单元执行的指令能够把数据 存储 到机器的内存中,在机器内存中 检索 数据,在算术逻辑单元中以某种方式 处理 数据。词语“处理”非常通用。在机器层,处理涉及在数据值上执行算术和逻辑操作。 6.2 机器语言 机器语言 :由计算机直接使用的二进制编码指令构成的语言 Pep/8:一台虚拟机 虚拟机 :为了模拟真实机器的重要特征而设计的假想机器 Pep/8反应的重要特征 回忆第5章中所说的,寄存器是中央处理器中算术/逻辑单元的一小块存储区域,它用来存储特殊的数据和中间值。Pep/8有七个寄存器,我们重点研究其中三个: 程序计数器(PC) , 其中包含下一条即将被执行的指令的地址。 指令寄存器(IR) , 其中包含正在被执行的指令的一个副本。 累加器 (是一个寄存器)。