堆排序
2016-09-03 21:43
141 查看
堆排序(Heapsort)是指利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种。
可以利用数组的特点快速定位指定索引的元素。堆分为大根堆和小根堆,是完全二叉树。大根堆的要求是每个节点的值都不大于其父节点的值,即A[PARENT[i]] >= A[i]。
在数组的非降序排序中,需要使用的就是大根堆,因为根据大根堆的要求可知,最大的值一定在堆顶。
堆排序首先将待排序的数组存入堆中,并将堆构造为最大/最小堆。再依次从堆中取出堆顶元素,从而得到有序数组。
构造堆时,所用的方法为从最底层有子节点的节点开始依次向上处理。
取出顶元素恢复堆时则是先将末尾元素与顶元素交换位置,在对顶元素进行下沉处理即可。
堆排序是不稳定排序。即相同的元素再经过堆排序后,其先后位置可能发生变化。
堆排序的时间复杂度为N*logN。
Python的代码实现如下:
可以利用数组的特点快速定位指定索引的元素。堆分为大根堆和小根堆,是完全二叉树。大根堆的要求是每个节点的值都不大于其父节点的值,即A[PARENT[i]] >= A[i]。
在数组的非降序排序中,需要使用的就是大根堆,因为根据大根堆的要求可知,最大的值一定在堆顶。
堆排序首先将待排序的数组存入堆中,并将堆构造为最大/最小堆。再依次从堆中取出堆顶元素,从而得到有序数组。
构造堆时,所用的方法为从最底层有子节点的节点开始依次向上处理。
取出顶元素恢复堆时则是先将末尾元素与顶元素交换位置,在对顶元素进行下沉处理即可。
堆排序是不稳定排序。即相同的元素再经过堆排序后,其先后位置可能发生变化。
堆排序的时间复杂度为N*logN。
Python的代码实现如下:
# -*- coding: utf-8 -*- #用列表表示一个堆,其中列表中索引为0的位置为空。从索引1开始存放元素。 def parent(i): #在堆中,某个节点的父节点为其索引值整除2。例如索引为4的父节点的索引为2。索引为9的父节点的索引为4。 return i/2 def left(i): #某个节点的左子节点的索引为i*2 return i*2 def right(i): #某个节点的右子节点的索引为i*2+1 return i*2+1 class Heap: #堆的数据结构类 def __init__(self, heapList=[None]): #对堆进行初始化。没有给堆初始列表时,初始化为仅包含一个None元素的列表。 self.heapList = [None] + heapList #有初始化列表时,堆列表为初始化列表前插入None元素 def max_heapfy(self, i): #表明对i节点进行最大堆恢复 if (i*2) > self.length-1: #该元素没有子节点时 maxIndex = i elif (i*2+1) > self.length-1: #该元素只有左节点时 maxIndex = left(i) elif self.heapList[left(i)] > self.heapList[right(i)]: #该元素同时有左右节点,且左节点的值大于右节点时 maxIndex = left(i) else: #该元素同时有左右节点,且左节点的值小于右节点时 maxIndex = right(i) if self.heapList[i] < self.heapList[maxIndex]: #当其子节点值大于其节点值时: self.heapList[i], self.heapList[maxIndex] = self.heapList[maxIndex], self.heapList[i] #交换其子节点的值和其值 self.max_heapfy(maxIndex) #并对其子节点进行最大堆化 def build_max_heap(self): #构建最大堆 self.length = len(self.heapList) #计算堆的大小(包含第一个空元素) for i in range(self.length/2, 0, -1): #从包含子节点的节点开始依次向上遍历 self.max_heapfy(i) def insert(self, k): #向堆内插入元素 self.length += 1 #堆的规模加1 self.heapList.append(float("-inf")) #向堆内插入一个负无穷的数 self.increase_key(self.length, k) #增加元素 def maxinum(self): #查询堆内最大元素,即为索引为1的元素值。 return self.heapList[1] def extract_max(self): #弹出堆内最大元素。 maxValue = self.heapList[1] #取得最大元素值 self.heapList[1] = self.heapList[self.length] #将末尾元素移至堆头 del self.heapList[self.length] #删除末尾元素 self.length -= 1 #将堆的规模减1 self.max_heapfy(1) #对堆顶元素最大堆化 return maxValue def increase_key(self, x, k): #增加元素 self.heapList[x] = k #将新增的负无穷位置赋予插入值 while x > 1 and self.heapList[parent(x)] < self.heapList[x]: #当元素索引大于1且其值大于其父节点值 self.heapList[parent(x)], self.heapList[x] = self.heapList[x], self.heapList[parent(x)] #交换其值和其父节点的值 x = parent(x) #继续对其父节点进行判断 def show(self): #展示堆 print "the length of queue is", self.length - 1 print "the heapList is", self.heapList[1:] def heapSort(unsortedList): heap = Heap(unsortedList) #将乱序列表转换为堆 heap.build_max_heap() #将堆构建为最大堆 print heap.heapList print "*************heap has been build up*********" for i in range(len(unsortedList), 1, -1): heap.heapList[i], heap.heapList[1] = heap.heapList[1], heap.heapList[i] #将末尾节点与根节点进行交换, #交换完成后,i位置的节点为当前堆中最大的元素。即每次循环中得到的i索引的元素为已有序的列表。 heap.length -= 1 #未排序的堆的规模减小1 heap.max_heapfy(1) #此时,根节点不满足最大堆的要求,需要对堆进行最大堆恢复 return heap.heapList[1:] if __name__ == '__main__': list1 = [3,2,4,6,7,5,1,8,10,9] list2 = ["wang", "zhe", "tian", "jin", "da", "xue"] ordered_list1 = heapSort(list1) ordered_list2 = heapSort(list2) print ordered_list1 #[2, 3, 4, 5, 6, 7] print ordered_list2 #['da', 'jin', 'tian', 'wang', 'xue', 'zhe']
相关文章推荐
- 堆和堆排序
- 10种算法原理(冒泡排序,选择排序,快速排序,堆排序,希尔排序,桶排序等)
- STL算法,堆排序
- 白话经典算法系列之七 堆与堆排序
- 常见排序算法总结与实现(冒泡、插入、选择、希尔、堆排序、归并、快排)
- 堆排序java实现
- 6种排序算法及其比较 简单选择排序,堆排序,简单插入排序,希尔排序,冒泡排序,快速排序,归并排序
- 堆排序 Heap Sort
- 堆排序
- 堆排序原理及实现
- java 堆排序
- 选择排序---简单选择排序 堆排序
- 排序算法08:优先队列与堆排序
- 最大堆排序
- 数据结构基础加强之最小堆的实现与堆排序
- 排序--堆排序
- hdu 1280 堆排序
- c++实现最大堆建立(链表结构)和堆排序
- 堆排序详解
- 排序 堆排序