排序算法---(四)

引言

在前几篇文章里面讲到了六种排序,今天来讲一下剩下两种:基数排序、堆排序

基数排序

1.思路

(1)首先确定最大数的位数:找到待排序数组中的最大数,并确定其位数

(2)将元素按照相应的位数存入桶中:先定义一个桶(二维数组):用来存放待排序数组元素,再定义一个桶计数器(一维数组):用来记录每个桶里面有几个元素,将元素放入桶中有三步:① 放哪个桶(看相应位数是多少,例如相应位数上是1,那么就放在x坐标为1的桶里)、② 找到桶应该放在桶内的哪个位置(因为相应位数上是同一个数字的可能有多个,因此桶计数器发挥作用了,若计数为3,那说明这个桶已经放了三个元素了,那将待放入元素放在第四个位置上)、③ 更新桶计数器(+1);

(3)相应位数排完序后,将存入桶里元素有序的放回原数组

2.代码

java 复制代码
public class jsSort {
    public static void main(String[] args) {
        int[] arr=new int[]{5,1,3,9,8,2};
        int n=arr.length;
        sort(arr);
        for(int i=0;i<n;i++){
            System.out.print(arr[i]+" ");
        }
    }

    public static void sort(int[] arr) {
        int max=arr[0];
        for(int i=0;i<arr.length;i++){
            if(arr[i]>max){
                max=arr[i];
            }
        }

        int maxLength=(max+"").length();
        int[][] bucket=new int[10][arr.length];
        int[] bucketCount=new int[10];
        int t=1;
        for(int i=0;i<maxLength;i++){
            //存数据
            for(int j=0;j<arr.length;j++){
                int element=arr[j]/t%10;
                bucket[element][bucketCount[element]]=arr[j];
                bucketCount[element]++;
            }
            int index=0;
            //取数据
            for(int k=0;k<10;k++){
                if(bucketCount[k]!=0){
                    for(int j=0;j<bucketCount[k];j++){
                        arr[index++]=bucket[k][j];
                    }
                }
                bucketCount[k]=0;
            }
            t=t*10;
        }
    }
}

堆排序

1.相关知识

完全二叉树:从上到下、从左到右依次填满结点,前面每一层必须是满的,最后一层可以不满,但只能缺右边的结点,不能中间空、不能左边空

大顶堆:在完全二叉树的基础上父节点的值大于左右孩子的值

2.思路

(1)首先将待排序数组构造成一个大顶堆,此时整个数组最大值就被放在了二叉树的顶端

(2)将堆顶元素和堆底元素进行交换,此时堆底元素变成了整个数组最大值

(3)重新构建大顶堆,不包含上一步的堆底元素(最大值),重复上述步骤,这样就实现了每次都把最大元素拿出来,实现了数组升序

3.关键点

构造大顶堆:从最后一个元素当作parent,首先判断是否有孩子:child=parent*2+1是否小于nums.length,直到找到符合条件的parent,找到后开始判断parent和child哪个大,大的换到parent位置,依次遍历,遍历到二叉树的最顶端(数组的第一个元素),这样不断地向上遍历并交换,就实现了堆顶元素是数组最大的元素

排除上一轮的堆底元素:只需要将待排序数组长度减一即可

4.代码

java 复制代码
public class heapSort {
    public static void main(String[] args) {
        int[] arr=new int[]{5,1,3,9,6,8,2};

        for(int i=arr.length-1;i>=0;i--){
            sort(arr,i,arr.length);
        }

        //交换堆顶元素和堆底元素,并排除堆底元素
        for(int k=arr.length-1;k>=0;k--){
            int temp=arr[k];
            arr[k]=arr[0];
            arr[0]=temp;
            sort(arr,0,k);
        }
        //循环输出
        for(int j=0;j<arr.length;j++){
            System.out.print(arr[j]+" ");
        }
    }
    public static void sort(int[] arr,int parent,int length){
        int child=parent*2+1;

        while(child<length){
            int rChild=child+1;
            if(rChild<length && arr[rChild]>arr[child]){
                child++;
            }
            
            //将大的元素放在parent位置
            if(arr[child]>arr[parent]){
                int temp=arr[child];
                arr[child]=arr[parent];
                arr[parent]=temp;

                parent=child;
                child=parent*2+1;
            }else{
                break;
            }
        }
    }
}

小舟有话说

至此,八大排序已全部讲解完毕,其中要求我们熟练掌握的有三种排序:冒泡排序、快速排序、堆排序,大家一定要熟练记忆,堆排序虽然看起来难理解,但是只要懂了二叉树相关知识就不难。

如果觉得内容不错,那就点点赞,点点关注吧,下次找我不迷路~

相关推荐
chao1898446 小时前
基于 SPEA2 的多目标优化算法 MATLAB 实现
开发语言·算法·matlab
沪漂阿龙6 小时前
AI大模型面试题:支持向量机是什么?间隔最大化、软间隔、核函数、LinearSVC 全面拆解
人工智能·算法·支持向量机
little~钰7 小时前
倍增算法和ST表
算法
知识领航员8 小时前
蘑兔AI音乐深度实测:功能拆解、实测表现与适用场景
java·c语言·c++·人工智能·python·算法·github
薛定e的猫咪8 小时前
因果推理研究方向综述笔记
人工智能·笔记·深度学习·算法
如何原谅奋力过但无声9 小时前
【灵神高频面试题合集06-08】反转链表、快慢指针(环形链表/重排链表)、前后指针(删除链表/链表去重)
数据结构·python·算法·leetcode·链表
平行侠9 小时前
037插入排序 - 整理扑克牌的算法
数据结构·算法
ECT-OS-JiuHuaShan9 小时前
彻底定理化:从量子纠缠到量子代谢
数据库·人工智能·学习·算法·生活·量子计算
爱喝雪碧的可乐10 小时前
2026 腾讯广告算法大赛优秀方案启示:行为条件化多模态自回归生成推荐摘要
算法·数据挖掘·回归·推荐系统·推荐算法