堆排序

一.什么是堆?

把数组中的元素之间的关系用一种下标之间的数学关系组成完全二叉树的结构,这种结构偶是逻辑结构,物理结构还是数组


二 数组中元素怎么变为堆结构?

每个元素的下标的i(i-1》/2 为它的父节点位置,每个元素的左节点下标为 (i*2)+1 ,右节点下表为 (i*2)+2

比如给定一个数组 8,5,2,6,7,2     5的父节点是8 ,左孩子节点是 6  右孩子节点是7!


 

三 堆排序的过程

先把给定的数组做一个 heapinsert() 的过程,每个节点都和它的父节点比较,满足大于他的父节点,则交换,当前节点变为父节点,再次比较,满足则交换,循环结束,整个数组会变成一个大根堆的结构(每颗子树的第一个节点最大)

private static void heapInsert(int[] arr, int index) {
        while(arr[index]>arr[(index-1)/2]){
            swap(arr,index,(index-1)/2);
            index=(index-1)/2;
        }

四 把堆中的数从小达到排好序

把堆顶的数与堆尾的数交换,再把堆的范围见减1,重新按大根堆排序,这样就把最大的数放在了数组的最后一位,剩下的数又形成了一个大很堆结构,再次执行1步骤,这样又把剩下的数里的最大的树放在了数组倒数第二的位置

    private static int[] heapify(int[] arr, int index, int heapsize) {
        int left = index * 2 + 1;
        while(left<heapsize){
            int largest = arr[left+1] >arr[left] && left+1<heapsize ? left+1 :left;
            largest = arr[index] > arr[largest] ? index : largest;
            if(index ==largest){
                break;
            }
            swap(arr,index,largest);
            index= largest;
            left = index * 2 +1;
        }
        return arr;
    }

整个过程的代码

/**
 * 堆排
 * @author Administrator
 *
 */
public class HeapSort {
    public static int[] heapSort(int[] arr){
        if(arr==null && arr.length<2){
            return null;
        }
        for(int i =0;i<arr.length;i++){
            heapInsert(arr,i);
        }
        int size = arr.length;
        swap(arr,0,--size);
        while(size>0){
            heapify(arr,0,size);
            swap(arr,0,--size);
        }
        return arr;
    }

    private static int[] heapify(int[] arr, int index, int heapsize) {
        int left = index * 2 + 1;
        while(left<heapsize){
            int largest = arr[left+1] >arr[left] && left+1<heapsize ? left+1 :left;
            largest = arr[index] > arr[largest] ? index : largest;
            if(index ==largest){
                break;
            }
            swap(arr,index,largest);
            index= largest;
            left = index * 2 +1;
        }
        return arr;
    }

    private static void heapInsert(int[] arr, int index) {
        while(arr[index]>arr[(index-1)/2]){
            swap(arr,index,(index-1)/2);
            index=(index-1)/2;
        }
    }

    private static void swap(int[] arr, int i, int j) {
        int tmp=arr[i];
        arr[i]=arr[j];
        arr[j]=tmp;
    }

 

posted @ 2018-08-30 15:05  大小黄人  阅读(224)  评论(0编辑  收藏  举报