八种排序算法与代码实现(Java代码实现)

简介: 八大排序算法是:1、直接插入排序;2、希尔排序;3、简单选择排序;4、堆排序;5、冒泡排序;6、快速排序;7、归并排序;8、桶排序/基数排序。

选择排序

1.遍历整个序列,将最小的数放在最前面。
2.遍历剩下的序列,将最小的数放在最前面。
3.重复第二步,直到只剩下一个数。
  /**
     * 选择排序
     * @param arr 待排序的数组
     */
    public void selectSort(int[] arr){
        for (int i=0;i<arr.length;++i){
            for (int j=i+1;j< arr.length;++j){
                if (arr[i]>arr[j]){
                    arr[i]^=arr[j];
                    arr[j]^=arr[i];
                    arr[i]^=arr[j];
                }
            }
        }
    }

基数排序(桶排序)

1.将所有的数的个位数取出,按照个位数进行排序,构成一个序列。
2.将新构成的所有的数的十位数取出,按照十位数进行排序,构成一个序列。
注意:负数不行,小数不行
    public void radixSort(int[] arr) {

        int maxArr = arr[0];
        //首先获取数组中最大数的位数
        for (int i = 0; i < arr.length; i++) {
            if (maxArr < arr[i]) {
                maxArr = arr[i];
            }
        }
        //用特殊的方法获取整数的位数
        int maxLength = (maxArr + "").length();

        //准备开始排序
        //首先创建10个桶,用来存放数据
        int[][] bucket = new int[10][arr.length];
        //每个水桶的索引(即 每个水桶 里面有多少个数据)
        int[] bucketOfElement = new int[bucket.length];

        for (int l = 0, n = 1; l < maxLength; l++, n *= 10) {
            int currentnum = 0;
            //将arr数组中的数  进行分开,分到对应的桶中
            for (int i = 0; i < arr.length; i++) {
                currentnum = arr[i] / n % 10;
                bucket[currentnum][bucketOfElement[currentnum]] = arr[i];
                bucketOfElement[currentnum]++;
            }

            //依次将桶中的数据 合到数组中
            int indexArr = 0;
            int indexBucket = 0;
            for (int j = 0; j < bucketOfElement.length; j++) {
                while (bucketOfElement[j] != 0) {
                    arr[indexArr] = bucket[j][indexBucket];
                    indexArr += 1;
                    indexBucket += 1;
                    bucketOfElement[j]--;
                }
                indexBucket = 0;
            }
        }
    }




希尔排序

1.将数的个数设为n,取奇数k=n/2,将下标差值为k的书分为一组,构成有序序列。
2.再取k=k/2 ,将下标差值为k的书分为一组,构成有序序列。
3.重复第二步,直到k=1执行简单插入排序。

    public static int[] shellSort(int[] arr) {
        int temp = 0;
        //插入时 采用交换法
        for (int l = arr.length / 2; l > 0; l /= 2) {
            //遍历各组中所有的元素,(共有 l 组,每组有数个元素)。 l 为步长
            for (int i = l; i < arr.length; ++i) {
                for (int j = i; j - l >= 0; j -= l) {
                    //如果当前的元素大于 加上步长后的那个元素的话就 交换位置
                    if (arr[j] < arr[j - l]) {
                        temp = arr[j];
                        arr[j] = arr[j - l];
                        arr[j - l] = temp;
                    }
                }
            }
        }
        return arr;
    }




归并排序

