堆排序

python实现堆排序

倾然丶 夕夏残阳落幕 提交于 2019-11-29 17:33:36
直接放代码,对堆概念模糊者请自行查询! #python实现堆排序 def heapify ( arr , n , i ) : largest = i left = 2 * i + 1 right = 2 * i + 2 if left < n and arr [ largest ] < arr [ left ] : largest = left if right < n and arr [ largest ] < arr [ right ] : largest = right if largest != i : arr [ largest ] , arr [ i ] = arr [ i ] , arr [ largest ] #python是地址引用,交换 heapify ( arr , n , largest ) #下沉式调整 def heapsort ( arr ) : n = len ( arr ) for i in range ( n - 1 , - 1 , - 1 ) : heapify ( arr , n , i ) #将序列构造成大根堆 #把最大值交换到最后位置,再重新调整为堆,升序排列 for i in range ( n - 1 , 0 , - 1 ) : arr [ i ] , arr [ 0 ] = arr [ 0 ] , arr [ i ] heapify

数据结构与算法之排序详解 一点课堂(多岸学院)

时光毁灭记忆、已成空白 提交于 2019-11-29 15:20:18
通过前面的知识,我们已经知道,有序的数据在查找时有极大的性能提升。很多查找都基于有序数据,但并不是所有的结构都能像二叉排序树一样,在插入数据时就已经排好序,很多时候往往是无序的数据,需要我们使用时再进行排序,这就意味着我们需要寻找高效率的排序算法。接下来,我们对当下使用较为普遍的几个算法逐一进行分析。这里推荐一个可以查看算法运行动态过程的网站,加深对算法原理的理解。 基础知识 排序定义 假设含有n个记录的序列为{r1. r2, ..., rn},其相应的关键字分别为{k1, k2, ..., kn},需确定1, 2, ..., n的一种排列p1, p2, ..., pn,使其相应的关键字满足kp1≤kp2≤...≤kpn(非递减或非递增) 关系,即使得序列成为一个按关键字有序的序列{rp1, rp2, ..., rpn} , 这样的操作就称为排序。 稳定性 假设ki=kj( 1≤i≤n, 1≤j≤ n, i≠j ) ,且在排序前的序列中 ri 领先于 rj (即i<j) 。如果排序后 ri 仍领先于 rj,则称所用的排序方法是稳定的;反之,若可能使得排序后的序列中 rj 领先 ri,则称所用的排序方法是不稳定的。 简单来说,就是对于原数据中相等的数据,排序前后如果相对位置没有改变,就是稳定的。 内排序与外排序 内排序是在排序整个过程中,待排序的所有记录全部被放置在内存中

游戏开发面试总结2

风流意气都作罢 提交于 2019-11-29 15:04:29
总结一些面试常问的吧 1:聊一聊虚函数吧 C++中,虚函数主要是实现了多态机制,简而言之就是 用父类型的指针指向了子类型的实例,然后通过父类的指针去调用子类的成员函数。 每一个含有虚函数的类都至少有一个与之对应的虚函数表,存放着这个类所由虚函数对应的函数指针。 虚函数表在构建的过程中的步骤:    1:拷贝基类的虚函数表   2:替换重写的虚函数指针   3:追加子类的虚函数指针 这些步骤是编译器完成的 2: 虚析构函数:虚析构函数使得在删除指向子类对象的基类指针的时候可以调用子类的析构函数达到释放子类中堆内存的目的,防止内存泄漏 当delete父类的指针时,由于子类的析构函数和父类的析构函数形成多态,所以先调用子类的析构函数再调用父类的析构函数 。 纯虚函数:形式为virtual void fun() = 0; 不需要实现,因为不会被调用到 抽象基类:至少有一个纯虚函数的类,抽象基类不能产生改类的对象,但是可以有这个类的指针或者引用;子类中必须将纯虚函数实现,否则子类也是抽象基类 3: 聊一聊堆排序吧 堆排序分为两个步骤:   1:根据初始的输入数据,进行HeapAdjust形成初始堆     复杂度为O(n),包括比较和交换 公式可以写为s = 2^( i - 1 ) * ( k - i ),2^( i - 1) 表示该层上有多少个元素,( k - i)

十大排序算法之堆排序

流过昼夜 提交于 2019-11-29 10:18:23
例题: 对a[]={3,44,38,5,47,15,36,26,27,2,46,4,19,50,48}排序 要求从小到大排列。 引入新知识: 这个排序要涉及到数据结构中一个满二叉树的概念 先说二叉树的概念: 每个父节点最多拥有两个子节点的树为二叉树 满二叉树的概念: 除最后一层无任何子节点外,每一层上的所有结点都有两个子结点的二叉树。 来源: https://blog.csdn.net/qq_43652327/article/details/100780738

十种常见排序算法

