堆排序(Heap Sort)
堆排序(Heapsort)是指利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种。可以利用数组的特点快速定位指定索引的元素。—百度百科
时间复杂度:最好 O(n)=O(n);平均O(n)=O(nlogn);最差O(n)=O(nlogn)
空间复杂度:O(n)=O(1)
稳定性: 不稳定
堆(Heap)
堆: 顺序储存的完全二叉树,其每个结点均小于等于或大于等于其子节点。
小根堆:每个结点元素的值都小于等于其子节点元素的值的堆。
S[i]<=S[2*i+1] && S[i]<=S[2*i+2]
大根堆:每个结点元素的值都大于等于其子节点元素的值的堆。
S[i]>=S[2*i+1] && S[i]>=S[2*i+2]
堆顶: 序列中第一个元素S[0],为序列中最小值(小根堆)或最大值(大根堆)。
左子节点:S[2*i+1]
右子节点:S[2*i+2]
父节点: S[(i-1)/2]
如下图,有一个数组S[9,6,7,3,1,4]即为一个大根堆。其堆顶为S[0]=9。
算法描述
—wiki
建堆算法
从最后一个非叶节点开始上调整,将最较大的值往上顶。
例:[9,1,5,3,8,7,2,4,6,0]
排序算法
- 将待排序序列调整大根堆。
- 交换堆顶和末尾元素,将堆顶元素(即最大值)抛出,将剩余序列继续步骤1,直到剩余序列大小为零。
例:[9,1,5,3,8,7,2,4,6,0]
示例代码
代码参考自Chimomo
/// <summary>
/// 堆排序 C#
/// </summary>
public static void HeapSort(int[] S){
// 由底向上建 大顶堆
// 由完全二叉树的性质可知,叶子结点是从index=S.Length/2开始,
// 所以从index=(S.Length/2)-1结点开始由底向上进行大根堆的调整。
for (int i = (S.Length / 2) - 1; i >= 0; i--) {
HeapAdjust(S, i, S.Length);
}
// 每一遍循环将堆顶元素(即最大值)抛出到数组末尾,然后堆大小减一,从新建堆
for (int i = S.Length - 1; i > 0; i--) {
S.Swap(0, i); // 将堆顶元素和最后一个元素交换
HeapAdjust(S, 0, i); // 剩余区域建堆
}
}
/// <summary>
/// 将指定的结点调整为堆
/// </summary>
private static void HeapAdjust(int[] S, int i, int heapSize){
int left = (2 * i) + 1; // 左子结点索引
int right = left + 1; // 右子结点索引
int large = i; // 存放大的结点值的索引
// 比较左子结点
if (left < heapSize && S[left] > S[large]) {
large = left;
}
// 比较右子结点
if (right < heapSize && S[right] > S[large]) {
large = right;
}
// 如有子结点大于自身就交换,使大的元素上移
// 并递归该子节点,以保证堆的性质
if (i != large) {
S.Swap(i, large);
HeapAdjust(S, large, heapSize);
}
}
def heap_sort(s): #Python
for i in range(len(s)//2-1, -1, -1):
heap_adjust(s, i, len(s))
for i in range(len(s)-1, 0, -1):
s[0], s[i] = s[i], s[0]
heap_adjust(s, 0, i)
def heap_adjust(s, i, size):
left = 2 * i + 1
right = left + 1
large = i
if left < size and s[left] > s[large]:
large = left
if right < size and s[right] > s[large]:
large = right
if i != large:
s[i], s[large] = s[large], s[i]
heap_adjust(s, large, size)
文中若有什么错误,欢迎留言指正。
转载请保留出处:http://blog.csdn.net/x1060549/article/details/78792704