1.选择相邻两个数组成一个有序序列。
2.选择相邻的两个有序序列组成一个有序序列。
3.重复第二步,直到全部组成一个有序序列。
/**
     * 归并排序
     * @param arr 需要排序的数组
     * @param left 数组左边的索引
     * @param right 数组右边的索引
     */
    public void mergetSort(int[] arr , int left ,int right){
        if (left<right){
            int mid = (left+right)/2;
            //向坐递归
            mergetSort(arr,left,mid);
            //向右递归
            mergetSort(arr,mid+1,right);
            //合并递归后的
            merget(arr,left,mid,right);
        }
    }
    
    /**
     * 合并的方法
     *
     * @param arr   需要排序的数组
     * @param left  左边有序序列的初始索引
     * @param mid   中间序列的索引
     * @param right 右边序列的索引
     */
    public void merget(int[] arr,int left,int mid,int right){

        int l =left;//初始化l,左边有序序列的初始索引
        int m = mid+1; //初始化m,右边有序序列的初始索引
        int index=0;//指向tempArr数组的当前索引
        //做中转的数组
        int[] tempArr=new int[right-left+1];
        //比较两个素组
        //先把左右两边  有序的  按照规则填充到temp数组中
        //直到 有一边的数组已经处理完毕
        while (l<=mid&&m<=right){
            //如果左边有序序列的当前元素 小于右边的有序序列的当前元素
            //即将左边的当前元素,填充到team
            //让后 l++   index++
            if (arr[l]<arr[m]){
                tempArr[index]=arr[l];
                l++;
            }else{  //反之 将右边的当前元素  填充到team数组中
                tempArr[index]=arr[m];
                m++;
            }
            index++;
        }
        //把剩余数组 依次填充到tempArr 数组中
        
        //如果左边有剩余,就把左边的全部加进去
        while (l<=mid){
            tempArr[index]=arr[l];
            l++;
            index++;
        }
        //如果右边有剩余,就把右边的全部加进去
        while(m<=right){
            tempArr[index]=arr[m];
            m++;
            index++;
        }
        //将tempArr中 有序的元素,添加到 arr数组中
        int i=0;
        while (left<=right){
            arr[left]=tempArr[i];
            i++;
            left++;
        }
    }




插入排序

1.将第一个数和第二个数排序,然后构成一个有序序列
2.将第三个数插入进去,构成一个新的有序序列。
3.对第四个数、第五个数……直到最后一个数,重复第二步。
    /**
     * 插入排序
     *
     * @param arr 需要排序的数组
     */
    public void insertSort(int[] arr) {
        for (int i = 1; i < arr.length; ++i) {
            for (int j = 0; j < i; ++j) {
                if (arr[i]<arr[j]){
                    arr[j]^=arr[i];
                    arr[i]^=arr[j];
                    arr[j]^=arr[i];
                }
            }
        }
    }




冒泡排序

1.将序列中所有元素两两比较,将最大的放在最后面。
2.将剩余序列中所有元素两两比较,将最大的放在最后面。
3.重复第二步,直到只剩下一个数。
   /**
     * 冒泡排序
     *
     * @param arr 待排序的数组
     */
    public void bubbleSort(int[] arr) {
        for (int i = arr.length; i > 0; --i) {
            for (int j = 1; j < i; ++j) {
                if (arr[j] < arr[j - 1]) {
                    //交换位置
                    arr[j] ^= arr[j - 1];
                    arr[j - 1] ^= arr[j];
                    arr[j] ^= arr[j - 1];
                }
            }
        }
    }




堆排序

思路:
1.将序列构建成大顶堆。
2.将根节点与最后一个节点交换,然后断开最后一个节点。
3.重复第一、二步,直到所有节点断开。
/**
     * 堆排序
     *
     * @param arr 待排序的数组
     */
    public void headSort(int[] arr) {
        int len = arr.length - 1;
        //利用循环 排成大顶堆 (叶子结点 小于父节点 满足a[i]>a[i*2+1]&&a[i]>a[i*2+2]条件)
        for (int i = len / 2 - 1; i >= 0; --i) {
            swap(arr, i, len);
        }
        int temp = 0;
        //排完序之后堆顶一定是最大的数,让后把最大的数放到数组最后面断开节点
        for (; len > 0; len--) {
            temp = arr[len];
            arr[len] = arr[0];
            arr[0] = temp;
            swap(arr, 0, len - 1);
        }
    }

public void swap(int[] arr, int k, int len) {

        for (int i = k * 2 + 1; i <= len; i = i * 2 + 1) {
            if (i < len && arr[i] < arr[i + 1]) i++;

            if (arr[i] > arr[k]) {
                int temp = arr[k];
                arr[k] = arr[i];
                arr[i] = temp;
                k = i;
            }
        }
    }




快速排序

