七大基于比较的排序算法(JAVA)

这篇具有很好参考价值的文章主要介绍了七大基于比较的排序算法(JAVA)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

冒泡排序

优化:

堆排序

插入排序

希尔排序

归并排序

快速排序

优化

选择排序 


 排序算法的稳定性大小相同的元素在排序前后相对位置相同就称其为稳定的排序。

注:一个本身就是稳定的排序 是可以实现为不稳定的排序的 ;但是相反 一个本身就不稳定的排序 是不可能实现为稳定的排序的。

稳定的排序算法:插入排序 冒泡排序 归并排序

冒泡排序

时间复杂度: o(n^2)   如果加了优化  最好情况O(N)
空间复杂度:O(1)
稳定性: 稳定

    public static void bubbleSort(int[] array){

        for (int i = 0; i < array.length-1; i++) {
            for (int j = 0; j < array.length-1; j++) {
                if (array[j] > array[j+1]) {
                    swap(array, j, j+1);
                }
            }
        }
    }

    private static void swap(int[] array, int minIndex, int i) {
        int tmp = array[i];
        array[i] = array[minIndex];
        array[minIndex] = tmp;
    }

优化:

     public static void bubbleSort(int[] array) {
        for (int i = 0; i < array.length-1; i++) {
            boolean flg = false;
            for (int j = 0; j < array.length-1-i; j++) {
                if(array[j] > array[j+1]) {
                    swap(array,j,j+1);
                    flg = true;
                }
            }
            if(!flg) {
                return;
            }
        }
    }

堆排序

时间复杂度:O(n*logN)    N^1.3 -->
空间复杂度:O(1)
稳定性:不稳定
数据量非常 大的时候 堆排 一定比希尔快

堆排序的原理:

  1. 用一个大根堆的堆顶元素和最后一个元素交换
  2. 使数组长度减一
  3. 在重新将堆调整为大根堆

七大基于比较的排序算法(JAVA),算法,排序算法,java

    public static void heapSort(int[] array){

        createHeap(array);
        for (int i = 0; i < array.length - 1; i++) {
            swap(array, 0, array.length-1-i);
            shiftDown(array, 0, array.length-1-i);
        }
    }

    private static void createHeap(int[] array) {
        for (int i = (array.length-1-1)/2; i >= 0; i--) {
            shiftDown(array, i, array.length);
        }
    }

    private static void shiftDown(int[] array, int i, int length) {//length个元素
        int child = i * 2 + 1;
        while (child < length) {
            if (child + 1 < length && array[child] < array[child+1]) {
                child++;
            }
            if (array[child] > array[i]) {
                swap(array, child, i);
                i = child;
            }else {
                break;
            }
            child = i * 2 + 1;
        }
    }
    private static void swap(int[] array, int minIndex, int i) {
        int tmp = array[i];
        array[i] = array[minIndex];
        array[minIndex] = tmp;
    }

插入排序

时间复杂度:
        最好情况:数据完全有序的时候 O(N)
        最坏情况:数据完全逆序的时候 O(N^2)
空间复杂度:O(1)
稳定性:稳定


插入排序的原理

  1. 从左边第一位开始挨个令其成为关键码
  2. 从左到右把待排序的记录按其关键码值的大小逐个插入到左边已经排好序的有序序列中
  3. 直到所有的记录插入完为止,得到一个新的有序序列
    public static void insertSort(int[] array){

        for (int i = 1; i < array.length; i++) {
            int tmp = array[i];
            int j = i - 1;
            for (; j >= 0 ; j--) {
                //如果此处改为array[j] >= tmp就会变成不稳定排序
                if (array[j] > tmp) {
                    array[j+1] = array[j];
                }else{
                    break;
                }
            }
            array[j+1] = tmp;
        }
    }

希尔排序

时间复杂度:
             约等于:n^1.3 - n^1.5
复杂度:O(1)
稳定性:不稳定

希尔排序其实就是对插入排序的一种优化

基本原理:

  1. 先按照步长将数组分为若干组
  2. 对每组进行插入排序
  3. 减小步长重复以上步骤

七大基于比较的排序算法(JAVA),算法,排序算法,java

    public static void shellSort(int[] array){

        int gap = array.length;
        while (gap > 1) {
            gap = gap / 2;
            shell(array, gap);
        }
    }

    private static void shell(int[] array, int gap) {
        for (int i = gap; i < array.length; i++) {
            int tmp = array[i];
            int j = i-gap;
            for (; j >= 0; j -= gap) {
                if (array[j] > tmp) {
                    array[j+gap] = array[j];
                }else {
                    break;
                }
            }
            array[j+gap] = tmp;
        }
    }

归并排序

时间复杂度: 0(N*logN)
空间复杂度:O(n)
稳定性: 稳定

