一步一步搞清排序之堆排序(JAVA)

本文深入浅出地介绍了堆排序的基本原理及实现步骤,并通过实例演示了如何利用大顶堆完成数组的排序过程。堆排序是一种利用堆的数据结构进行的排序算法,它通过构建大顶堆并不断调整来达到排序的目的。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言:堆堆堆~相信有学过数据结构的同学都了解堆的过程和原理(毕竟数据结构考试最喜欢让我们画大小顶堆的生成过程),了解堆,也了解排序的我,在很长一段时间之内都没有理解堆排序真正的含义。
一直认为大小顶堆已经算是有序了呀,所以导致了我一直以为堆排序就是生成一个大(小)顶堆,当然这个想法是错误滴~现在理清了思路,Mark下来,希望能帮到和我一样曾经迷茫的童鞋~


原理:堆的原理这里就不详细讲啦,只需要记住一句话(根节点大于所有的子节点则为大顶堆,根节点小于所有的子节点则为小顶堆)就可以判断一个堆啦。

那么问题来了,如何进行堆排序呢?

顾名思义,就是利用堆,进行排序。以下举例以大顶堆为例。

要进行堆排序,一共需要生成N-1个大顶堆,每生成一个大顶堆,就将根节点与最末尾元素交换,这样最大的元素就被放在了数组的最后面。
然后N–,在剩下N-1个元素中,继续生成大顶堆,将根节点放在这N-1个元素的最后面···
以此类推,每一次都选出当前排列元素的最大值,放置在队尾,直到完成第N-1个大顶堆的交换~
注意:堆排序的思路和选择排序有点类似,都是每次选择最大的元素,但是,由于堆的树形结构的特殊性,可以保存部分排序结果,可以减少比较的次数。

代码如下:

package zj.com.heap;

import java.util.Arrays;

public class HeapSort {

    public void BuildHeap(int[] a){
        for(int i = 0;i<a.length-1;i++)
        {
            int lastindex = a.length-1-i;
            MaxHeap(a, lastindex);
            //交换每次建堆后的首尾元素,实现非降序排列
            Swap(a, 0, lastindex);
        }
    }

    //构建大顶堆
    public void MaxHeap(int[] a,int lastindex){
        for(int i = (lastindex-1)/2;i>=0;i--)
        {
            int k = i;
            int bigest = 2*k+1;
            while(bigest<=lastindex)
            {
                if(bigest<lastindex)
                {
                    if(a[bigest]<a[bigest+1])
                    {
                        bigest++;
                    }
                }
                if(a[bigest]>a[k])
                {
                    Swap(a, k,bigest);
                    k = bigest;
                }
                else
                {
                    break;
                }
            }
        }
    }
    //交换元素
    public void Swap(int[] a,int i ,int j){
        int temp = a[i];
        a[i] = a[j] ;
        a[j] = temp;
    }

    public static void main(String[] args) {

        int[] a = {3,2,1,6,5,4,9,8,7};
        HeapSort heapSort = new HeapSort();
        heapSort.BuildHeap(a);
        System.out.println(Arrays.toString(a));
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值