思路:
1.选择第一个数为p,小于p的数放在左边,大于p的数放在右边。
2.递归的将p左边和右边的数都按照第一步进行,直到不能递归。
 /**
     * 快速排序
     *
     * @param arr   需要排序的数组
     * @param left  0
     * @param right 数组的长度-1
     */
    public void fastSort(int[] arr, int left, int right) {
        int l = left;
        int r = right;
        int mid = (l + r) / 2;
        while (l < r) {
            //在左边找到大于的值
            while (arr[l] < arr[mid]) l++;
            //在右边找到小于的值
            while (arr[r] > arr[mid]) r--;
            //如果 l>= r ,则说明 mid左边全是小于arr[mid]的数,右边全是大于arr[mid]的数
            if (l >= r) break;
            //交换位置
            int temp = arr[l];
            arr[l] = arr[r];
            arr[r] = temp;

            //如果交换完之后, 发现arr[l] == arr[mid] 则r-- ,前移
            if (arr[l] == arr[mid]) {
                r -= 1;
            }
            //如果交换完之后, 发现arr[r]==arr[mid]  则l--,往后移
            if (arr[r] == arr[mid]) {
                l += 1;
            }
        }
        // 如果 l == r, 必须l++, r--, 否则为出现栈溢出
        if (l == r) {
            l++;
            r--;
        }
        //向右递归
        if (l < right) fastSort(arr, l, right);
        //向左递归
        if (r > left) fastSort(arr, left, r);
    }
目录
相关文章
|
11天前
|
安全 Java 编译器
深入理解Java中synchronized三种使用方式:助您写出线程安全的代码
`synchronized` 是 Java 中的关键字,用于实现线程同步,确保多个线程互斥访问共享资源。它通过内置的监视器锁机制,防止多个线程同时执行被 `synchronized` 修饰的方法或代码块。`synchronized` 可以修饰非静态方法、静态方法和代码块,分别锁定实例对象、类对象或指定的对象。其底层原理基于 JVM 的指令和对象的监视器,JDK 1.6 后引入了偏向锁、轻量级锁等优化措施,提高了性能。
34 3
|
2月前
|
Java
java小工具util系列4:基础工具代码(Msg、PageResult、Response、常量、枚举)
java小工具util系列4:基础工具代码(Msg、PageResult、Response、常量、枚举)
54 24
|
18天前
|
前端开发 Java 测试技术
java日常开发中如何写出优雅的好维护的代码
代码可读性太差,实际是给团队后续开发中埋坑,优化在平时,没有那个团队会说我专门给你一个月来优化之前的代码,所以在日常开发中就要多注意可读性问题,不要写出几天之后自己都看不懂的代码。
54 2
|
1月前
|
存储 算法 程序员
C 语言递归算法:以简洁代码驾驭复杂逻辑
C语言递归算法简介:通过简洁的代码实现复杂的逻辑处理,递归函数自我调用解决分层问题,高效而优雅。适用于树形结构遍历、数学计算等领域。
|
1月前
|
Java 编译器 数据库
Java 中的注解(Annotations):代码中的 “元数据” 魔法
Java注解是代码中的“元数据”标签,不直接参与业务逻辑,但在编译或运行时提供重要信息。本文介绍了注解的基础语法、内置注解的应用场景,以及如何自定义注解和结合AOP技术实现方法执行日志记录,展示了注解在提升代码质量、简化开发流程和增强程序功能方面的强大作用。
77 5
|
1月前
|
存储 算法 Java
Java 内存管理与优化:掌控堆与栈,雕琢高效代码
Java内存管理与优化是提升程序性能的关键。掌握堆与栈的运作机制,学习如何有效管理内存资源,雕琢出更加高效的代码,是每个Java开发者必备的技能。
55 5
|
2月前
|
Java API 开发者
Java中的Lambda表达式:简洁代码的利器####
本文探讨了Java中Lambda表达式的概念、用途及其在简化代码和提高开发效率方面的显著作用。通过具体实例,展示了Lambda表达式如何在Java 8及更高版本中替代传统的匿名内部类,使代码更加简洁易读。文章还简要介绍了Lambda表达式的语法和常见用法,帮助开发者更好地理解和应用这一强大的工具。 ####
|
2月前
|
并行计算 算法 测试技术
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面,旨在通过综合策略提升程序性能,满足实际需求。
65 1
|
2月前
|
Java API Maven
商汤人像如何对接?Java代码如何写?
商汤人像如何对接?Java代码如何写?
48 5
|
1月前
|
安全 Java API
Java中的Lambda表达式:简化代码的现代魔法
在Java 8的发布中,Lambda表达式的引入无疑是一场编程范式的革命。它不仅让代码变得更加简洁,还使得函数式编程在Java中成为可能。本文将深入探讨Lambda表达式如何改变我们编写和维护Java代码的方式,以及它是如何提升我们编码效率的。