堆排序

排序算法之堆排序

删除回忆录丶 提交于 2019-12-28 04:01:48
1)基本思想 堆排序的基本思想基于优先队列,对于一个无序数组,首先构造出最小堆,然后每一次删除顶点处最小的元素,这样依次删除就可以得到一个降序排列的数组。在此过程中,如将删除的元素依次赋给一个数组,那么最终得到的是一个增序排列的数组,但是需要额外的数组空间。为了减少空间消耗,可以利用堆删除元素之后并重新构造之后的最后一个位置来存放刚刚删除的元素,最终得到的是一个降序数组。为了得到增序排列的数组,可以将最小堆改为最大堆,即顶点处的元素是最大的,称为maxHeap. 示例如下,首先删除顶点处元素97,并将最后一个元素移至顶点处,并重新构造最大堆: 2)算法实现 1 #include "stdafx.h" 2 #include <iostream> 3 using namespace std; 4 5 void print(int A[], int n) 6 { 7 for(int i = 0; i < n; i++) 8 { 9 cout<<A[i]<<" "; 10 } 11 cout<<endl; 12 } 13 14 void HeapDown(int A[], int i, int n) 15 { 16 int child; 17 int temp = A[i]; 18 for(; 2 * i + 1 < n; i = child) 19 { 20 child = 2 * i

堆排序

前提是你 提交于 2019-12-28 04:01:36
一、堆的概念:   堆是一种数据结构,是一棵像这样的完全二叉树,其任何一非叶节点的关键字不大于或者不小于其左右孩子节点的关键字。堆分为大顶堆和小顶堆,满足Key[i]>=Key[2i+1]&&key>=key[2i+2]称为大顶堆,满足 Key[i]<=key[2i+1]&&Key[i]<=key[2i+2]称为小顶堆。Java中的优先队列PriorityQueue就是基于堆这种数据结构来实现的。 二、堆排序的思想:   堆排序主要分为两步,建立初始堆,以及移除堆顶元素后的调整,我们以大顶堆为例描述,假设存在整型数组int[] R,数组中有n个元素,那么其堆排序思想如下:   1、将初始待排序关键字序列(R0,R2....Rn-1)构建成大顶堆,此堆为初始的无序区;   2、将堆顶元素R[0]与最后一个元素R[n-1]交换,此时得到新的无序区(R0,R2,......Rn-2)和新的有序区(Rn-1),且满足R[0,2...n-2]<=R[n-1];   3、由于交换后新的堆顶R[0]可能违反堆的性质,因此需要对当前无序区(R0,R2,......Rn-2)调整为新堆,然后再次将R[0]与无序区最后一个元素交换,     得到新的无序区(R0,R2....Rn-3)和新的有序区(Rn-2,Rn-1)。不断重复此过程直到有序区的元素个数为n-1,则整个排序过程完成。 三

堆排序

送分小仙女□ 提交于 2019-12-28 04:01:22
堆排序   堆排序是利用 堆 这种数据结构而设计的一种排序算法,堆排序是一种 选择排序, 它的最坏,最好,平均时间复杂度均为O(nlogn),它也是不稳定排序。首先简单了解下堆结构。 堆    堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆;或者每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆。如下图: 同时,我们对堆中的结点按层进行编号,将这种逻辑结构映射到数组中就是下面这个样子 该数组从逻辑上讲就是一个堆结构,我们用简单的公式来描述一下堆的定义就是: 大顶堆:arr[i] >= arr[2i+1] && arr[i] >= arr[2i+2] 小顶堆:arr[i] <= arr[2i+1] && arr[i] <= arr[2i+2] ok,了解了这些定义。接下来,我们来看看堆排序的基本思想及基本步骤: 堆排序基本思想及步骤 堆排序的基本思想是:将待排序序列构造成一个大顶堆,此时,整个序列的最大值就是堆顶的根节点。将其与末尾元素进行交换,此时末尾就为最大值。然后将剩余n-1个元素重新构造成一个堆,这样会得到n个元素的次小值。如此反复执行,便能得到一个有序序列了 来源: https://www.cnblogs.com/pacino12134/p/11038480.html

007-排序算法-堆排序

