堆排序(●'◡'●)

前言

菜鸟漫漫成长路——堆排序。

  • 满二叉树:所有节点的孩子都是全的,即最后一层都是叶节点。
  • 完全二叉树:叶节点只可以出现在最下层和次下层,且最下层的叶节点依次在左边。

首先,我们了解一下怎么用一个数组来表示一个完全二叉树。
这里写图片描述
上面七个小格子代表的是一个长度为7的数组,如果将它写成二叉树的形式就是图上所示。可是我们要怎么建立起关系来呢?其实通过数组的下标就能非常简单的实现。当当前节点为i的时候,则它的左孩子的下标为i*2+1,右孩子为i*2+2,父节点为(i-1)/2。比如说,3的左孩子为4右孩子为5,3的数组下标为0,则4的下标为0*2+1=1,5的下标为0*2+2。

堆就是一种特殊的完全二叉树。它又分为大根堆和小根堆。大根堆就是父节点的数比左孩子以及右孩子都大。小根堆就是父节点的数比左孩子以及右孩子都小。

构建大根堆(加一个新节点到堆里,并向上调整)

了解了大根堆以及对应下标的关系之后,我们要建立大根堆就很简单啦。

这里写图片描述

  1. 首先,我们假设这个堆的大小为1,则,当前构建的大根堆只有③一个节点。如图a。
  2. 接着我们将堆的大小扩为2,将④这个节点加入。加入后我们进行比较,发现比它的父节点③要大,所以,我们将数组0和1的位置交换。如图b。
  3. 接着再将堆的大小扩为3,将⑤这个节点加入。加入后我们进行比较,发现比它的父节点④要大,所以,我们将数组0和2的位置交换。如图c。
  4. 继续将堆的大小+1,扩为4。将⑥这个节点加入。加入后我们进行比较,发现比它的父节点③要大,继续比较发现交换后,⑥仍然比父节点⑤要大,继续交换。如图d所示。

Code

    public static void heapInsert(int[]a,int index){
        while(a[index]>a[(index-1)/2]){
            swap(a,index,(index-1)/2);//交换两个数
            index = (index-1)/2;
        }
    }

调整大根堆

当大根堆某个值变小了,我们要怎么把它调整回一个大根堆呢?其实也很简单。找到这个节点的左孩子和右孩子,并和这个孩子的最大值交换。依次向下进行对比,直到到达叶节点,或者比它的左右孩子都大即可停止。

Code

    public static void heapify(int[]a,int index,int size){
        int left = index*2+1;
        while(left < size ){
            int largest = left+1 < size && a[left] < a[left+1] ? left+1:left;
            largest = a[largest]>a[index]? largest:left;
            if (largest == index){
                break;
            }
            swap(a,largest,index);
            index = largest;
            left = index*2+1;
        }
    }

堆排序

其实堆排序就是根据上面两种方法来进行合作。假设我们的数组长度为4。首先我们构建好了一个大根堆后,大根堆的第一个节点就是我们整个数组最大的数。接下来我们将第一个节点和我们最后的一个节点交换,交换后,我们将大根堆的size-1=3。那么此时我们假设数组下标为0,1,2的三个数为大根堆,是不是就相当于我们调整大根堆的操作。调整好后,最大的数又到了堆顶,我们再将他与末尾交换,再将size-1。。。。。。依次下去,到最后大根堆的size为0后数组就从小到大排序好啦。

Code

    public static void heapSort(int[]a){
        if (a == null || a.length<2){
            return;
        }
        for (int i = 0;i <a.length;i++){
            heapInsert(a,i);
        }
        int size = a.length;
        swap(a,0,--size);
        while(size > 0){
            heapify(a,0,size);
            swap(a,0,--size);
        }

完整代码

public class HeapSort {
    public static void heapSort(int[]a){
        if (a == null || a.length<2){
            return;
        }
        for (int i = 0;i <a.length;i++){
            heapInsert(a,i);
        }
        int size = a.length;
        swap(a,0,--size);
        while(size > 0){
            heapify(a,0,size);
            swap(a,0,--size);
        }
    }
    public static void heapInsert(int[]a,int index){
        while(a[index]>a[(index-1)/2]){
            swap(a,index,(index-1)/2);//交换两个数
            index = (index-1)/2;
        }
    }
    public static void swap(int[] arr, int i, int j) {
        int tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
    }
    public static void heapify(int[]a,int index,int size){
        int left = index*2+1;
        while(left < size ){
            int largest = left+1 < size && a[left] < a[left+1] ? left+1:left;
            largest = a[largest]>a[index]? largest:left;
            if (largest == index){
                break;
            }
            swap(a,largest,index);
            index = largest;
            left = index*2+1;
        }
    }
}
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值