堆排序

 

堆排序:一种基于堆的排序算法;

一些基础概念

堆定义:

当且仅当该序列满足如下性质(简称为堆性质)

(1)     ki≤K2iki≤K2i+1 (2)Ki≥K2iki≥K2i+1(1≤i≤ n) //ki相当于二叉树的非叶结点,K2i则是左孩子,k2i+1是右孩子

若将此序列所存储的向量R[1..n]看做是一棵完全二叉树的存储结构,则堆实质上是满足如下性质的完全二叉树:

树中任一非叶结点的关键字均不大于(或不小于)其左右孩子(若存在)结点的关键字。

下图为数组对应的大根堆和小根堆。

堆的高度:

堆可以被看成是一棵树,结点在堆中的高度可以被定义为从本结点到叶子结点的最长简单下降路径上边的数目;定义堆的高度为树根的高度。我们将看到,堆结构上的一些基本操作的运行时间至多是与树的高度成正比,为Olgn

大根堆的堆排序思想:

1)         初始化R[1…n]为大根堆,该堆为无序的;

2)         交换R[1]R[n]R[1…n-1]为无序的,R[n]为有序的;

3)         初始化R[1…n-1]为大根堆;

4)         交换R[1]R[n-1]R[1…n-2]为无序的,R[n-1…n]为有序的;

 依次重复,知道排好序为止。

算法如下:

/**

     * 建立堆

     * heap为需要建堆的数组,

     * root建堆的起始根

     * index为未排序的最后叶子节点

     */

    private static void createHeap(int[] heap, int root, int index) {

       int left;

       int right;

       int tmp;

       if(root>=index){

           return ;

       }

       while (root >= 0) {

           left = root << 1;

           right = (root << 1) + 1;

           if (right <= index) {

              if (heap[root] < heap[right]) {

                  tmp=heap[root];

                  heap[root]= heap[right];

                  heap[right]=tmp;

                  createHeap(heap, right, index);

               }

           }

           if (left <= index) {

              if (heap[root] < heap[left]) {

                  tmp=heap[root];

                  heap[root]= heap[left];

                  heap[left]=tmp;

                  createHeap(heap, left, index);

              }

           }

           root--;

       }

    }

   

    public static void heapSort(int[]heap, int index) {

       int i, j, Temp;

       // 将二叉树转成Heap

       for (i = (index / 2); i >= 1; i--)

           createHeap(heap,i, index);

       // 开始进行堆排序

       for (i = index ; i >= 1; i--) {

            Temp = heap[i]; // HeapRoot值和最后一个值交换

            heap[i] = heap[0];

            heap[0] = Temp;

            createHeap(heap,0, i-1); // 对其余数值重建堆

           System.out.print("排序中: ");

           for (j = 0; j <= index; j++)

              System.out.printf("%3s", heap[j]);

           System.out.println("");

       }

    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值