不羁的心 提交于 2019-12-28 04:01:10
一、概述   堆排序(英语:Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。 排序方法 时间复杂度(平均) 时间复杂度 (最坏) 时间复杂度(最好) 空间复杂度 稳定性 堆排序 $O(nlogn)$ O(nlogn) O(nlogn) O(1) 不稳定   在堆的数据结构中,堆中的最大值总是位于根节点(在优先队列中使用堆的话堆中的最小值位于根节点)。堆中定义以下几种操作: 最大堆调整(Max Heapify):将堆的末端子节点作调整,使得子节点永远小于父节点 创建最大堆(Build Max Heap):将堆中的所有数据重新排序 堆排序(HeapSort):移除位在第一个数据的根节点,并做最大堆调整的递归运算 1.1、说明      不断将大根堆的堆顶元素与堆尾元素交换,再重建大根堆的过程。将待排序列构建成大根堆,用变量 heapSize 来控制堆的大小,然后不断地 heapify ,直到 heapSize 等于零。在 heapify 的过程中就是先比较子节点的大小,然后比较父节点和子节点的大小,如果最后发现父节点是比子节点大的话跳出 heapify 循环,否则将子节点与父节点交换,并且找到子节点的左孩子,再重复上诉过程,直到左孩子的位置 left 大于

堆排序

梦想与她 提交于 2019-12-28 04:01:02
1.算法步骤: 根据初始输入数据,利用堆的调整算法siftDown()形成初始堆; 通过一系列的元素交换和重新调整堆进行排序。 2.代码实现: public static void heapSort(int[] arr){   for(int i=(arr.length-2)/2;i>=0;i--){     siftDown(arr,i,arr.length-1);//从最后一个非叶节点开始,自上向下比较,形成最大堆   }   for(int i=arr.length-1;i>=0;i--){//从最后一个元素开始,将堆顶元素(即最大)与当前位置元素交换,同时保持当前位置以前的元素构成最大堆     int tmp=arr[i];     arr[i]=arr[0];     arr[0]=tmp;     siftDown(arr,0,i-1);   } } public static void siftDown(int[] arr,int start,int end){   int i=start,j=2*i+1;   while(j<=end){     int tmp=arr[i];     if(j<end&&arr[j]<arr[j+1])       j++;     if(tmp>=arr[j]){       break;     }     else{   

堆排序

僤鯓⒐⒋嵵緔 提交于 2019-12-28 04:00:47
http://www.cnblogs.com/skywang12345/p/3602162.html 堆是一种数据结构,其约束(根节点大于左右子节点——大根堆,根节点小于左右子节点——小根堆),一般用完全二叉树表示,用数组直接存储 堆排序包括两部分:1,构造堆,保证堆的性质 2,输出根节点,并调整堆(将根节点与叶子节点调换,堆的性质被打破)使得余下的节点使其仍然构成堆 堆的插入删除 堆的插入:每次插入都是将新数据放在数组最后。可以发现从这个新数据的父结点到根结点必然为一个有序的数列,现在的任务是将这个新数据插入到这个有序数据中——这就类似于 直接插入排序 中将一个数据并入到有序区间中 // 新加入i结点 其父结点为(i - 1) / 2 void MinHeapFixup(int a[], int i) { int j, temp; temp = a[i]; j = (i - 1) / 2; //父结点 while (j >= 0 && i != 0) { if (a[j] <= temp) break; a[i] = a[j]; //把较大的子结点往下移动,替换它的子结点 i = j; j = (i - 1) / 2; } a[i] = temp; } void MinHeapFixup(int a[], int i) { for (int j = (i - 1) / 2; (j

堆排序

半腔热情 提交于 2019-12-28 04:00:32
/** * 堆排序:Java */ public class HeapSort { /* * (最大)堆的向下调整算法 * * 注:数组实现的堆中,第N个节点的左孩子的索引值是(2N+1),右孩子的索引是(2N+2)。 * 其中,N为数组下标索引值,如数组中第1个数对应的N为0。 * * 参数说明: * a -- 待排序的数组 * start -- 被下调节点的起始位置(一般为0,表示从第1个开始) * end -- 截至范围(一般为数组中最后一个元素的索引) */ public static void maxHeapDown(int[] a, int start, int end) { int c = start; // 当前(current)节点的位置 int l = 2*c + 1; // 左(left)孩子的位置 int tmp = a[c]; // 当前(current)节点的大小 for (; l <= end; c=l,l=2*l+1) { // "l"是左孩子,"l+1"是右孩子 if ( l < end && a[l] < a[l+1]) l++; // 左右两孩子中选择较大者,即m_heap[l+1] if (tmp >= a[l]) break; // 调整结束 else { // 交换值 a[c] = a[l]; a[l]= tmp; } } } /* *

排序算法___堆排序

左心房为你撑大大i 提交于 2019-12-28 04:00:15
/** * 堆排序:Java * * @author skywang * @date 2014/03/11 */ public class HeapSort { /* * (最大)堆的向下调整算法 * * 注:数组实现的堆中,第N个节点的左孩子的索引值是(2N+1),右孩子的索引是(2N+2)。 * 其中,N为数组下标索引值,如数组中第1个数对应的N为0。 * * 参数说明: * a -- 待排序的数组 * start -- 被下调节点的起始位置(一般为0,表示从第1个开始) * end -- 截至范围(一般为数组中最后一个元素的索引) */ public static void maxHeapDown(int[] a, int start, int end) { int c = start; // 当前(current)节点的位置 int l = 2*c + 1; // 左(left)孩子的位置 int tmp = a[c]; // 当前(current)节点的大小 for (; l <= end; c=l,l=2*l+1) { // "l"是左孩子,"l+1"是右孩子 if ( l < end && a[l] < a[l+1]) l++; // 左右两孩子中选择较大者,即m_heap[l+1] if (tmp >= a[l]) break; // 调整结束 else { //

Python标准库模块之heapq

对着背影说爱祢 提交于 2019-12-26 08:35:34
功能:该模块提供了堆排序算法的实现,比如排序算法,就可以用这个实现啦 1. 创建堆 heapq有两种方式创建堆 一种是使用一个空列表,然后使用heapq.heappush()函数把值加入堆中, 另外一种就是使用heap.heapify(list)转换列表成为堆结构 import heapq # 第一种 """函数定义: heapq.heappush(heap, item) - Push the value item onto the heap, maintaining the heap invariant. heapq.heappop(heap) - Pop and return the smallest item from the heap, maintaining the heap invariant. If the heap is empty, IndexError is raised. To access the smallest item without popping it, use heap[0]. """ nums = [2, 3, 5, 1, 54, 23, 132] heap = [] for num in nums: heapq.heappush(heap, num) # 加入堆 print(heap[0]) # 如果只是想获取最小值而不是弹出,使用heap

选择排序

人盡茶涼 提交于 2019-12-26 05:34:07
原理:每一趟从待排序的记录中选出最小的元素,顺序放在已排序好的序列最后,直到全部记录排序完毕。基于此思想的算法主要有简单选择排序、树形选择排序和堆排序(这里只介绍常用的简单选择排序); 简单选择排序的基本思想:给定数组int arr={里面n个数据};,第1趟排序,在待排序数据arr[1]~arr[n]中选出最小的数据,将它与arr[1]交换;第2趟,在待排序数据arr[2]~arr[n]中选出最小的数据,将它与arr[2]交换;以此类推,第i趟在待排序数据arr[i]~arr[n]中选出最小数据,将它与arr[i]交换,直到全部排序完成; 举例:数组 int[] arr={5 2 8 4 9 1} 第一趟排序: 最小数据1,把1放在首位,排序结果:1 2 8 4 9 5 第二趟排序: 最小数据2,排序结果:1 2 8 4 9 5 第三趟排序: 最小数据4,排序结果:1 2 4 8 9 5 第四趟排序: 最小数据5,排序结果:1 2 4 5 9 8 第五趟排序: 最小数据8,排序结果:1 2 4 5 8 9 注:每一趟排序获得最小数的方法:for循环进行比较,定义一个第三个变量tmp,首先前两个数比较,把较小的数放在tmp中,然后用tmp再去跟剩下的数据比较,如果出现比tmp小的数据,就用它代替tmp中原有的数据; 示例代码: public class Test { public