数据结构之堆排序(java)

来源:互联网 发布:手机成绩统计软件 编辑:程序博客网 时间:2024/06/07 05:09

算法描述

堆排序是利用堆的性质进行的一种选择排序。下面先讨论一下堆。
堆实际是一棵完全二叉树。
完全二叉树要么是满二叉树,要么是在成为满二叉树的路上。

 满二叉树定义:除最后一层无任何子节点外,每一层上的所有结点都有两个子结点(最后一层上的无子结点的结点为叶子结点)。也可以这样理解,除叶子结点外的所有结点均有两个子结点。节点数达到最大值。所有叶子结点必须在同一层上.
完全二叉树定义:若设二叉树的深度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第 h 层所有的结点都连续集中在最左边,这就是完全二叉树。

那么从定义可以知道,第i各元素的父亲节点为第(i-1)/2,左孩子节点为i*2+1,*右孩子节点为i*2+2。

下面来介绍大根堆。

根结点(亦称为堆顶)的关键字是堆里所有结点关键字中最大者,称为大根堆,又称最大堆(大顶堆)。

(1)把整个数组变成大根堆:
每增加一个元素,都把它和它父亲节点的值进行比较,若当前元素的值较大,那就交换它与它父亲节点的值,再依次比较再上一层节点,最后我们得到一个根节点为所有子树最大值的完全二叉树。
(2)利用大根堆进行排序:
将大根堆的堆顶元素与最后一个元素进行交换,再调成大根堆结构。即将调整后的堆顶依次往下沉。怎么下称具体看代码实现。
算法分析
时间复杂度:O(N*logN) 但常数项比较大
//建立大根堆的过程是O(N),接下来每一个点下沉的高度最多为logN级别,一共n个元素,时间复杂度严格为O(N*logN)
空间复杂度:O(1)
//只用到有限的几个额外变量
实现不能做到稳定性

code:

public class HeapSort {    public static void heapSort(int[] arr) {        if (arr == null || arr.length < 2) {            return;        }        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);        }    }    public static void heapInsert(int[] arr, int index) {        while (arr[index] > arr[(index - 1) / 2]) {            swap(arr, index, (index - 1) / 2);            index = (index - 1) / 2;        }    }    public static void heapify(int[] arr, int index, int size) {        int left = index * 2 + 1;        while (left < size) {            int largest = left + 1 < size && arr[left + 1] > arr[left] ? left + 1 : left;            largest = arr[largest] > arr[index] ? largest : index;            if (largest == index) {                break;            }            swap(arr, largest, index);            index = largest;            left = index * 2 + 1;        }    }    public static void swap(int[] arr, int i, int j) {        int tmp = arr[i];        arr[i] = arr[j];        arr[j] = tmp;    }    public static void printArray(int[] arr) {        if (arr == null) {            return;        }        for (int i = 0; i < arr.length; i++) {            System.out.print(arr[i] + " ");        }        System.out.println();    }    public static void main(String[] args) {        int[] arr = new int[]{5, 6, 23, 4, 2, 1, 9, 0};        heapSort(arr);        printArray(arr);    }}
原创粉丝点击