归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。

可参考:

    public void mergerSort(int[] nums, int left, int right) {//right:数组长度减一
        if (left >= right) {
            return;
        }
        int mid = (left + right) / 2;
        mergerSort(nums, left, mid);
        mergerSort(nums, mid + 1, right);
        merger(nums, left, mid, right);
    }

    private void merger(int[] nums, int left, int mid, int right) {
        int[] tmp = new int[right-left+1];
        int i = 0;
        int l = left;
        int r = mid + 1;
        while (l <= mid && r <= right) {
            if (nums[l] < nums[r]) {
                tmp[i++] = nums[l++];
            }else {
                tmp[i++] = nums[r++];
            }
        }
        while (l <= mid) {
            tmp[i++] = nums[l++];
        }
        while (r <= right) {
            tmp[i++] = nums[r++];
        }
        i = 0;
        for (int j = 0; j < tmp.length; j++) {
            nums[left++] = tmp[j];
        }
    }

快速排序

时间复杂度:
        最好情况:O(N*logN)   满二叉树/完全二叉树
        最坏情况:O(N^2) 单分支的树
空间复杂度:
        最好情况:O(logN)   满二叉树/完全二叉树
        最坏情况:O(N)   单 分支的树
稳定性:不稳定

快速排序基本原理

  1. 任取待排序元素序列中的某元素作为基准值
  2. 按照该排序码将待排序集合分割成两子序列,左子序列中所有元素均小于基准值,右子序列中所有元素均大于基准值
  3. 每个子序列重复该过程,直到所有元素都排列在相应位置上为止

有Hoare法   挖坑版法  前后指针法
这里只介绍Hoare法

    public static void quickSort(int[] array){

        quick(array, 0, array.length-1);
    }

    private static void quick(int[] array, int left, int right) {
        if (left >= right) {
            return;
        }
        int Index = findSwap(array, left, right);
        quick(array, left, Index-1);
        quick(array, Index+1, right);

    }
    
    private static int findSwap(int[] array, int left, int right) {
        int key = array[left];
        int keyIndex = left;
        while (left < right) {
            //必须right先走
            //如果是left先走,两个相遇的地方一定比key大
            while (left < right && array[right] >= key) {
                right--;
            }
            while (left < right && array[left] <= key) {
                left++;
            }
            swap(array, right, left);
        }
        if (left == right) {
            swap(array, keyIndex, left);
        }
        return left;
    }

    private static void swap(int[] array, int minIndex, int i) {
        int tmp = array[i];
        array[i] = array[minIndex];
        array[minIndex] = tmp;
    }

优化

利用三数取中法来避免单分支树的形成(尽量降低树的高度)

    public int[] sortArray(int[] nums) {
        //快速排序
        quickSort(nums, 0, nums.length-1);
        return nums;
    }

    private void quickSort(int[] nums, int left, int right) {
        if (left >= right) {
            return;
        }
        //三数取中法
        swap(nums, left, threeNumMid(nums, left, right));
        //也可以在这里加一个判断当左右之间的数据个数小于一定值然后调用插入排序
        //因为在排序过程中数组会趋近于有序所以插入排序的效率会很快
        int pivot = quick(nums, left, right);
        quickSort(nums, left, pivot-1);
        quickSort(nums, pivot+1, right);
    }

    private int threeNumMid(int[] nums, int left, int right) {
        int mid = (left + right) / 2;
        if (nums[left] > nums[right]) {
            if (nums[mid] > nums[left]) {
                return left;
            }else if (nums[mid] < nums[right]) {
                return right;
            }else {
                return mid;
            }
        }else {
            if (nums[mid] < nums[left]) {
                return left;
            }else if (nums[mid] > nums[right]) {
                return right;
            }else {
                return mid;
            }
        }
    }

    private int quick(int[] nums, int left, int right) {
        int index = left;
        int key = nums[left];
        while (left < right) {
            while (left < right && nums[right] >= key) {
                right--;
            }
            while (left < right && nums[left] <= key) {
                left++;
            }
            swap(nums, right, left);
        }
        swap(nums, index, left);
        return left;
    }

    private void swap(int[] nums, int left, int right) {
        int tmp = nums[left];
        nums[left] = nums[right];
        nums[right] = tmp;
    }

选择排序 

时间复杂度:O(n^2)
空间复杂度:O(1)
稳定性:不稳定的排序

