您的位置:首页 > 其它

堆排序

2017-08-11 19:36 190 查看

堆排序

知识点

堆分为大顶堆,小顶堆。

大顶堆的定义:每个节点的值都不大于其父节点的值

小顶堆的定义:每个节点的值都不小于其父节点的值



左边大顶堆, 右边小顶堆

堆排序是一种选择排序,时间复杂度是O(n*log(n)), 也是一种不稳定的排序方法

从图中可以看出大顶堆根节点的值最大

对全数组A
构建大顶堆

A[0]与A[n-1]值互换

重新调整A[0]–A[n-2]为大顶堆

A[0]与A[n-2]值互换

…………..

依次下去直到堆里面只有一个元素,此时数组已经有序

时间复杂度的证明:每次调整堆的时候,时间复杂度是O(log(n)),所以堆排序的复杂度为

O(n*log(n))

代码:

#include<iostream>
using namespace std;

int swap(int *a, int i, int j);
int swim(int *a, int k);
int sink(int *a, int k, int len);
int Less(int *a, int i, int j);

int Less(int *a, int i, int j) {
if(a[i-1] <= a[j-1]) return 1;
else return 0;
}

int heapSort(int *a, int len) {
/*n-1次循环*/
for(int i = len; i > 1; i--) {
swap(a, 1, i);
sink(a, 1, i -1);
}
return 0;
}

/*构建堆*/
int heap(int *a, int len) {
int start = 0;
if(len % 2 == 0) start = len / 2;
else  start = len / 2 + 1;

for(int i = start; i > 0; i--) {
sink(a, i, len);
}
return 0;
}

/*交换*/
int swap(int *a, int i, int j) {
i -= 1; j -= 1;
int temp = 0;
temp = a[i];
a[i] = a[j];
a[j] = temp;
return 0;
}

/*上浮*/
int swim(int *a, int k) {
while(k > 1) {
if(!Less(a, k, k/2)) swap(a, k, k/2);
else break;
k = k / 2;
}
return 0;
}

/*下沉*/
int sink(int *a, int k, int len){
int j = 0;
while(2*k <= len) {
j = 2*k;
if(j < len && Less(a, j, j+1)) j++;
if(!Less(a,j, k)) swap(a, k, j);
else break;
k = j;
}
return 0;
}

int main() {
int a[10] = {1, 3, 1, 3, 7, 2, 7, 9, 8, 4};

/*构建初始堆*/
heap(a, 10);

heapSort(a, 10);

for(int i = 0; i < 10; i++) {
printf("%d ", a[i]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  堆排序