您的位置:首页 > 其它

堆排序

2017-05-18 07:37 204 查看

选择排序:

void Selection_Sort(ElementType A[], int N)
{
int i, MinPosition;
for (i = 0; i < N; i++) {
MinPosition = scanForMin(A, i, N-1);
//从A[i]到A[N-1]中找最小元
Swap(&A[i], A[MinPosition])
}
}

  关键是找最小元的一步 普通选择排序都看一遍 时间复杂度O(N^2)

  可用最小堆来优化 使时间复杂度降为O(NlogN)

算法1:

void Heap_Sort(ElementType A[], int N)
{
BuildHeap(A);  //O(N)
for (i = 0; i < N; i++)
Tmp[i] = DeleteMin(A); //O(logN)
for (i = 0; i < N; i++)  //O(N)
A[i] = TmpA[i];
}

  T(N) = O(NlogN)

  问题:需要额外O(N)空间 且复制元素需要时间

算法2:

  

  调成最大堆 每次把最大的放到最后位置 堆的规模减1 然后调整最大堆

  定理:堆排序处理N个不同元素的随机排列的平均比较次数是 2NlogN - O(Nlog logN)

  虽然堆排序给出了最佳平均时间复杂度 但实际效果不如用Sedgewick增量序列的Shell Sort

void Swap(ElementType *a, ElementType *b)
{
ElementType t = *a; *a = *b; *b = t;
}

void PercDown(ElementType A[], int p, int N)
{
int Parent, Child;
ElementType X;

X = A

; for (Parent = p; (Parent*2+1) < N; Parent = Child) { Child = Parent*2 + 1; if ( (Child!= N-1) && (A[Child] < A[Child+1]) ) Child++; if (X >= A[Child]) break; else A[Parent] = A[Child]; } A[Parent] = X; } void HeapSort(ElementType A[], int N) { int i; for (i = N/2-1; i >= 0; i--) PercDown(A, i, N); //建立最大堆 for (i = N-1; i > 0; i--) { Swap(&A[0], &A[i]); PercDown(A, 0, i); } }

[p]时间复杂度: 

  平均O(Nlog2N) 最坏O(Nlog2N) 不稳定

PTA结果:

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: