堆排序

堆排序

难度:★★★★☆

基本思想

二叉堆:
叉堆有两种:最大堆和最小堆。最大堆:父结点的键值总是大于或等于任何一个子节点的键值;最小堆:父结点的键值总是小于或等于任何一个子节点的键值。
数组表示二叉堆:
对于数组按照二叉树从左向右,从上到下依次排列,如图:
[0,1,2,3,4,5,6,7,8]
在这里插入图片描述

  1. 堆的根节点(root)为A[0];
  2. 对这个堆中i节点(从0开始);
  3. 父节i的左节点,数组对应A[2*i+1];
  4. 父节i的右节点,数组对应A[2*i+2];
  5. 反过来知道某个节点数组下标为i,则它的父节点为(i-1)/2

利用二叉堆排序:
1.将A构建成一个最大堆(符合max-heap property,也就是根节点最大);
2.取出根节点;第一位与最后一位交换,同时数组长度减1,对减1的数组进行下一轮排序
3.将剩下的数组元素在建成一个最大二叉堆,返回第2步,直到所有元素都被取光。

算法图解

建成一个最大堆
在这里插入图片描述
在这里插入图片描述

程序实现
import java.util.Arrays;
import java.util.Random;

/**
 * Created by android on 19-6-24.
 */
public class MaxHeap {
    protected int A[];
    protected int heapsize;


    /**
     * @param i,父节点,需要调整该节点与其子节点的值,使得保证任何何一个节点在任何情况下的值都不会超过它的父亲节点,A[Parent]≥A[i]
     */
    protected void maxHeapify(int i) {
        int l = 2 * i + 1;
        int r = 2 * i + 2;
        int largest = i;
        if (l <= heapsize - 1 && A[l] > A[i]) {
            largest = l;
        }
        if (r <= heapsize - 1 && A[r] > A[largest]) {
            largest = r;
        }
        if (largest != i) {
            int temp = A[i];
            // 父节点比其的一个子节点小,交换其值
            A[i] = A[largest];
            A[largest] = temp;
            //因为子节点交换为一个小值,需要与子节点的子节点进行比较,保证任何何一个节点在任何情况下的值都不会超过它的父亲节点
            maxHeapify(largest);
        }
    }

    //节点i所对应的父节点
    protected int parent(int i) {
        return (i - 1) / 2;
    }

    public void buildMaxHeap(int[] A) {
        this.A = A;
        this.heapsize = A.length;

        for (int i = parent(heapsize - 1); i >= 0; i--)
            maxHeapify(i);
    }

    public void heapsort(int[] A) {
        buildMaxHeap(A);

        int step = 1;
        for (int i = A.length - 1; i > 0; i--) {
            System.out.println("Step: " + (step++) + Arrays.toString(A));
            int temp = A[i];
            A[i] = A[0];
            A[0] = temp;
            heapsize--;
            maxHeapify(0);
        }
    }

    public static void main(String[] args) {
        //a sample input
        Random random = new Random();
        int[] A = new int[18];
        for (int i = 0; i < A.length; i++) {
            A[i] = random.nextInt(10);
        }
        System.out.println("Input: " + Arrays.toString(A));
        MaxHeap maxhp = new MaxHeap();
        maxhp.heapsort(A);
        System.out.println("Output: " + Arrays.toString(A));

    }
}

在这里插入图片描述

排序算法稳定性

如果一个无序的序列里有两个相等的数据,在排序之后与之前的前后关系一定一样,那么就是稳定的排序,反正不稳定。堆排序不稳定

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值