堆排序

来源:互联网 发布:新丰县网络问政平台 编辑:程序博客网 时间:2024/06/05 08:17

堆排序

知识点

堆分为大顶堆,小顶堆。

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

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

图片

左边大顶堆, 右边小顶堆

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

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

  • 对全数组A[n]构建大顶堆

  • 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;} 
原创粉丝点击