排序算法之堆排序详解(附最大堆示例代码)

来源:互联网 发布:数据散修txt下载 编辑:程序博客网 时间:2024/04/28 18:17

1.堆的概念(最大堆与最小堆)
堆排序的时间复杂度是n logN,具有nl og N时间复杂度的排序算法还有快速排序和理想状态下的归并排序,一般来说快速排序的性能优于堆排序,但堆排序在实际中也有很多的应用,后续会做具体介绍.
堆指的是堆数据结构,被看成是一个近似的完全二叉树,树上的每一个结点对应数组中的一个元素.
完全二叉树满足两个特性:
1.父结点的键值总是大于或等于(小于或等于)任何一个子节点的键值。
2.每个结点的左子树和右子树都是一个二叉堆(都是最大堆或最小堆)。
最大堆性质是指除了根以外的所有结点i都要满足:A[PARENT(i)]>=A[i];,也就是说,某个结点的值至多与其父结点一样大.,因此,堆中的最大元素存放在根结点中,并且,在任一子树种,该子树所包含的所有结点的值都不大于该子树根结点的值.
最小堆性质是指除了根以外的所有结点i都有A[PARENT]<=A[i];最小堆中的最小元素存放在根结点中.
在堆排序算法中,我们使用的是最大堆,最小堆通常用于构造优先数列.
2.堆排序原理
堆排序可分为3个步骤:
1.建堆:堆排序算法利用BUILD-MAX-HEAP将输入数组A[1..n]建成最大堆,其中n=A.length.因为数组中的最大元素总在根结点A[1]中,通过把它与A[n]进行互换,我们可以让该元素放到正确的位置
2.调整堆,因为交换之后新的根结点可能会违背最大堆的性质,为了维护最大堆的性质,我们要做的就是调用MAX-HEAP(A,1),从而在A[1,n-1]上构造一个新的最大堆
3.递归调用:堆排序算法会不断重复这一过程,直到堆的大小从n-1降到2位置终止递归调取,到此排序完成.

堆排序伪代码
调整堆
MAX-HEAPIFY(A,i)
l = LEFT(i)
r = RIGHT(i)
if l ≤ A.heap-size and A[l] > A[i]
largest = l
else largest = i
if r ≤ A.heap-size and A[r] > A[largest]
largest = r
if largest ≠ i
exchange A[i] with A[largest]
MAX-HEAPIFY(A,largest)
建堆
BUILD-MAX-HEAP(A)
A.heap-size = A.length
for i = (A.length/2) downto 1
MAX-HEAPPIFY(A,i)
递归调用
HEAPSORT(A)
BUILD-MAX-HEAP(A)
for i = A.length downto 2
exchange A[1] with A[i]
A.heap-size = A.heap-size - 1
MAX-HEAPIFY(A,1)
3.堆排序示例代码

最大堆的java代码实现

    private static int N;    /* Sort Function */    //传入一个数组进行堆排序    public static void sort(int arr[]) {        //建堆        heapify(arr);        for (int i = N; i > 0; i--) {            swap(arr, 0, i);            N = N - 1;            maxheap(arr, 0);        }    }    //建堆的方法    /* Function to build a heap */    public static void heapify(int arr[]) {        N = arr.length - 1;        //循环调用调整堆,直到堆的大小到2为止        for (int i = N / 2; i >= 0; i--)            maxheap(arr, i);    }    //调整堆使其根结点为最大元素    /* Function to swap largest element in heap */    public static void maxheap(int arr[], int i) {        int left = 2 * i;        int right = 2 * i + 1;        int max = i;        if (left <= N && arr[left] > arr[i])            max = left;        if (right <= N && arr[right] > arr[max])            max = right;        if (max != i) {            swap(arr, i, max);            //递归调用堆的调整堆的方法            maxheap(arr, max);        }    }    /* Function to swap two numbers in an array */    //交换数组i和j位置的元素    public static void swap(int arr[], int i, int j) {        int tmp = arr[i];        arr[i] = arr[j];        arr[j] = tmp;    }    /* 测试方法 */    @Test    public void heapSortTest() {        int arr[] = {222, 5, 2, 4, 6, 1, 3, 11, 9, 10, 8, 7, 0};        sort(arr);        System.out.println(Arrays.toString(arr));    }

c++代码实现

/* * C++ Program to Implement Heap Sort */#include <iostream>#include <conio.h>using namespace std;void max_heapify(int *a, int i, int n){    int j, temp;    temp = a[i];    j = 2*i;    while (j <= n)    {        if (j < n && a[j+1] > a[j])            j = j+1;        if (temp > a[j])            break;        else if (temp <= a[j])        {            a[j/2] = a[j];            j = 2*j;        }    }    a[j/2] = temp;    return;}void heapsort(int *a, int n){    int i, temp;    for (i = n; i >= 2; i--)    {        temp = a[i];        a[i] = a[1];        a[1] = temp;        max_heapify(a, 1, i - 1);    }}void build_maxheap(int *a, int n){    int i;    for(i = n/2; i >= 1; i--)    {        max_heapify(a, i, n);    }}int main(){    int n, i, x;    cout<<"enter no of elements of array\n";    cin>>n;    int a[20];    for (i = 1; i <= n; i++)    {        cout<<"enter element"<<(i)<<endl;        cin>>a[i];    }    build_maxheap(a,n);    heapsort(a, n);    cout<<"sorted output\n";    for (i = 1; i <= n; i++)    {        cout<<a[i]<<endl;    }    getch(); }

测试运行结果截图

运行结果

4.优先队列简介
优先队列有两种形式:最大优先队列最小优先队列.
优先队列是一种用来维护由一组元素构成的集合S的数据结构,其中的每一个元素都有一个相关的值,成为关键字.一个最大优先队列支持一下操作:
INSERT(S,x):把元素x插入集合S中.这一操作等价于S = S U {x}.
MAXIMUM(S):返回S中具有最大关键字的元素.
EXTRACT-MAX(S):去掉并返回S中的具有最大关键字的元素.
INCREASE-KEY(S,x,k):将元素x的关键字值增加到k,这里假设k的值不小于x的原关键字值.
最大优先队列的应用有很多,其中一个就是在共享计算机系统的作业调度
最小优先队列可以用于基于事件驱动的模拟器.
在一个包含n个元素的堆中,所有优先队列的操作都可以在O(lg n)时间内完成.

如有不足之处请指正,谢谢!

附上最小堆排序的链接:http://blog.csdn.net/morewindows/article/details/6709644/
参考过别人的链接:http://www.sanfoundry.com/java-program-implement-heap-sort/

2 0
原创粉丝点击