iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >Java排序算法怎么快速上手
  • 264
分享到

Java排序算法怎么快速上手

2023-06-27 11:06:04 264人浏览 安东尼
摘要

本篇内容主要讲解“Java排序算法怎么快速上手”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java排序算法怎么快速上手”吧!插入排序插入排序的基本思想:每步将一个待排序元素,按其排序码大小插入

本篇内容主要讲解“Java排序算法怎么快速上手”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java排序算法怎么快速上手”吧!

Java排序算法怎么快速上手

插入排序

插入排序的基本思想:每步将一个待排序元素,按其排序码大小插入到前面已经排好序的一组元素中,直到元素全部插入为止。在这里,我们介绍三种具体的插入排序算法:直接插入排序,希尔排序与折半插入排序。

1、直接插入排序

**直接插入排序的思想:**当插入第i(i>=1)个元素时,前面的V[0],…,V[i-1]等i-1个 元素已经有序。这时,将第i个元素与前i-1个元素V[i-1],…,V[0]依次比较,找到插入位置即将V[i]插入,同时原来位置上的元素向后顺移。在这里,插入位置的查找是顺序查找。直接插入排序是一种稳定的排序算法,其实现如下:

      public class StraightInsertionSort {   public static int[] insertSort(int[] target){       if(target != null && target.length != 1){   // 待排序数组不为空且长度大于1           for (int i = 1; i for (int j = i; j > 0; j--) {    // 向有序序列中插入新的元素                   if(target[j]  return target;   }}

2、希尔排序

**希尔排序的思想:**设待排序序列共n个元素,首先取一个整数gap

      public class shellSort {   public static int[] shellSort(int[] target){       if(target != null && target.length != 1){           int gap = target.length;       // gap个大小为gap的子序列           do{               gap = gap/3 + 1;     // 不断缩小gap直至为1               for (int i = 0 + gap; i if(target[i] do{                           target[j + gap] = target[j];         // 后移元素                           j = j - gap;          // 再比较前一个元素                       }while(j >= 0 && target[j] > temp);  // 向前比较的终止条件                       target[j + gap] = temp;         // 将待插入值插入合适的位置                   }               }           }while(gap > 1);       }       return target;   }}

3、折半插入排序

**折半插入排序的思想:**当插入第i(i>=1)个元素时,前面的V[0],…,V[i-1]等i-1个 元素已经有序。这时,折半搜索第i个元素在前i-1个元素V[i-1],…,V[0]中的插入位置,然后直接将V[i]插入,同时原来位置上的元素向后顺移。与直接插入排序不同的是,折半插入排序比直接插入排序明显减少了关键字之间的比较次数,但是移动次数是没有改变。所以,折半插入排序和插入排序的时间复杂度相同都是O(N^2),但其减少了比较次数,所以该算法仍然比直接插入排序好。折半插入排序是一种稳定的排序算法,其实现如下:

      public class BinaryInsertSort {   public static int[] binaryInsertSort(int[] target) {       if (target != null && target.length > 1) {           for (int i = 1; i if(temp while(left if(target[mid] else if(target[mid] > temp){                           right = mid - 1;    // 缩小插入区间                       }else{        // 待插入值与有序序列中的target[mid]相等,保证稳定性的处理                           left = left + 1;                         }                   }                   // left及其后面的数据顺序向后移动,并在left位置插入                   for (int j = i; j > left; j--) {                       target[j] = target[j-1];                   }                   target[left] = temp;               }           }       }       return target;   }}

选择排序

**选择排序的基本思想:**每一趟 (例如第i趟,i = 0,1,…)在后面第n-i个待排序元素中选出最小元素作为有序序列的第i个元素,直到第n-1趟结束后,所有元素有序。在这里,我们介绍两种具体的选择排序算法:直接选择排序与堆排序。

1、直接选择排序

**直接选择排序的思想:**第一次从R[0]~R[n-1]中选取最小值,与R[0]交换,第二次从R1~R[n-1]中选取最小值,与R1交换,….,第i次从R[i-1]~R[n-1]中选取最小值,与R[i-1]交换,…..,第n-1次从R[n-2]~R[n-1]中选取最小值,与R[n-2]交换,总共通过n-1次,得到一个按排序码从小到大排列的有序序列。直接选择排序是一种不稳定的排序算法,其实现如下:

      public class StraightSelectSort {   public static int[] selectSort(int[] target){       if(target != null && target.length != 1){           for (int i = 0; i for (int j = i + 1; j if(target[min_index] > target[j]){                       min_index = j;                   }               }               if(target[min_index] != target[i]){  // 导致不稳定的因素:交换                   int min = target[min_index];                   target[min_index] = target[i];                   target[i] = min;               }           }       }       return target;   }}

2、堆排序

**堆排序的核心是堆调整算法。**首先根据初始输入数据,利用堆调整算法shiftDown()形成初始堆;然后,将堆顶元素与堆尾元素交换,缩小堆的范围并重新调整为堆,如此往复。堆排序是一种不稳定的排序算法,其实现如下:

      public class HeapSort {   public static int[] heapSort(int[] target) {       if (target != null && target.length > 1) {           // 调整为最大堆           int pos = (target.length - 2) / 2;           while (pos >= 0) {               shiftDown(target, pos, target.length - 1);               pos--;           }           // 堆排序           for (int i = target.length-1; i > 0; i--) {               int temp = target[i];               target[i] = target[0];               target[0] = temp;               shiftDown(target, 0, i-1);           }           return target;       }       return target;   }      private static void shiftDown(int[] target, int start, int end) {       int i = start;       int j = 2 * start + 1;       int temp = target[i];       while (j if (j  target[j]) {  //找出较大子女               j = j + 1;           }           if (target[j] break;           } else {               target[i] = target[j];               i = j;               j = 2 * j + 1;           }       }       target[i] = temp;   }}

交换排序

**交换排序的基本思想:**根据序列中两个元素的比较结果来对换这两个记录在序列中的位置,也就是说,将键值较大的记录向序列的尾部移动,键值较小的记录向序列的前部移动。

1、冒泡排序

**冒泡排序的思想:**根据序列中两个元素的比较结果来对换这两个记录在序列中的位置,将键值较大的记录向序列的尾部移动,键值较小的记录向序列的前部移动。因此,每一趟都将较小的元素移到前面,较大的元素自然就逐渐沉到最后面了,也就是说,最大的元素最后才能确定,这就是冒泡。冒泡排序是一种稳定的排序算法,其实现如下:

public class BubbleSort {      public static int[] bubbleSort(int[] target) {       int n = target.length;       if (target != null && n != 1) {           // 最多需要进行n-1躺,每一趟将比较小的元素移到前面,比较大的元素自然就逐渐沉到最后面了,这就是冒泡           for (int i = 0; i for (int j = n-1; j > i; j--) {                   if(target[j] return target;   }      public static int[] optimizeBubbleSort(int[] target) {       int n = target.length;       if (target != null && n != 1) {           // 最多需要进行n-1躺,每一趟将比较小的元素移到前面,比较大的元素自然就逐渐沉到最后面了,这就是冒泡           for (int i = 0; i false;               for (int j = n-1; j > i; j--) {                   if(target[j] true;                   }               }               System.out.println(Arrays.toString(target));               if (!exchange){    // 若 i 到 n-1 这部分元素已经有序,则直接返回                   return target;               }           }       }       return target;   }}

2、快速排序

**快速排序的思想:**通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小(划分过程),然后再按此方法对这两部分数据分别进行快速排序(快速排序过程),整个排序过程可以递归进行,以此达到整个数据变成有序序列。快速排序是一种不稳定的排序算法。

public class QuickSort {      public static int[] quickSort(int[] target, int left, int right) {       if(right > left){     // 递归终止条件           int base_index = partition(target,left, right);  // 原序列划分后基准元素的位置           quickSort(target, left, base_index-1);    // 对第一个子序列快速排序,不包含基准元素!           quickSort(target, base_index+1, right);   // 对第二个子序列快速排序,不包含基准元素!           return target;       }       return target;   }      public static int partition(int[] target, int left, int right){       int base = target[left];   // 基准元素的值       int base_index = left;    // 基准元素最终应该在的位置       for (int i = left+1; i if(target[i] if(base_index != i){    // 相等情况意味着i之前的元素都小于base,只需要换一次即可,不需要次次都换                   int temp = target[base_index];                   target[base_index] = target[i];                   target[i] = temp;               }           }       }       // 将基准元素就位       target[left] = target[base_index];         target[base_index] = base;       System.out.println(Arrays.toString(target));       return base_index;  //返回划分后基准元素的位置   }}

归并排序

**归并排序包含两个过程:”归”和”并”。**其中,”归”是指将原序列分成半子序列,分别对子序列进行递归排序;”并”是指将排好序的各子序列合并成原序列。归并排序算法是一个典型的递归算法,因此也是概念上最为简单的排序算法。与快速排序算法相比,归并排序算法不依赖于初始序列,并且是一种稳定的排序算法,但需要与原序列一样大小的辅助存储空间。

public class MergeSort {      public static int[] mergeSort(int[] target, int left, int right) {       if(right > left){           // 递归终止条件           int mid = (left + right)/2;           mergeSort(target, left, mid);   // 归并排序第一个子序列           mergeSort(target, mid+1, right);   // 归并排序第二个子序列           return merge(target,left,mid,right);  // 合并子序列成原序列       }       return target;   }      public static int[] merge(int[] target, int left, int mid, int right){       // 需要一个与原待排序数组一样大的辅助数组空间       int[] temp = Arrays.copyOf(target, target.length);       // s1,s2是检查指针,index 是存放指针       int s1 = left;       int s2 = mid + 1;       int index = left;       // 两个表都未检查完,两两比较       while(s1 if(temp[s1] else{               target[index++] = temp[s2++];           }       }       //若第一个表未检查完,复制       while(s1 while(s2 return target;   }}

Ps : 归并排序和快速排序都是典型的递归算法,因此它们比较容易理解和实现。关于递归思想和内涵深度剖析,请见博文《算法设计方法:递归的内涵与经典应用》。

分配排序(基数排序)

分配排序的基本思想:用空间换时间。在整个排序过程中,无须比较关键字,而是通过用额外的空间来”分配”和”收集”来实现排序,它们的时间复杂度可达到线性阶:O(n)。其中,基数排序包括两个过程:首先,将目标序列各元素分配到各个桶中(分配过程);然后,将各个桶中的元素按先进先出的顺序再放回去(收集过程),如此往复,一共需要进行d趟,d为元素的位数。

  public class RadixSort {      public static int[] radixSort(int[] target, int r, int d, int n){       if (target != null && target.length != 1 ) {           int[][] bucket = new int[r][n];  // 一共有基数r个桶,每个桶最多放n个元素           int digit;  // 获取元素对应位上的数字,即装入那个桶           int divisor = 1;   // 定义每一轮的除数,1, 10, 100, ...           int[] count = new int[r];   // 统计每个桶中实际存放元素的个数           for (int i = 0; i for (int ele : target) {                     digit = (ele/divisor) % 10;  // 获取元素对应位上的数字(巧妙!!!)                   bucket[digit][count[digit]++] = ele; // 将元素放入对应桶,桶中元素数目加1               }               // 收集               int index = 0;  // 目标数组的下标               for (int j = 0; j while(k return target;   }}

总结

Java排序算法怎么快速上手

1、直接插入排序 Vs. 折半插入排序 Vs. 希尔排序

这三种排序方法都属于插入排序的范畴。与直接插入排序的顺序搜索插入位置相比,折半插入排序通过折半搜索的方法搜索插入位置,因此,在搜索插入位置方面,折半插入排序要快于直接插入排序。实际上,折半插入排序比直接插入排序只是减少了关键字之间的比较次数,但是移动次数是没有改变。所以,折半插入排序和插入排序的时间复杂度相同都是O(n^2),但减少了比较次数,所以该算法要比直接插入排序好一点。希尔排序可以看作是对直接插入排序的一种优化,它将全部元素分为间隔为gap的gap个子序列并对每一个子序列进行直接插入排序,同时不断缩小间隔gap,直至所有元素位于同一个序列。使用这种方式可以保证排序效率,因为刚开始时,gap较大,每个子序列元素较少,排序速度较快;待到排序后期,gap变小,每个子序列元素较多,但大部分元素基本有序,所以排序速度仍较快。因此,希尔排序比直接插入排序 、折半插入排序都要高效,但它不是稳定的。

2、直接选择排序 Vs. 堆排序

这两种排序方法都属于插入选择排序的范畴,它们的核心思想都是每一趟都选择一个极值元素放在靠前/靠后位置,直到序列有序。与直接选择排序不同的是,堆排序不是“蛮力选择”,而是不断进行堆调整以取得每趟中的极值。因此,堆排序比直接选择排序要高效,不过它们都是不稳定的。

3、冒泡排序 Vs. 快速排序

这两种排序方法都属于选择排序的范畴,它们的核心思想都是元素的交换,冒泡排序中每一趟相邻元素互相比较,并将较小的交换到前面(较大的自然沉到后面)位置,快速排序则是以基准点为基础,将比它小的元素和比它大的元素分别交换到它的两边。因此,快速排序比冒泡排序要高效,但它不是稳定的。

4、归并排序 Vs. 快速排序

这两种排序方法都属于递归算法的范畴,因此,它们都比较容易让人理解和实现。与快速排序相比,归并排序不但是稳定的,还是与原始序列无关的(不依赖于原始序列的顺序,时间复杂度总是O(nlgn)),但是需要与原始序列一样大小的空间;而快速排序则一般情况下都要比其他高效排序算法(包括归并排序)快,而且空间复杂度只为O(1)。另外,我们从算法实现中可以看出这两种递归算法有以下区别和联系:

  • 二者的递归终止条件相同;
  • 二者的实现结构较为类似,归并排序是先归后并,快速排序是先分后排;
  • 归并排序的核心实现在于有序子序列的合并,而快速排序的核心实现在于对原始序列的划分;

5、小结

直接插入排序、直接选择排序和冒泡排序是基本的排序方法,它们平均情况下的时间复杂度都是O(n^2),实现也比较简单,它们对规模较小的元素序列很有效。

快速排序、堆排序和归并排序是高效的排序方法,它们平均情况下的时间复杂度都是O(nlgn),其中快速排序是最通用的高效排序算法,但其是不稳定的;归并排序是上述几种排序算法中唯一与初始序列无关的,而且时间复杂度总是O(nlgn),但其空间复杂度是O(n),是一种稳定的排序算法;堆排序的时间复杂度总是O(nlgn),空间复杂度是O(1),也是不稳定的。它们对规模较大的元素序列很有效。

希尔排序的效率介于基本排序方法与高效排序方法之间,是一种不稳定的排序算法。它们各有所长,都拥有特定的使用场景。基数排序虽然具有线性增长的时间复杂度,但实际上开销并不比快速排序小很多,应用相对不太广泛。

因此,在实际应用中,我们必须根据实际任务的特点和各种排序算法的特性来做出最合适的选择。

到此,相信大家对“Java排序算法怎么快速上手”有了更深的了解,不妨来实际操作一番吧!这里是编程网网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

--结束END--

本文标题: Java排序算法怎么快速上手

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

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

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

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

下载Word文档
猜你喜欢
  • Java排序算法怎么快速上手
    本篇内容主要讲解“Java排序算法怎么快速上手”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java排序算法怎么快速上手”吧!插入排序插入排序的基本思想:每步将一个待排序元素,按其排序码大小插入...
    99+
    2023-06-27
  • java 排序算法之快速排序
    目录简单介绍基本思想思路分析代码实现推导实现完整实现大数据量耗时测试性能分析简单介绍 快速排序(Quicksort) 是对 冒泡排序的一种改进。 基本思想 快速排序算法通过多次比较和...
    99+
    2024-04-02
  • JAVA十大排序算法之快速排序详解
    目录快速排序问题思路荷兰国旗问题代码实现时间复杂度算法稳定性总结快速排序 快速排序是对冒泡排序的一种改进,也是采用分治法的一个典型的应用。JDK中Arrays的sort()方法,具体...
    99+
    2024-04-02
  • java如何实现快速排序算法
    这篇文章将为大家详细讲解有关java如何实现快速排序算法,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。快速排序算法使用的分治法策略来把一个序列分为两个子序列来实现排序的思路:1.从数列中挑出一个元素,称为...
    99+
    2023-06-02
  • 详解Java双轴快速排序算法
    目录一、前言二、回顾单轴快排三、双轴快排分析3.1、总体情况分析3.2、k交换过程3.3、收尾工作四、双轴快排代码一、前言 首选,双轴快排也是一种快排的优化方案,在JDK的Array...
    99+
    2024-04-02
  • go快速排序算法怎么实现
    快速排序(Quick Sort)是一种高效的排序算法,它的基本思想是选择一个基准元素,通过一趟排序将数组分成两部分,其中一部分的所有...
    99+
    2023-10-26
    go
  • PHP快速排序算法怎么应用
    在PHP中,可以使用快速排序算法来对数组进行排序。以下是一个使用递归实现的快速排序算法的示例:```phpfunction quic...
    99+
    2023-10-11
    PHP
  • Java排序算法之怎么实现快速排序的三数取中法
    这篇文章主要讲解了“Java排序算法之怎么实现快速排序的三数取中法”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java排序算法之怎么实现快速排序的三数取中法”吧!基本步骤三数取中在快排的过...
    99+
    2023-06-25
  • python快速排序算法怎么实现
    快速排序是一种常用的排序算法,其算法思想是通过递归地将数组分为较小和较大的两个子数组,然后不断重复这个过程,直到整个数组有序。下面是...
    99+
    2023-08-15
    python
  • 在Java中怎么实现一个快速排序算法
    在Java中怎么实现一个快速排序算法?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。快速排序的原理:选择一个关键值作为基准值。比基准值小的都在左边序列(一般是无序...
    99+
    2023-05-30
    java
  • java数据结构与算法(快速排序法)
    快速排序法: 顾名思议,快速排序法是实践中的一种快速的排序算法,在c++或对java基本类型的排序中特别有用。它的平均运行时间是0(N log N)。该算法之所以特别快,主要是由于非...
    99+
    2024-04-02
  • Python中怎么实现快速排序算法
    Python中怎么实现快速排序算法,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。Python实现快速排序算法快速排序算法是一种基于交换的高效的排序算法,由C.R.A.Hoare...
    99+
    2023-06-02
  • 【Java】快速排序
    文章目录 一、什么是快速排序二、基准元素的选择1、选择第一个元素2、随机选择 三、元素的交换1、双边循环法2、单边循环法 一、什么是快速排序 快速排序是由冒泡排序演变而来,比冒泡排序更快的排序算法。之所以快,是因为快速排...
    99+
    2023-08-17
    java 排序算法 算法 学习 开发语言
  • Java快速排序方法怎么使用
    本篇内容介绍了“Java快速排序方法怎么使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!快速排序思想介绍快速排序使用了分治的思想,通过一轮...
    99+
    2023-06-02
  • 手撕排序之快速排序
    快排的思想(霍尔版本): 如何实现单趟排序: 先假设key是数列的首元素,然后分别定义left和right,left指向首元素的下一个元素,right指向最后一个元素。 先遍历右边,如果比key小,就停止遍历,如果比key大就right-...
    99+
    2023-10-25
    算法 排序算法 数据结构
  • Java 快速排序
    快速排序是一种常用的基于比较的排序算法,其时间复杂度为 O(nlogn),并且具有稳定性和广泛的应用场景。本文将全面详细的讲解一下 Java 中快速排序算法的原理、实现以及时间复杂度等问题。 一、快速...
    99+
    2023-09-06
    java 排序算法 算法
  • 图解Java排序算法之快速排序的三数取中法
    目录基本步骤三数取中根据枢纽值进行分割代码实现总结基本步骤 三数取中 在快排的过程中,每一次我们要取一个元素作为枢纽值,以这个数字来将序列划分为两部分。在此我们采用三数取中法,也就是...
    99+
    2024-04-02
  • C#实现快速排序算法
    快速排序是应用最广泛的排序算法,流行的原因是它实现简单,适用于各种不同情况的输入数据且在一般情况下比其他排序都快得多。 快速排序是原地排序(只需要一个很小的辅助栈),将长度为 N 的...
    99+
    2024-04-02
  • 排序算法图解之Java快速排序的分步刨析
    目录1.快速排序简介2.思路简介及图解3.实现代码及运行结果1.快速排序简介 快速排序是对冒泡排序的一种改进。基本思想为:通过一趟排序将要排序的数据分割为独立的两个部分,其中一部分的...
    99+
    2022-11-13
    Java快速排序算法 Java快速排序 Java 排序
  • c语言快速排序算法怎么使用
    使用快速排序算法,需要先定义一个快速排序函数,然后在主函数中调用该函数。下面是一个示例的C语言快速排序算法的实现:```c#incl...
    99+
    2023-09-21
    c语言
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作