数据结构之堆排序(Java实现大顶堆)

学习目标:

掌握堆排序以及优先级队列的原理和实现


学习内容:

1.向上建堆找最大值 2.向下更新堆

学习产出:

学习堆排序需要循序渐进。首先我们要明白堆排序的两个重要过程:

  • 向上建堆,将最大值放到对顶
  • 向下更新堆

我们需要在数组中找到最后一个非叶节点。因为我们自底向上找到最大值,如果直接找叶节点无法通过比较确定大小关系。在完全二叉树中,最后一个非叶节点在数组中的位置与整个树的节点数有一定的关系

index = N / 2;
index为最后一个非叶节点在数组的索引,N为整个树的结点,向下取整。

所以我们从N/2开始遍历,每次都比较以该节点为根节点的树的最大值,并将其不断上浮。

static void buildMaxHeap(int[] A,int len){
    for(int i = len/2;i>=1;i--)
    {
        maxHeap(A,i,len);
    }
}
static void maxHeap(int[] A,int index,int len){
    int left = index*2;
    int right = 2*index+1;
    int largest;
    if(left <= len && A[left] > A[index]){
        largest = left;
    }
    else{
        largest = index;
    }
    if(right <= len && A[largest] < A[right])
    {
        largest = right;
    }
    if(largest != index)
    {
        swap(index,largest);
        maxHeap(A,largest,len);
    }
}

先从当前节点,左节点,右节点中找到最大值,将其与当前节点进行交换,进行递归操作。
每当我进行好上述整个操作的时候,我们就已经把最大值给放到了堆顶。此时我们需要将堆顶元素与数组末尾元素进行交换,因为排序的最终结果就是最大值在最末尾不是吗?

private static void heapSort() {
    for(int i=H;i>=1;i--) {
        buildMaxHeap(A, i);
        swap(1,i);
    }
}

这里我们需要不断遍历,i表示当前数组未排序的长度,以便于将局部最大值放到对应的位置。

完整代码

package AizuOJ.Heap;

import java.util.Scanner;

public class HeapSort {
    static int[] A = new int[1000];
    static int H;

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        H = in.nextInt();
        for(int i=1;i<=H;i++){
            int key = in.nextInt();
            A[i] = key;
        }
        heapSort();
        for(int i=1;i<=H;i++){
            System.out.println(A[i]);
        }
    }
    static void buildMaxHeap(int[] A,int len){
        for(int i = len/2;i>=1;i--)
        {
            maxHeap(A,i,len);
        }
    }
    static void swap(int x,int y){
        int item = A[x];
        A[x] = A[y];
        A[y] = item;
    }
    static void maxHeap(int[] A,int index,int len){
        int left = index*2;
        int right = 2*index+1;
        int largest;
        if(left <= len && A[left] > A[index]){
            largest = left;
        }
        else{
            largest = index;
        }
        if(right <= len && A[largest] < A[right])
        {
            largest = right;
        }
        if(largest != index)
        {
            swap(index,largest);
            maxHeap(A,largest,len);
        }
    }
    private static void heapSort() {
        for(int i=H;i>=1;i--) {
            buildMaxHeap(A, i);
            swap(1,i);
        }
    }
}

题目链接ALDS1_9_D

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值