一.排序算法大全之堆排序

来源:互联网 发布:大数据需求分析 编辑:程序博客网 时间:2024/05/21 19:23

一.排序算法大全之堆排序

先从伪代码的角度分析:

二叉堆数据结构是一种数组对象,用堆对数组A(数组下标用i表示)进行排序,需要了解这些性质。

堆的基本性质:1.堆是一个完全二叉树 

        2.二叉堆有两种:a.最大堆 A[parent(i)]>=a[i]

       b.最小堆 A[parent(i)]<=a[i]

       3.通过下标i,求父节点,左子节点,右子节点

           parent(i)

return i/2向下取整的值

         left(i)

return 2i

            right(i)

           return 2i+1

 

 

 

好了现在来进行堆排序分析:

给出一个数组:A

要对一个数组进行堆排序:我们要先创建出一个堆(此处我以创建最大堆为例),然后再对其进行排序。

(一)在建堆的过程中我们用到了一个方法:max_heapify(A,i)

这个方法的作用是对输入的数组A,和下标i;如果下标i不满足堆的基本性质,能对其下标进行调整。

1.max_heapify()是对最大堆进行操作的重要子程序,其输入为一个数组A和下标 i。

2.当max_heapify(A,i)被调用时我们假定left(i)和right(i)为根的两颗二叉树都是最大堆,但此时A[i]可能小于其子女。这样就违反了最大堆的性质。

3.max_heapify()让A[i]在最大堆中“下降”,使以i为根的子树成为最大堆。

           

伪代码:

max_heapify(A,i)

L=left(i)

R=right(i)

if L<=heapsize(A)and A[L]>A[i]

then largest=L

else largest=i

if R<=heapsize(A)and A[R]>A[i]

then largest=R

if largest!=i

then exchange(A[i],a[largest])//交换两数的值

  max_heapify(A,largest)

 

 


(二.)建堆的思路

a.我们可以自底向上的调用max_heapify(A,i)来讲一个数组A[1,...,n]变成最大堆。

b.子数组A[parent(i)+1,...,n]中的元素都是叶子节点,因此可以看作只含一个元素的堆(故它本身就是一个最大堆)。

c.过程build_max_heap对树中每一个非叶子节点进行调用一次max_heapify()。

建最大堆的伪代码:

bulid_max_heapify(A)

heapsize[A]=length(A)

for i= parent[i] downto 1

do max_heapify(A,i)

 

 

 

(三).对建好的堆进行排序

a.调用build_max_heap(A)将输入的数组A[1,...,n]构造成一个最大堆

b.A[1]是最大元素,通过与A[n]互换来达到最终正确位置

c.去掉结点n(通过减小heapsize[A]),可以将A[1,...,n]建成最大堆

d.原来根的子女们依然是最大堆,而新的元素违背了最大堆的性质。这时可调用max_heapify(A,1)就可以保持这个效果

e.伪代码:

heapsort(A)

build_max_heap(A)

for i = length(A) downto 2

do exchange(A[1],a[i])

    heapsize = heapsize[A]-1

    max_heapify(A,1)


   

对思路已经有了一个清晰的认识,现在我们用java代码实现它:

package com.wukung.blog;public class HeapSortTest {/** * @param args */public static void main(String[] args) {// TODO Auto-generated method stubint[] a = {1,15,6,4,8,10,11,3,19};new HeapSortTest().heap_sort(a);for(int i=0;i<a.length;i++){System.out.print(a[i]+" ");}}//保持堆的性质,输入一个数组,和一个数组下标i,当max_heapify()被调用时,我们假定//以left(i)和light(i)为根的两颗二叉树都为最大堆,但此时A[i]可能小于其子女。//为了保持堆的性质,调用max_heapify()让A[i]在堆中的位置下降public void max_heapify(int[] a,int heapsize,int i){int l = getLift(i);int r = getRight(i);int largest = i;if(l<=heapsize-1&&a[l]>a[i]){largest=l;}if(r<=heapsize-1&&a[r]>a[largest]){largest=r;}if(largest!=i){int temp = a[largest];a[largest] = a[i];a[i] = temp;max_heapify(a, heapsize, largest);}}//输入一个数组,把这个数组建成一颗最大堆public void bulid_max_heapify(int[] a){int size=getParent(a.length-1);for(int i=size;i>=0;i--){max_heapify(a, a.length, i);}}//堆排序public void heap_sort(int[] a){bulid_max_heapify(a);for(int j=a.length-1;j>=1;j--){int temp = a[0];a[0] = a[j];a[j] = temp;//heapsize--;max_heapify(a,j,0);}}public int getLift(int current){return (current<<1)+1;}public int getRight(int current){return (current<<1)+2;}public int getParent(int current){return (current-1)>>1;}}


 

 

 

 

16 0
原创粉丝点击