堆排序

来源:互联网 发布:索尼smartwatch2 软件 编辑:程序博客网 时间:2024/05/21 06:44

堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法,它是选择排序的一种。先说 一下什么是堆。

二叉堆的定义:
堆分为大根堆和小根堆两种。对于一个小根堆,它是具有如下特性的一颗完全二叉树。

  1. 若树根结点存在左孩子,则根结点的值(或某个域的值)小于等于左孩子结点的值(或某个域的值);
  2. 若树根结点存在右孩子,则根结点的值(或某个域的值)小于等于右孩子结点的值(或某个域的值);
  3. 以左、右孩子为根的子树又各是一个堆;
    大根堆的定义于上述类似,只要把小于等于改为大于等于就行。

堆的存储:
一般都用数组来表示堆。
若array[0,…,n-1]表示一颗完全二叉树的顺序存储模式,则双亲节点指针和孩子结点指针之间的内在关系如下:

  任意一节点指针 i:父节点:i==0 ? null : (i-1)/2

           左孩子:2*i + 1

           右孩子:2*i + 2
堆应该满足以下需求:
1.小根堆:array[i] <= array[2*i + 1] 且 array[i] <= array[2*i + 2];
2.大根堆:array[i] >= array[2*i + 1] 且 array[i] >= array[2*i + 2];

大根堆排序

  1. 初始化操作:将arr[0,..,n-1]构造为初始堆;
  2. 每一趟排序的基本操作:将当前无序区的堆顶记录arr[0]和该区间的最后一个记录交换,然后将新的无序区调整为堆(亦称重建堆)。
import java.util.Arrays;public class MaxHeap {    public static void main(String[] args) {        int[] arr = {23,15,43,22,67,100,60,55,76};        buildMaxHeap(arr);        System.out.println(Arrays.toString(arr));        heapSort(arr);        System.out.println(Arrays.toString(arr));    }    public static void heapSort(int[] arr){        //buildMaxHeap(arr); //为便于观察,测试中初始化成堆        for(int i=arr.length-1; i>1; i--){            int temp = arr[0];//堆顶元素和堆底元素交换,得到最大值            arr[0] = arr[i];            arr[i] = temp;            adjust(arr,0,i);//调整        }    }    public static void buildMaxHeap(int[] arr){         //从最后一个节点array.length-1的父节点(array.length-1-1)/2开始,直到根节点0,反复调整堆        for(int i=(arr.length-2)/2; i>=0; i--){            adjust(arr, i, arr.length);        }    }    private static void adjust(int[] arr, int n, int length) {        int temp = arr[n];        for(int i=2*n+1; i<length-1; i=2*i+1){//i为初始化节点n的左孩子            if(i<length && arr[i]<arr[i+1]){//取节点较大的子节点的下标                i++;//如果节点的右孩子的值>左孩子,取右孩子节点的下标            }            if(temp>=arr[i]){//如果根节点>=左右节点中较大的,不用调整                break;            }else{                arr[n] = arr[i];//将左右子结点中较大值调整到父节点上                n = i;//修改n值,以便继续向下调整            }        }        arr[n] = temp;//被调整的结点的值放到孩子节点的位置    }}
原创粉丝点击