堆排序(java实现)

常见排序--堆排序

因为堆结构是一个典型的完全二叉树,所以堆可以用一个一维数组表示。父结点与左子结点、右子结点的关系很容易推到出。推导过程如下:

假设数组的下标是:0 , 1 , 2 , 3 , 4 , 5, 6 , 7 , 8 

则结点关系如下:

parent left right

   0            1        2

   1            3        4

   2            5        6 

   3            7        8 

我们很容易找出它们之间的关系:(1-1)/2 = 0 ,  (2-1)/2 = 0 ; 

                                                 (3-1)/2 = 1,   (4-1)/2 = 1;

                                                 (5-1)/2 = 2,   (6-1)/2 = 2;

 .....

所以任意结点n的父结点:parent = (n - 1) /2

而左子结点n与父结点的关系是上个函数的反函数,即:n = parent * 2 + 1;右子结点m的下标显然始终比左子结点n大1,即:m = parent * 2 + 2

根据上述公式,我们可以轻易写出,parent() , left()  ,right() 函数,详见以下实现。


完成堆排序,主要有三个模块:MaxHeap, BuildHeapify 和HeapSort。

 MaxHeap功能很简单,可简单认为是比较三个数的大小,只是这三个数由parent(),left(),right()进行确定。

BuildHeapify是建最大(小)堆,从非叶子节点开始,并且从后向前“最大(小)堆”。完全二叉树的非叶子结点个数计算公式:n/2 。注意,当前节点下标与n/2相差1

HeapSort根据最大(小)堆排序,我们可以类比冒泡排序。每次建堆,最大(小)值会被推到最数组的0位置。


Java实现的堆排序:

public class TestHeap {
       public static void main(String[] args) {<span style="font-family: Arial, Helvetica, sans-serif;">       </span><span style="font-family: Arial, Helvetica, sans-serif;">     </span><span style="font-family: Arial, Helvetica, sans-serif;">
</span>              int[] a = {3,1,3,4,51,6,7,43,132,4,45,732,79,2,2,2,1,3,5,7,8,98,9};<span style="font-family: Arial, Helvetica, sans-serif;">              </span>
              Heap heap = new Heap();
              heap.BuildHeapify(a, a.length);
              heap.HeapSort(a);
              for(int x : a){
                        System.out.print(x + " ");
              }
              System.out.println();
       }
}

class Heap {
        public int parent(int i){
               return (i-1)/2;
        }
        public int left(int i){
               return i*2+1;
        }
        public int right(int i){
               return i*2+2;
        }
        public void MaxHeap(int[] a,int i){
               int big = i;
               int l = left(i);
               int r = right(i);
               if(a[i]<a[l]){
                       big = l;
               }
               if(a[big]<a[r]){
                      big = r;
               }
               if(big != i){
                      int tmp = a[i];
                      a[i] = a[big];
                      a[big] = tmp;
               }
        }
        public void BuildHeapify(int[] a,int len){
               for(int i=len/2-1;i>=0;i--){
                      MaxHeap(a,i);
               }
        }
        public void HeapSort(int[] a){
               for(int i=a.length-1;i>=0;i--){
                     BuildHeapify(a,i);
                     int tmp = a[0];
                     a[0] = a[i];
                     a[i] = tmp;
               }
        }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值