我的编程空间,编程开发者的网络收藏夹
学习永远不晚

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

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

七大基于比较的排序算法(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. 在重新将堆调整为大根堆

    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

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

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

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

下载Word文档

猜你喜欢

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
2023-06-03

基于python的七种经典排序算法(推荐)

一、排序的基本概念和分类 所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。排序算法,就是如何使得记录按照要求排列的方法。 排序的稳定性:经过某种排序后,如果两个记录序号同等,且两者在原无序记录中的先后
2022-06-04

Java基于分治法实现的快速排序算法示例

本文实例讲述了Java基于分治法实现的快速排序算法。分享给大家供大家参考,具体如下:package cn.nwsuaf.quick;public cl
2023-05-30

各大排序算法的Objective-C实现以及图形化演示比较是怎样的

这期内容当中小编将会给大家带来有关各大排序算法的Objective-C实现以及图形化演示比较是怎样的,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。用Objective-C实现几种基本的排序算法,并把排序的
2023-06-17

Java如何使用“自然顺序”算法比较字符串(不区分大小写)

Java中的String.compareTo()不区分大小写,可使用String.compareToIgnoreCase()方法或自定义比较器实现。String.compareToIgnoreCase()转换为小写后再比较,效率更高。自定义比较器提供更复杂的比较规则,但性能较低。注意检查字符串是否为空,使用统一字符集,非ASCII字符使用Collator类比较。
Java如何使用“自然顺序”算法比较字符串(不区分大小写)
2024-04-02

java 中基本算法之希尔排序的实例详解

java 中基本算法之希尔排序的实例详解希尔排序(Shell Sort)是插入排序的一种。也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本。希尔排序是非稳定排序算法。该方法因DL.Shell于1959年提出而得名。希尔排序是把记录
2023-05-31

Java如何用“自然排序”算法对数组进行不区分大小写字母的排序

Java使用“自然排序”算法对字符串数组进行不区分大小写的排序。该算法通过定制比较器实现,将字符串转换为小写再比较。它可以按自然顺序对包含数字和大小写字母的字符串进行排序,且使用简单高效。局限性是仅适用于字符串,无法自定义排序顺序。替代方案是使用Guava库的Ordering.natural().nullsFirst()方法。此算法广泛应用于需要不区分大小写字母排序的场景。
Java如何用“自然排序”算法对数组进行不区分大小写字母的排序
2024-04-02

基数排序算法的原理与实现详解(Java/Go/Python/JS/C)

基数排序(RadixSort)是一种非比较型整数排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。本文将利用Java/Go/Python/JS/C不同语言实现基数排序算法,感兴趣的可以了解一下
2023-03-06

Java/Go/Python/JS/C基数排序算法的原理与实现方法是什么

这篇文章主要介绍“Java/Go/Python/JS/C基数排序算法的原理与实现方法是什么”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Java/Go/Python/JS/C基数排序算法的原理与实现
2023-07-05

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录