排序算法之堆排序
核心思想:利用最大堆的堆顶元素最大原理,进行排序,每次移除堆顶元素,将最大的移动到当前子序列最后,在剩下元素中重复上述操作,直至序列有效。
C语言代码:
#include <iostream>
using namespace std;
//排序时可以将a传给heap然后利用heap自身排序节约一个空间
class MaxHeap{
private:
int * heap;
int size;
int maxsize;
public:
MaxHeap(int sz):size(0),maxsize(sz){
if(sz>0)
heap = new int[sz];
}
~MaxHeap(){
delete [] heap;
}
//插入元素建立最大堆
bool push(int x){
if(size==maxsize)
return false;
int i = size++;
//这里i应该>0,才能保证i节点有父节点,否则会出现数组越界
while(i>0){
int p = (i+1)/2-1;
if(x>heap){
heap = heap;
i = p;
}else{
break;
}
}
heap = x;
return true;
}
void pushArray(int a[],int n){
for(int i=0;i<n;i++)
push(a);
}
//堆排序算法
/**
* 通过将原序列建立最大堆,因为堆顶的元素最大,所以每次将堆顶的元素放到最后
* 再剩下的元素中重复此操作,直至剩下一个元素
*/
void sort(int a[],int n){
//先将a保存到堆中
pushArray(a,n);
int x;
for(int i=n-1;i>=0;i--){
shift(x);
a = x;
}
}
//移除元素
bool shift(int& x){
if(0==size)
return false;
x = heap[0];
/**
* 将最后一个元素放到堆顶,然后再进行重构
*/
heap[0] = heap[size-1];
size--;
int p = 0;
int l = p*2+1;
while(l<size){
int r = l+1;
int max = r<size ? (heap[l]>heap[r] ? l : r) : l;
//交换
if(heap[max]>heap){
int tmp = heap;
heap = heap[max];
heap[max] = tmp;
}
p = max;
l = p*2+1;
}
return true;
}
void output(){
for(int i=0;i<size;i++)
cout<<heap<<" ";
cout<<endl;
}
};
int main(void){
MaxHeap h(10);
int a[] = {1,9,2,8,18,4,2,7,3,8};
h.sort(a,10);
for(int i=0;i<10;i++)
cout<<a<<" ";
cout<<endl;
return 0;
}
时间复杂度:nlog2n 空间复杂度:将待排序数组传给堆中的堆序列,因此不需要额外的空间。 算法稳定性:因为建立堆本身就是不是稳定的,所以堆排序是一种不稳定的排序算法。