寵の児 提交于 2019-11-29 08:58:49
1.常见排序算法分类 常见排序算法一般分为以下几种: (1)非线性时间比较类排序:交换类排序(快速排序和冒泡排序)、插入类排序(简单插入排序和希尔排序)、选择类排序(简单选择排序和堆排序)、归并排序(二路归并排序和多路归并排序); (2)线性时间非比较类排序:计数排序、基数排序和桶排序。 在比较类排序中,归并排序最快,其次是快速排序和堆排序,两者不相伯仲,但是有一点需要注意,数据初始排序状态对堆排序不会产生太大的影响,而快速排序却恰恰相反。 线性时间非比较类排序一般要优于非线性时间比较类排序,但前者对待排序元素的要求较为严格,比如计数排序要求待排序数的最大值不能太大,桶排序要求元素按照hash分桶后桶内元素的数量要均匀。线性时间非比较类排序的典型特点是以空间换时间。 注意: 本文所有示例代码均为递增排序。 2.算法描述与实现 2.1交换类排序 交换排序的基本方法是:两两比较待排序记录的排序码,交换不满足顺序要求的偶对,直到全部满足位置。常见的冒泡排序和快速排序就属于交换类排序。 2.1.1冒泡排序 算法思想: 从数组中第一个数开始,依次遍历数组中的每一个数,通过相邻比较交换,每一轮循环下来找出剩余未排序数的中的最大数并"冒泡"至数列的顶端。 算法步骤: (1)从数组中第一个数开始,依次与下一个数比较并次交换比自己小的数,直到最后一个数。如果发生交换,则继续下面的步骤,如果未发生交换

Mysql 排序优化与索引使用(转)

心不动则不痛 提交于 2019-11-29 08:20:48
为了优化SQL语句的排序性能,最好的情况是避免排序,合理利用索引是一个不错的方法。因为索引本身也是有序的,如果在需要排序的字段上面建立了合适的索引,那么就可以跳过排序的过程,提高SQL的查询速度。下面我通过一些典型的SQL来说明哪些SQL可以利用索引减少排序,哪些SQL不能。假设t1表存在索引key1(key_part1,key_part2),key2(key2) a.可以利用索引避免排序的SQL 1 2 3 4 SELECT * FROM t1 ORDER BY key_part1,key_part2; SELECT * FROM t1 WHERE key_part1 = constant ORDER BY key_part2; SELECT * FROM t1 WHERE key_part1 > constant ORDER BY key_part1 ASC ; SELECT * FROM t1 WHERE key_part1 = constant1 AND key_part2 > constant2 ORDER BY key_part2; b.不能利用索引避免排序的SQL 1 2 3 4 5 6 7 8 9 10 11 //排序字段在多个索引中,无法使用索引排序 SELECT * FROM t1 ORDER BY key_part1,key_part2, key2; /

Python堆排序

亡梦爱人 提交于 2019-11-29 07:32:21
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,

堆排序基本思路

三世轮回 提交于 2019-11-29 07:22:16
堆排序的基本思路:   a.将无需序列构建成一个堆,根据升序降序需求选择大顶堆或小顶堆;   b.将堆顶元素与末尾元素交换,将最大元素"沉"到数组末端;   c.重新调整结构,使其满足堆定义,然后继续交换堆顶元素与当前末尾元素,反复执行调整+交换步骤,直到整个序列有序。 来源: https://my.oschina.net/u/4177395/blog/3102142

算法之堆排序

∥☆過路亽.° 提交于 2019-11-29 06:30:53
要求:从小到大排序 思路:先将数组构建成大顶堆, 然后依次“删除”顶部元素 到末尾 /** * “下沉”操作 ,如果构建大顶堆,将小的下沉;如果构建小顶堆,将大的下沉;这里是将小的下沉 * 由于从底部开始调整,,下面的已经是大顶堆了 * @param array 待调整的数组(堆) * @param parentIndex 父节点 * @param lastIndex 最大位置 */ public static void downAdjust ( int [ ] array , int parentIndex , int lastIndex ) { // 保存父节点的值,用于进行最后的替换你 int tmp = array [ parentIndex ] ; // 获取子节点位置 int biggerChildIndex = 2 * parentIndex + 1 ; while ( biggerChildIndex <= lastIndex ) { // 看一下左右子节点那个更大,将biggerChildIndex指向更大那个 if ( biggerChildIndex + 1 < lastIndex && array [ biggerChildIndex + 1 ] > array [ biggerChildIndex ] ) { biggerChildIndex ++ ; }

容器适配器————heap

萝らか妹 提交于 2019-11-29 03:21:07
堆(heaps)不是容器,而是一种特别的数据组织方式。堆一般用来保存序列容器 。 堆是一个完全二叉树,每个节点与其子节点位置相对。父节点总是大于或等于子节点,这种情况下被叫作大顶堆,或者父节点总是小于或等于子节点,这种情况下叫作小顶堆。注意,给定父节点的子节点不一定按顺序排列。 创建堆 用来创建堆的函数定义在头文件 algorithm 中。max_heap() 对 随机访问迭代器 指定的一段元素重新排列,生成一个堆。默认使用的是 < 运算符,可以生成一个大顶堆。 make_heap(iterator first,iterator last);//将[first,last)范围进行堆排序,默认less<int>(),降序 make_heap(iterator first,iterator last,less<int>()); make_heap(iterator first,iterator last,greater<int>());//升序 堆操作 堆不是容器,而是组织容器元素的一种特别方式。只能确定堆的范围,即开始和结束 迭代器 指定的范围。这意味着可以用容器中的元素子序列创建堆。可以在已生成的堆中添加元素。 pop_heap() 将front移动到end前一位,即末尾,然后将剩下的元素重新堆排序成一个新heap,使用的规则要个make_heap一样。 pop_heap