继前边的《排序算法(一)》之后,排序算法(二)就要诞生啦!!这篇文章主要来分析堆排序。在上篇文章《堆&
优先级队列》中,我们分析了建堆,插入元素,删除元素的时间复杂度。这里复习一次。
建堆:O(N*lgN)
插入:O(lgN)
删除:O(lgN)
也分析了为什么优先级队列的底层要用堆!!如果上篇关于堆的文章看懂之后,下边的堆排序就比较好写了。
我们知道堆的特点是:第一个元素要么是最大值(大堆),要么是最小值(小堆),这样在排序的时候,直接将第一个
元素和最后一个元素进行交换,然后从第一个元素开始进行向下调整。
所以,如果需要升序,就建一个大堆,需要降序,就建一个小堆。
下边用图片再来说明这样一个过程:
【实现代码】
#include<iostream>
using namespace std;
void AdjustDown(int a[],size_t i,size_t len)
{
assert(a && i >= 0 && len > 0);
size_t parent = i;
size_t child = 2 * parent + 1;
while (child < len)
{
if (child + 1 < len && a[child] < a[child + 1])
++child;
if (a[parent] < a[child])
{
swap(a[parent], a[child]);
parent = child;
child = parent * 2 + 1;
}
else
break;
}
}
void HeapSort(int a[], size_t n)
{
assert(a && n);
for (int i = (n - 2) / 2; i >= 0; --i)
{
AdjustDown(a,i,n);//向下调整
}
/*for (size_t i = 0;i < n;++i)
{
swap(a[0],a[n-1-i]);
AdjustDown(a,0,n-i-1);
}*/
for (size_t i = n-1;i > 0;--i)
{
swap(a[0],a[i]);
AdjustDown(a,0,i);
}
}
void Show(int a[],size_t n)
{
for (size_t i = 0; i < n; ++i)
{
cout << a[i] << " ";
}
cout << endl;
}
void testSort()
{
int a[] = { 3,4,5,1,2,6,7 };
HeapSort(a,7);
Show(a,7);
}
int main()
{
testSort();
system("pause");
return 0;
}