选择排序基本原理:文章来源地址https://www.toymoban.com/news/detail-714996.html

  1. 从左至右每一次从待排序的数据元素中选出最小(或最大)的一个元素
  2. 将其放在待排序元素的起始位置,已有序元素的最后边
  3. 重复上述步骤直到全部待排序的数据元素排完 。
    public static void selectSort(int[] array){

        for (int i = 0; i < array.length; i++) {
            int minIndex = i;
            for (int j = i+1; j < array.length; j++) {
                if (array[minIndex] > array[j]) {
                    minIndex = j;
                }
            }
            swap(array, minIndex, i);
        }
    }

    private static void swap(int[] array, int minIndex, int i) {
        int tmp = array[i];
        array[i] = array[minIndex];
        array[minIndex] = tmp;
    }

到了这里,关于七大基于比较的排序算法(JAVA)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 七大排序算法——堆排序,通俗易懂的思路讲解与图解(完整Java代码)

    排序:所谓排序,就是使一串记录,按照其中的某个或某些的大小,递增或递减的排列起来的操作。 上述待排序的数中,有两个5。 将 前面 的5标记一个a, 将 后面 的5标记一个b。 通过算法进行排序后,这一组数就有序了, 但是要看两个相同的5的位置是否有改变。

    2024年02月16日
    浏览(21)
  • 七大排序算法——归并排序,通俗易懂的思路讲解与图解(完整Java代码)

    排序:所谓排序,就是使一串记录,按照其中的某个或某些的大小,递增或递减的排列起来的操作。 上述待排序的数中,有两个5。 将 前面 的5标记一个a, 将 后面 的5标记一个b。 通过算法进行排序后,这一组数就有序了, 但是要看两个相同的5的位置是否有改变。

    2024年02月15日
    浏览(37)
  • 七大排序算法——冒泡排序,通俗易懂的思路讲解与图解(完整Java代码)

    排序:所谓排序,就是使一串记录,按照其中的某个或某些的大小,递增或递减的排列起来的操作。 上述待排序的数中,有两个5。 将 前面 的5标记一个a, 将 后面 的5标记一个b。 通过算法进行排序后,这一组数就有序了, 但是要看两个相同的5的位置是否有改变。

    2024年02月16日
    浏览(25)
  • 数据结构与算法中的七大排序(Java实现)

    目录 一、直接插入排序 二、希尔排序 三、直接选择排序 四、堆排序 五、冒泡排序 六、快速排序 七、归并排序               定义i下标之前的元素全部已经有序 ,遍历一遍要排序的数组,把i下标前的元素全部进行排序,当遍历玩这个数组后,就已经排好序了。        

    2024年02月06日
    浏览(38)
  • 十大排序——11.十大排序的比较汇总及Java中自带的排序算法

    这篇文章对排序算法进行一个汇总比较! 目录 0.十大排序汇总 0.1概述 0.2比较和非比较的区别 0.3基本术语 0.4排序算法的复杂度及稳定性 1.冒泡排序 算法简介 动图演示 代码演示 应用场景 算法分析 2.快速排序 算法简介 动图演示 代码演示 应用场景 算法分析 3.插入排序 算法简

    2024年04月29日
    浏览(24)
  • Java 七大排序之快速排序(三种方法包含优化方法)

    任取待排序元素序列中的某元素作为基准值,按照该排序码将待排序集合分割成两子序列,左子序列中所有元素均小于基准值,右子序列中所有元素均大于基准值,然后最左右子序列重复该过程,直到所有元素都排列在相应位置上为止。 1)  挖坑法 划分完之后,再左右递归。

    2024年02月09日
    浏览(26)
  • 数据结构中的七大排序(Java实现)

    目录 一、直接插入排序 二、希尔排序 三、直接选择排序 四、堆排序 五、冒泡排序 六、快速排序 七、归并排序               定义i下标之前的元素全部已经有序 ,遍历一遍要排序的数组,把i下标前的元素全部进行排序,当遍历玩这个数组后,就已经排好序了。        

    2024年02月08日
    浏览(35)
  • 七大排序算法和计数排序

    以下排序以从小到大排序为例 时间复杂度: 最好情况:完全有序的情况 1 2 3 4 5 O(N) 最坏情况:完全逆序的情况 5 4 3 2 1 O(N^2)(相当于等差数列求和) 空间复杂度:O(1) 稳定性:稳定 当所给的数据越有序,直接插入排序越快 有一组基本有序的数据时,用直接插入排序较好 希

    2024年02月16日
    浏览(31)
  • java自然排序Comparable和比较器排序Comparator

    案例需求 存储学生对象并遍历,创建TreeSet集合使用无参构造方法 要求:按照年龄从小到大排序,年龄相同时,按照姓名的字母顺序排序 实现步骤 使用空参构造创建TreeSet集合 用TreeSet集合存储自定义对象,无参构造方法使用的是自然排序对元素进行排序的 自定义的Student类实

    2024年02月07日
    浏览(70)
  • java linq多字段排序时间比较

            使用的基础类

    2024年02月14日
    浏览(26)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包