堆排序-Heap Sort
2017-09-22 11:29
344 查看
坐在宿舍敲代码,楼下大一新生在军训
当初我们整齐的口号,嘹亮的军歌
是否也触动了哪位老学长
有人来,就得有人走,
人来人往,这样的更迭交替
不过是毅种循环
我们发现了一个规律:堆的左孩子和右孩子在数组中对应的下标分别为2i+1和2i+2。
代码如下:
下面是对于数组arr[] = {76,32,14,86,40,98,18,57,13,20,85};进行堆排序的过程:
整个逻辑分为两个部分:
第一部分,先将数组转化为最大值堆:
初始:i= sz/2-1,即i=4;
上面是用max_heap(arr,4,10)把arr[4…10]调整为最大堆 ,即把arr[4]和它两个孩子(arr[9]和arr[10])中较大值进行交换。
i=3时,父节点87比57和13都大,因此不交换。
i=2时,14和98交换。
i=1时,32和86交换。
i=0时,76和98交换。
此过程完成后 , 数组变成了一个最大值堆。如下图:
第二部分,进行数据交换,把最大堆数组变为有序数组
先把数组第一个元素(根结点)和最后一个元素交换
交换后:
交换完成后,对于arr[10],我们就不要再理它了,孤立它,把arr[0….9]调整为最大堆:
当n=9时,孤立86,调整arr[0…8],此时arr[9..10]是有序的
...
...
依次类推,直到整个数组有序。
堆排序的时间复杂度为O(nlgn),并且堆排序不是稳定的算法。
当初我们整齐的口号,嘹亮的军歌
是否也触动了哪位老学长
有人来,就得有人走,
人来人往,这样的更迭交替
不过是毅种循环
什么是堆?
堆一棵二叉树,其子结点的值通常都小(大)于父结点。根结点是树中的最大(小)结点,其中,子结点比父结点小的堆称为最大值堆,相反的被称为最小值堆。对与一个堆,我们可以用层序遍历的方式将它连续储存在一个数组中。我们发现了一个规律:堆的左孩子和右孩子在数组中对应的下标分别为2i+1和2i+2。
堆排序
我们可以利用堆的特点来完成排序,对于一个最大值堆,其根结点总是最大的,把根结点拿出来放到数组最后一个位置,然后再把数组前面的元素重新调整为最大值堆,如此反复执行直到排序结束。代码如下:
void max_heap(int *arr,int start,int end)//调整为一个最大值堆 { int i,j,tmp; i = start,tmp = arr[i]; for(j=2*i+1; j<=end; j*=2) { while(j<end && arr[j]<arr[j+1])//让j指向左孩子和右孩子中大的那个 j++; if(tmp >= arr[j]) break; else { arr[i] = arr[j]; arr[j] = tmp; } i = j; } } void heap_sort(int *arr,int sz) { int i; for(i=sz/2-1; i>=0; i--) //调整数组为最大值堆 max_heap(arr,i,sz-1); for(i=sz-1; i>0; i--)//拿出根结点放到最后位置,然后进行调整 { int tmp = arr[0]; arr[0] = arr[i]; arr[i] = tmp; max_heap(arr,0,i-1); } } int main() { int i; int arr[] = {76,32,14,86,40,98,18,57,13,20,85}; int sz = sizeof(arr)/sizeof(arr[0]); heap_sort(arr,sz); for(i=0; i<sz; i++) printf("%d ",arr[i]); return 0; }
下面是对于数组arr[] = {76,32,14,86,40,98,18,57,13,20,85};进行堆排序的过程:
整个逻辑分为两个部分:
第一部分,先将数组转化为最大值堆:
初始:i= sz/2-1,即i=4;
上面是用max_heap(arr,4,10)把arr[4…10]调整为最大堆 ,即把arr[4]和它两个孩子(arr[9]和arr[10])中较大值进行交换。
i=3时,父节点87比57和13都大,因此不交换。
i=2时,14和98交换。
i=1时,32和86交换。
i=0时,76和98交换。
此过程完成后 , 数组变成了一个最大值堆。如下图:
第二部分,进行数据交换,把最大堆数组变为有序数组
先把数组第一个元素(根结点)和最后一个元素交换
交换后:
交换完成后,对于arr[10],我们就不要再理它了,孤立它,把arr[0….9]调整为最大堆:
当n=9时,孤立86,调整arr[0…8],此时arr[9..10]是有序的
...
...
依次类推,直到整个数组有序。
堆排序的时间复杂度为O(nlgn),并且堆排序不是稳定的算法。
相关文章推荐
- 【算法导论学习-013】堆排序(Heapsort)
- 排序算法之堆排序(Heapsort)解析
- PAT 1098. Insertion or Heap Sort (25) 堆排序和插入排序
- [硕.Love Python] HeapSort(堆排序)
- HeapSort——堆排序实现(算法类)
- js算法:heap sort 使用堆排序
- 堆排序 Heap Sort
- 堆排序(heapsort)
- 排序算法系列:堆排序(heapsort)(C语言)
- 堆排序(HeapSort)
- 排序1+4:归并排序(MergeSort)和堆排序(HeapSort)
- 堆排序(Heap Sort)
- 堆排序(Heap Sort) 算法实现 C语言版
- [硕.Love Python] HeapSort(堆排序)
- 排序算法之堆排序(HeapSort)
- 堆排序heapSort
- 堆排序(heap-sort)小结
- 堆排序(HEAPSORT)
- 堆排序(heap sort)
- 堆排序(HeapSort)之java实现