iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > JAVA >七大基于比较的排序算法(JAVA)
  • 240
分享到

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

算法排序算法java 2023-10-11 11:10:09 240人浏览 泡泡鱼
摘要

目录 冒泡排序 优化: 堆排序 插入排序 希尔排序 归并排序 快速排序 优化 选择排序   排序算法的稳定性: 大小相同的元素在排序前后相对位置相同就称其为稳定的排序。 注:一个本身就是稳定的排序 是可以实现为不稳定的排序的 ;但是相反

目录

冒泡排序

优化:

堆排序

插入排序

希尔排序

归并排序

快速排序

优化

选择排序 


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

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

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

冒泡排序

时间复杂度: 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. 在重新将堆调整为大根堆

    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. 减小步长重复以上步骤

    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)
稳定性: 稳定

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

可参考:icon-default.png?t=N7T8Http://t.csdnimg.cn/Yd62c

    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)
稳定性:不稳定的排序

选择排序基本原理:

  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;    }

来源地址:https://blog.csdn.net/2302_76339343/article/details/133498231

--结束END--

本文标题: 七大基于比较的排序算法(JAVA)

本文链接: https://www.lsjlt.com/news/428225.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 七大基于比较的排序算法(JAVA)
    目录 冒泡排序 优化: 堆排序 插入排序 希尔排序 归并排序 快速排序 优化 选择排序   排序算法的稳定性: 大小相同的元素在排序前后相对位置相同就称其为稳定的排序。 注:一个本身就是稳定的排序 是可以实现为不稳定的排序的 ;但是相反...
    99+
    2023-10-11
    算法 排序算法 java
  • Java重点之基于比较的七大排序
    七大基于比较的排序 直接插入排序 思想:以双指针来进行遍历数组和寻找较小元素的操作,每次找到较小元素的时候就将其插入到前面的适当位置,当遍历完整个数组,并完成插入操作后,排序完成。 ...
    99+
    2024-04-02
  • 七大排序算法详解
    1.概念 1.排序的稳定性 常见的稳定的排序有三种:直接插入排序,冒泡排序,归并排序 对于一组数据元素排列,使用某种排序算法对它进行排序,若相同数据之间的前后位置排序后和未排序之前是相同的,我们就...
    99+
    2023-09-10
    排序算法 算法 数据结构
  • Java排序算法速度比较(转载)
    public class Sort { public void swap(int a[], int i, int j) { int tmp = a[i]; a[i] = a[j]; a[j] = tmp; } p...
    99+
    2023-06-03
  • Java数据结构之基于比较的排序算法基本原理及具体实现
    目录1. 七大基于比较的排序-总览1.1常见基于比较的排序分类1.2时间复杂度,空间复杂度以及稳定性。2.直接插入排序2.1 直接插入排序的基本思想2.2 直接插入排序动画演示2.3...
    99+
    2024-04-02
  • 七大经典排序算法图解
    目录插入排序①直接插入排序基本思想动图演示代码实现②希尔排序基本思想图示代码实现选择排序③直接选择排序基本思想动图演示代码实现④堆排序基本思想建堆需要注意的问题图示代码实现交换排序⑤...
    99+
    2024-04-02
  • Java基础之八大排序算法
    目录前言一、直接插入排序二、希尔排序三、简单选择排序四、堆排序五、冒泡排序六、快速排序七、归并排序八、基数排序(桶排序)前言 关系 复杂度 一、直接插入排序 基本思想: 将新的数...
    99+
    2024-04-02
  • JAVA十大排序算法之基数排序详解
    目录基数排序代码实现时间复杂度算法稳定性基数排序 vs 桶排序 vs 计数排序总结基数排序 常见的数据元素一般是由若干位组成的,比如字符串由若干字符组成,整数由若干位0~9数字组成。...
    99+
    2024-04-02
  • Java中七种排序算法总结分析
    目录前言:对文章出现的一些名词进行解释一、插入排序1.基本思想2.直接插入排序3.希尔排序(缩小增量排序)二、选择排序1.基本思想2.直接选择排序3.堆排序三、交换排序1.基本思想2...
    99+
    2024-04-02
  • JAVA十大排序算法之桶排序详解
    目录桶排序代码实现时间复杂度算法稳定性总结桶排序 桶排序是计数排序的升级,计数排序可以看成每个桶只存储相同元素,而桶排序每个桶存储一定范围的元素,通过函数的某种映射关系,将待排序数组...
    99+
    2024-04-02
  • JavaScript中基本排序算法定义与效率比较的示例分析
    这篇文章主要介绍JavaScript中基本排序算法定义与效率比较的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!一、数组测试平台javascript数据结构与算法--基本排序...
    99+
    2024-04-02
  • Java基于分治法实现的快速排序算法示例
    本文实例讲述了Java基于分治法实现的快速排序算法。分享给大家供大家参考,具体如下:package cn.nwsuaf.quick;public class Quick { public static void swap(int[] ...
    99+
    2023-05-30
    java 分治法 快速排序
  • JAVA十大排序算法之堆排序详解
    目录堆排序知识补充二叉树满二叉树完全二叉树二叉堆代码实现时间复杂度算法稳定性思考总结堆排序 这里的堆并不是JVM中堆栈的堆,而是一种特殊的二叉树,通常也叫作二叉堆。它具有以下特点: ...
    99+
    2024-04-02
  • Java十大排序算法之堆排序刨析
    二叉堆是完全二叉树或者是近似完全二叉树。 二叉堆满足二个特性︰ 1.父结点的键值总是大于或等于(小于或等于)任何一个子节点的键值。 2.每个结点的左子树和右子树都是一个二叉堆(都是最...
    99+
    2024-04-02
  • 用JavaScript实现的七种排序算法
    这篇文章主要讲解了“用JavaScript实现的七种排序算法”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“用JavaScript实现的七种排序算法”吧!目录前言冒泡排序基础算法第二种写法是在...
    99+
    2023-06-20
  • Java 七大排序之快速排序(三种方法包含优化方法)
    (1)基本思想 任取待排序元素序列中的某元素作为基准值,按照该排序码将待排序集合分割成两子序列,左子序列中所有元素均小于基准值,右子序列中所有元素均大于基准值,然后最左右子序列重复该过程,直到所有元素都排列在相应位置上为止。 (2)代码实现...
    99+
    2023-09-07
    java 排序算法 数据结构 算法
  • JAVA十大排序算法之快速排序详解
    目录快速排序问题思路荷兰国旗问题代码实现时间复杂度算法稳定性总结快速排序 快速排序是对冒泡排序的一种改进,也是采用分治法的一个典型的应用。JDK中Arrays的sort()方法,具体...
    99+
    2024-04-02
  • Java十大排序算法之计数排序刨析
    计数排序是非比较的排序算法,用辅助数组对数组中出现的数字计数,元素转下标,下标转元素 计数排序优缺点 优点:快 缺点:数据范围很大,比较稀疏,会导致辅助空间很大,造成空间的浪费 使用...
    99+
    2024-04-02
  • JAVA十大排序算法之插入排序详解
    目录插入排序代码实现动图演示代码实现时间复杂度算法稳定性总结插入排序 当我们在玩扑克牌的时候,总是在牌堆里面抽取最顶部的一张然后按顺序在手中排列。 插入排序是指在待排序的元素中,假设...
    99+
    2024-04-02
  • Java 十大排序算法之希尔排序刨析
    目录希尔排序原理希尔排序的API设计希尔排序的代码实现希尔排序是插入排序的一种,又称"缩小增量排序”,是插入排序算法的一种更高效的改进版本。 希尔排序原理 1.选定一个增长量h,按照...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作