iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >Java十大排序算法怎么实现
  • 189
分享到

Java十大排序算法怎么实现

2023-06-29 22:06:39 189人浏览 薄情痞子
摘要

本篇内容介绍了“Java十大排序算法怎么实现”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!排序算法的稳定性:  &nbs

本篇内容介绍了“Java十大排序算法怎么实现”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

Java十大排序算法怎么实现

排序算法的稳定性:

        假定在待排序的记录序列中,存在多个具有相同的关键字的记录,如果排序以后,保证这些记录的相对次序保持不变,即在原序列中,a[i]=a[j],且 a[i] 在 a[j] 之前,排序后保证 a[i] 仍在 a[j] 之前,则称这种排序算法是稳定的;否则称为不稳定的。

Java十大排序算法怎么实现

一.选择排序

每次从待排序的元素中选择最小的元素,依次和第1、2、3...位置的元素进行交换。这样在数组前面的部分形成有序区域。每进行一次交换,有序区域长度加一。

Java十大排序算法怎么实现

public static void selectionSort(int[] arr){    //细节一:这里可以是arr.length也可以是arr.length-1    for (int i = 0; i < arr.length-1 ; i++) {        int mini = i;        for (int j = i+1; j < arr.length; j++) {            //切换条件,决定升序还是降序            if(arr[mini]>arr[j]) mini =j;        }        swap(arr,mini,i);    }}

二.冒泡排序

        依次比较相邻的两个数,如果顺序错误就把他们交换过来,这样的话,每一轮比较下来都可以把最大的数放到它应该在的位置。(就像是把最大的气泡冒到最上层一样)

         这里解释一下顺序错误的含义。我们按照按升序排序,后面的值应该大于等于前面的值,如果不满足的话,就交换。

Java十大排序算法怎么实现

public static void bubbleSort(int[] arr){    for (int i = 0; i < arr.length-1; i++) {        //记录本次有没有进行交换的操作        boolean flag = false;        //保存在头就动头,保存在尾就动尾        for(int j =0 ; j < arr.length-1-i ; j++){            //升序降序选择地            if(arr[j] > arr[j+1])            {                swap(arr,j,j+1);                flag = true;            }        }        //如果本次没有进行交换操作,表示数据已经有序        if(!flag){break;} //程序结束    }}

三.插入排序

        插入排序其实可以理解为我们玩扑克时摸牌的过程,我们在摸牌的时候手里的牌总是有序的,每摸一张牌,就把这张牌插到它应该在的位置。等所有的牌都摸完了以后,全部的牌就都有序了。

Java十大排序算法怎么实现

 思考:数组前面形成了有序区域,那我查找当前数字应该插入位置的时候,用二分进行,是不是就可以把插入排序的复杂度优化到O(nlogn)了呀?

        二分倒是可以log的复杂度找到位置。 关键是如果用数组存储的话,插入的时候数据后移还是O(n)的复杂度。如果用链表的话,找到位置插入是O(1)的了,但是链表也没办法二分呀。

public static void insertSort(int[] arr){        //从第二个数开始,把每个数依次插入到指定的位置        for(int i = 1 ; i < arr.length ; i++)        {            int key = arr[i];            int j = i-1;            //大的后移操作            while(j >= 0 && arr[j] > key)            {                arr[j+1] = arr[j];                j--;            }            arr[j+1] = key;        }    }

四.希尔排序

        希尔排序是Donald shell于1959年提出的一种排序算法,是对直接插入排序的改进之后的高效版本。 希尔排序需要准备一组数据作为增量序列。

这组数据需要满足以下三个条件:

数据递减排列

数据中的最大值小于待排序数组的长度

数据中的最小值是1。

        只要满足上述要求的数组都可以作为增量序列,但是不同的增量序列会影响到排序的效率。这里我们用{5,3,1}作为增量序列来进行讲解

Java十大排序算法怎么实现

 实现优化的原因:减少数据量,使O(n)和O(n^2)的差距并不大

public static void shellSort(int[] arr){        //分块处理        int gap = arr.length/2; //增量        while(1<=gap)        {            //插入排序:只不过是与增量位交换            for(int i = gap ; i < arr.length ; i++)            {                int key = arr[i];                int j = i-gap;                while(j >= 0 && arr[j] > key)                {                    arr[j+gap] = arr[j];                    j-=gap;                }                arr[j+gap] = key;            }            gap = gap/2;        }    }

五.堆排序

是一棵完全二叉树,分为大根堆、小根堆两种

可以O(1)取最大/小值,可以O(logn)删除最大/小值,可以O(logn)插入元素

MIN-HEapiFY(i)操作:

我们假设完全二叉树中某节点 i 的左子树和右子树都满足小根堆的性质,假设 i 节点的左孩子是 left_i,i 节点的右孩子是 rigℎt_i。那如果 a[i] 大于 a[left_i] 或 a[rigℎt_i] 的话,那以 i 节点为根节点的整棵子树就不满足小根堆的性质了,我们现在要进行一个操作:把以 i 为根节点的这棵子树调整成小根堆。

Java十大排序算法怎么实现

//堆排序    public static void heapSort(int[] arr){        //开始调整的位置为最后一个叶子节点        int start = (arr.length - 1)/2;        //从最后一个叶子节点开始遍历,调整二叉树        for (int i = start; i >= 0 ; i--){            maxHeap(arr, arr.length, i);        }         for (int i = arr.length - 1; i > 0; i--){            int temp = arr[0];            arr[0] = arr[i];            arr[i] = temp;            maxHeap(arr, i, 0);        }    }     //将二叉树调整为大顶堆    public static void maxHeap(int[] arr, int size, int index){        //建立左子节点        int leftnode = 2 * index + 1;        //建立右子节点        int rightNode = 2 * index + 2;         int maxNode = index;        //左子节点的值大于根节点时调整        if (leftNode < size && arr[leftNode] > arr[maxNode]){            maxNode = leftNode;        }        //右子节点的值大于根节点时调整        if (rightNode < size && arr[rightNode] > arr[maxNode]){            maxNode = rightNode;        }        if (maxNode != index){            int temp = arr[maxNode];            arr[maxNode] = arr[index];            arr[index] = temp;            //交换之后可能会破坏原来的结构,需要再次调整            //递归调用进行调整            maxHeap(arr, size, maxNode);        }    }

我使用的是大根堆,排序的过程归根下来就是:先左底根后右底根(看自己怎么写)->每个根向上在向下。(左右上下)

六.归并排序

        归并排序是分治法的典型应用,先来介绍一下分治法,分治法是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题&hellip;&hellip;直到最后子问题规模很小可以直接求解,再将子问题的解进行合并来得到原问题的解。

Java十大排序算法怎么实现

        归并排序分解子问题的过程就是每一次把数组分成2份,直到数组的长度为1(因为只有一个数字的数组是有序的)。然后再将相邻的有序数组合并成一个有序数组。直到全部合到一起,整个数组就排序完毕了。 现在要解决的问题就是如何把两个有序的数组合并成一个有序的数组。其实就是每次比较两个数组当前最小的两个元素,哪个小就选哪个

数组a

数组b

说明

答案数组

2,5,7

1,3,4

1<2,取1,数组b的指针后移

1

2,5,7

1,3,4

2<3,取2,数组a的指针后移

1,2

2,5,7

1,3,4

3<5,取3,数组b的指针后移

1,2,3

2,5,7

1,3,4

4<5,取4,数组b的指针后移

1,2,3,4

2,5,7

1,3,4

数组b中没有元素了,取5

1,2,3,4,5

2,5,7

1,3,4

数组b中没有元素了,取7

1,2,3,4,5,7

public static void mergeSort(int[] arr, int low, int high){        int middle = (high + low)/2;        if (low < high){            //递归排序左边            mergeSort(arr, low, middle);            //递归排序右边            mergeSort(arr, middle +1, high);            //将递归排序好的左右两边合并            merge(arr, low, middle, high);        }     }     public static void merge(int[] arr, int low, int middle, int high){        //存储归并后的临时数组        int[] temp = new int[high - low + 1];        int i = low;        int j = middle + 1;        //记录临时数组中存放数字的下标        int index = 0;        while (i <= middle && j <= high){            if (arr[i] < arr[j]){                temp[index] = arr[i];                i++;            } else {                temp[index] = arr[j];                j++;            }            index++;        }        //处理剩下的数据        while (j <= high){            temp[index] = arr[j];            j++;            index++;        }        while (i <= middle){            temp[index] = arr[i];            i++;            index++;        }        //将临时数组中的数据放回原来的数组        for (int k = 0; k < temp.length; ++k){            arr[k + low] = temp[k];        }    }

七.快速排序

        快速排序的工作原理是:从待排序数组中随便挑选一个数字作为基准数,把所有比它小的数字放在它的左边,所有比它大的数字放在它的右边。然后再对它左边的数组和右边的数组递归进行这样的操作。

        全部操作完以后整个数组就是有序的了。 把所有比基准数小的数字放在它的左边,所有比基准数大的数字放在它的右边。这个操作,我们称为“划分”(Partition)。

Java十大排序算法怎么实现

//快速排序public static void QuickSort1(int[] arr, int start, int end){int low = start, high = end;int temp;if(start < end){    int guard = arr[start];while(low != high){while(high > low && arr[high] >= guard) high--;while(low < high && arr[low] <= guard) low++;if(low < high){temp = arr[low];arr[low] = arr[high];arr[high] = temp;}}arr[start] = arr[low];arr[low] = guard;QuickSort1(arr, start, low-1);QuickSort1(arr, low+1, end);}}//快速排序改进版(填坑法)public static void QuickSort2(int[] arr, int start, int end){int low = start, high = end;if(start < end){while(low != high){    int guard = arr[start];//哨兵元素while(high > low && arr[high] >= guard) high--;arr[low] = arr[high];while(low < high && arr[low] <= guard) low++;arr[high] = arr[low];}arr[low] = guard;QuickSort2(arr, start, low-1);QuickSort2(arr, low+1, end);}}

八.鸽巢排序

        计算一下每一个数出现了多少次。举一个例子,比如待排序的数据中1出现了2次,2出现了0次,3出现了3次,4出现了1次,那么排好序的结果就是{1.1.3.3.3.4}。

Java十大排序算法怎么实现

//鸽巢排序    public static void PigeonholeSort(int[] arr){        //获取最大值        int k = 0;        for (int i = 0; i < arr.length; i++) {            k = Math.max(k,arr[i]);        }        //创建计数数组并且初始化为0        int[] cnt = new int[k+10];        for(int i = 0 ; i <= k ; i++) { cnt[i]=0; }        for(int i = 0 ; i < arr.length ;i++) { cnt[arr[i]]++; }        int j = 0;        for(int i = 0 ; i <=k ; i++)        {            while(cnt[i]!=0)            {                arr[j]=i;                j++;                cnt[i]--;            }        }    }

        鸽巢排序其实算不上是真正意义上的排序算法,它的局限性很大。只能对纯整数数组进行排序,举个例子,如果我们需要按学生的成绩进行排序。是一个学生+分数的结构那就不能排序了。

九.计数排序

        先考虑这样一个事情:如果对于待排序数据中的任意一个元素 a[i],我们知道有 m 个元素比它小,那么我们是不是就可以知道排好序以后这个元素应该在哪个位置了呢?(这里先假设数据中没有相等的元素)。计数排序主要就是依赖这个原理来实现的。

比如待排序数据是{2,4,0,2,4} 先和鸽巢一样做一个cnt数组{1,0,2,0,2}                                                                                                                                    0,1,2,3,4

此时cnt[i]表示数据i出现了多少次,

然后对cnt数组做一个前缀和{1,1,3,3,5}    :0,1,2,3,4

此时cnt[i]表示数据中小于等于i的数字有多少个

待排序数组

计数数组

说明

答案数组ans

2,4,0,2,4

1,1,3,3,5

初始状态

null,null,null,null,null,

2,4,0,2,4

1,1,3,3,5

cnt[4]=5,ans第5位赋值,cnt[4]-=1

null,null,null,null,4

2,4,0,2,4

1,1,3,3,4

cnt[2]=3,ans第3位赋值,cnt[2]-=1

null,null,2 null,4

2,4,0,2,4

1,1,2,3,4

cnt[0]=1,ans第1位赋值,cnt[0]-=1

0,null,2,null,4

2,4,0,2,4

0,1,2,3,4

cnt[4]=4,ans第4位赋值,cnt[4]-=1

0,null,2,4,4

2,4,0,2,4

0,1,2,3,3

cnt[2]=2,ans第2位赋值,cnt[2]-=1

0,2,2,4,4

十.基数排序

基数排序是通过不停的收集和分配来对数据进行排序的。

Java十大排序算法怎么实现

  • 因为是10进制数,所以我们准备十个桶来存分配的数。

  • 最大的数据是3位数,所以我们只需要进行3次收集和分配。

  • 需要先从低位开始收集和分配(不可从高位开始排,如果从高位开始排的话,高位排好的顺序会在排低位的时候被打乱,有兴趣的话自己手写模拟一下试试就可以了)

  • 在收集和分配的过程中,不要打乱已经排好的相对位置

        比如按十位分配的时候,152和155这两个数的10位都是5,并且分配之前152在155的前面,那么收集的时候152还是要放在155之前的。

//基数排序    public static void radixSort(int[] array) {        //基数排序        //首先确定排序的趟数;        int max = array[0];        for (int i = 1; i < array.length; i++) {            if (array[i] > max) {                max = array[i];            }        }        int time = 0;        //判断位数;        while (max > 0) {            max /= 10;            time++;        }        //建立10个队列;        List<ArrayList> queue = new ArrayList<ArrayList>();        for (int i = 0; i < 10; i++) {            ArrayList<Integer> queue1 = new ArrayList<Integer>();            queue.add(queue1);        }        //进行time次分配和收集;        for (int i = 0; i < time; i++) {            //分配数组元素;            for (int j = 0; j < array.length; j++) {                //得到数字的第time+1位数;                int x = array[j] % (int) Math.pow(10, i + 1) / (int) Math.pow(10, i);                ArrayList<Integer> queue2 = queue.get(x);                queue2.add(array[j]);                queue.set(x, queue2);            }            int count = 0;//元素计数器;            //收集队列元素;            for (int k = 0; k < 10; k++) {                while (queue.get(k).size() > 0) {                    ArrayList<Integer> queue3 = queue.get(k);                    array[count] = queue3.get(0);                    queue3.remove(0);                    count++;                }            }         }      }

“Java十大排序算法怎么实现”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

--结束END--

本文标题: Java十大排序算法怎么实现

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

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

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

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

下载Word文档
猜你喜欢
  • Java十大排序算法怎么实现
    本篇内容介绍了“Java十大排序算法怎么实现”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!排序算法的稳定性:  &nbs...
    99+
    2023-06-29
  • TypeScript十大排序算法插入排序怎么实现
    今天小编给大家分享一下TypeScript十大排序算法插入排序怎么实现的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。一. 插...
    99+
    2023-07-05
  • Python怎么实现十大经典排序算法
    这篇“Python怎么实现十大经典排序算法”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Python怎么实现十大经典排序算法...
    99+
    2023-06-29
  • 十大排序算法总结(Python3实现)
    目录   一、概述 二、算法简介及代码展示 1.冒泡排序 2.简单选择排序 3.简单插入排序 4.堆排序 5.快速排序 6.希尔排序 7.归并排序 8.计数排序 9.桶排序 10.基数排序 11.#代码说明 三、感悟总结 排序算法大概是...
    99+
    2023-01-31
    十大 算法
  • JavaScript如何实现十大排序算法
    本文小编为大家详细介绍“JavaScript如何实现十大排序算法”,内容详细,步骤清晰,细节处理妥当,希望这篇“JavaScript如何实现十大排序算法”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,...
    99+
    2024-04-02
  • Java十大经典排序算法的实现图解
    目录前言一、排序算法1.排序算法概述(百度百科)2.《数据结构与算法》中的排序算法3.算法分析二、十大经典排序算法(Java开发版)1.冒泡排序2.快速排序3.基数排序4.插入排序5...
    99+
    2024-04-02
  • JAVA十大排序算法之堆排序详解
    目录堆排序知识补充二叉树满二叉树完全二叉树二叉堆代码实现时间复杂度算法稳定性思考总结堆排序 这里的堆并不是JVM中堆栈的堆,而是一种特殊的二叉树,通常也叫作二叉堆。它具有以下特点: ...
    99+
    2024-04-02
  • JAVA十大排序算法之桶排序详解
    目录桶排序代码实现时间复杂度算法稳定性总结桶排序 桶排序是计数排序的升级,计数排序可以看成每个桶只存储相同元素,而桶排序每个桶存储一定范围的元素,通过函数的某种映射关系,将待排序数组...
    99+
    2024-04-02
  • Java十大排序算法之堆排序刨析
    二叉堆是完全二叉树或者是近似完全二叉树。 二叉堆满足二个特性︰ 1.父结点的键值总是大于或等于(小于或等于)任何一个子节点的键值。 2.每个结点的左子树和右子树都是一个二叉堆(都是最...
    99+
    2024-04-02
  • C++实现十大排序算法及排序算法常见问题
    目录前言0 概述1 冒泡排序2 选择排序3 插入排序4 希尔排序5 归并排序6 堆排序7 快速排序8 计数排序9 桶排序10 基数排序总结前言 本文为C++实现的十大排序算法及基于排...
    99+
    2024-04-02
  • JAVA十大排序算法之选择排序详解
    目录选择排序代码实现动图演示代码实现时间复杂度算法稳定性总结选择排序 1.找到数组中最大(或最小)的元素 2.将它和数组的第一个元素交换位置(如果第一个元素就是最大(小)元素那么它就...
    99+
    2024-04-02
  • JAVA十大排序算法之快速排序详解
    目录快速排序问题思路荷兰国旗问题代码实现时间复杂度算法稳定性总结快速排序 快速排序是对冒泡排序的一种改进,也是采用分治法的一个典型的应用。JDK中Arrays的sort()方法,具体...
    99+
    2024-04-02
  • JAVA十大排序算法之基数排序详解
    目录基数排序代码实现时间复杂度算法稳定性基数排序 vs 桶排序 vs 计数排序总结基数排序 常见的数据元素一般是由若干位组成的,比如字符串由若干字符组成,整数由若干位0~9数字组成。...
    99+
    2024-04-02
  • Java十大排序算法之计数排序刨析
    计数排序是非比较的排序算法,用辅助数组对数组中出现的数字计数,元素转下标,下标转元素 计数排序优缺点 优点:快 缺点:数据范围很大,比较稀疏,会导致辅助空间很大,造成空间的浪费 使用...
    99+
    2024-04-02
  • JAVA十大排序算法之插入排序详解
    目录插入排序代码实现动图演示代码实现时间复杂度算法稳定性总结插入排序 当我们在玩扑克牌的时候,总是在牌堆里面抽取最顶部的一张然后按顺序在手中排列。 插入排序是指在待排序的元素中,假设...
    99+
    2024-04-02
  • Java 十大排序算法之希尔排序刨析
    目录希尔排序原理希尔排序的API设计希尔排序的代码实现希尔排序是插入排序的一种,又称"缩小增量排序”,是插入排序算法的一种更高效的改进版本。 希尔排序原理 1.选定一个增长量h,按照...
    99+
    2024-04-02
  • Java 十大排序算法之选择排序刨析
    目录选择排序原理选择排序API设计选择排序代码实现选择排序的时间复杂度选择排序原理 ①假设第一个索引处的元素为最小值,和其他值进行比较,如果当前的索引处的元素大于其他某个索引处的值,...
    99+
    2024-04-02
  • Java 十大排序算法之归并排序刨析
    目录归并排序原理归并排序API设计归并排序代码实现归并排序的时间复杂度分析归并排序原理 1.尽可能的一组数据拆分成两个元素相等的子组,并对每一个子组继续拆分,直到拆分后的每个子组的元...
    99+
    2024-04-02
  • Java 十大排序算法之插入排序刨析
    目录插入排序原理插入排序API设计插入排序代码实现插入排序的时间复杂度分析插入排序原理 ①把所有元素分成已排序和未排序两组 ②找到未排序组的第一个元素,向已经排序的组中进行插入 ③倒...
    99+
    2024-04-02
  • Java 十大排序算法之冒泡排序刨析
    目录冒泡排序原理冒泡排序API设计冒泡排序的代码实现冒泡排序的时间复杂度分析冒泡排序原理 ①比较相邻的元素,如果前一个元素比后一个元素大,则交换这两个元素的位置 ②对每一对相邻的元素...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作