堆排序——java

来源:互联网 发布:联通网络结构 编辑:程序博客网 时间:2024/06/03 17:02

堆排序:
时间复杂度:O(n*log2(n))
空间复杂度:O(1)
不稳定
核心代码:

import java.util.Arrays;/** * 堆排序 * @author jin */public class Heap {    /**     * 创建大顶堆     * @param array     * @param lastIndex     */    public static void createMaxHeap(int[] array, int lastIndex) {        for (int i = (lastIndex - 1) / 2; i >= 0; i--) {            int fatherIndex = i;            while (fatherIndex * 2 + 1 <= lastIndex) { // 如果当前父节点有子节点的话                int biggerIndex = fatherIndex * 2 + 1;                if (biggerIndex < lastIndex) {                    if (array[biggerIndex] < array[biggerIndex + 1]) {                        biggerIndex++;                    }                }                if (array[biggerIndex] > array[fatherIndex]) {                    swap(array, fatherIndex, biggerIndex);                } else {                    break;                }            }        }    }    /**     * 数组中元素进行交换     * @param array     * @param i     * @param j     */    public static void swap(int[] array, int i, int j) {        int tmp = array[i];        array[i] = array[j];        array[j] = tmp;    }    /**     * main方法     */    public static void main(String[] args) {        int[] a = { 1, 2, 56, 3, 55, 2, 66, 9, 0, 7 };        for (int i = 0; i < a.length - 1; i++) {            createMaxHeap(a, a.length - 1 - i);            swap(a, 0, a.length - 1 - i);        }        System.out.println(Arrays.toString(a));    }}

堆排序,有两个步骤:
(1)先建一个大顶堆,
(2)然后堆顶与堆的最后一个元素进行交换。
步骤:
(1)建大顶堆:
大顶堆:所有的父节点的数都比子节点的数大。
大顶堆是通过数组进行存储的 ,例如:
堆的结构
在内存中的存储方式为:
存储方式
求某一子节点的父节点的索引:
(子节点索引-1)/2取整
建堆时,先从最后一个数开始,最后一个索引为lastIndex,其父节点为fatherIndex=(lastIndex-1)/2;如果该父节点有子节点的话,那么左节点为leftIndex=fatherIndex*2+1;
如果建大顶堆,也是从最后一个数开始,不过求子节点时,先假设左节点为最大的数biggerIndex=fatherIndex*2+1;如果biggerIndex

for(int i=(lastIndex-1)/2;i>=0;i--){//从后往前建立    int fatherIndex=i;    while(fatherIndex*2+1<=lastIndex){//如果当前父节点有子节点的话        int biggerIndex=fatherIndex*2+1;//为左节点        if(biggerIndex<lastIndex){            if(a[biggerIndex]<a[biggerIndex+1]){                biggerIndex++;//此时最大的数变为右节点            }        }        if(a[biggerIndex]>a[fatherIndex]){//交换这两个索引的值的位置        //这里用到了位运算,详细的以后会写            a[fatherIndex]=a[biggerIndex]^a[fatherIndex];            a[biggerIndex]=a[biggerIndex]^a[fatherIndex];            a[fatherIndex]=a[biggerIndex]^a[fatherIndex];        }else{            break;        }    }}

(2)然后堆顶与堆的最后一个元素进行交换。
这里就开始进行排序了,交换完成后,就实现了从小到大的排列。

0 0