您的位置:首页 > 其它

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

2014-04-17 13:26 225 查看
一.排序算法大全之堆排序

先从伪代码的角度分析:

二叉堆数据结构是一种数组对象,用堆对数组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
互换来达到最终正确位置

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 stub

int[] 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;
}
}


 

 

 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: