详细总结各种排序算法(Java实现)

发布时间 - 2026-01-11 03:12:32    点击率:

一、插入类排序

1.直接插入排序

思想:将第i个插入到前i-1个中的适当位置

时间复杂度:T(n) = O(n²)。

空间复杂度:S(n) = O(1)。

稳定性:稳定排序。

如果碰见一个和插入元素相等的,那么插入元素把想插入的元素放在相等元素的后面。

所以,相等元素的前后顺序没有改变,从原无序序列出去的顺序就是排好序后的顺序,所以插入排序是稳定

哨兵有两个作用:

① 进人查找(插入位置)循环之前,它保存了R[i]的副本,使不致于因记录后移而丢失R[i]的内容;

② 它的主要作用是:在查找循环中"监视"下标变量j是否越界。一旦越界(即j=0),因为R[0].可以和自己比较,循环判定条件不成立使得查找循环结束,从而避免了在该循环内的每一次均要检测j是否越界(即省略了循环判定条件"j>=1")

public void insertSort(int[] array){
  for(int i=1;i<array.length;i++)//第0位独自作为有序数列,从第1位开始向后遍历
  {
   if(array[i]<array[i-1])//0~i-1位为有序,若第i位小于i-1位,继续寻位并插入,否则认为0~i位也是有序的,忽略此次循环,相当于continue
   {
    int temp=array[i];//保存第i位的值
    int k = i - 1;
    for(int j=k;j>=0 && temp<array[j];j--)//从第i-1位向前遍历并移位,直至找到小于第i位值停止
    {
     array[j+1]=array[j];
     k--;
    }
    array[k+1]=temp;//插入第i位的值
   }
  }
}

2.折半插入排序

思想:将数据插入到已经排好序的序列中,通过不断与中间点比较大小来确定位置

时间复杂度:比较时的时间减为O(n㏒n),但是移动元素的时间耗费未变,所以总是得时间复杂度还是O(n²)。

空间复杂度:S(n) = O(1)。

稳定性:稳定排序。

3.希尔排序

思想:又称缩小增量排序法。把待排序序列分成若干较小的子序列,然后逐个使用直接插入排序法排序,最后再对一个较为有序的序列进行一次排序,主要是为了减少移动的次数,提高效率。原理应该就是从无序到渐渐有序,要比直接从无序到有序移动的次数会少一些。

时间复杂度:O(n的1.5次方)

空间复杂度:O(1)

稳定性:不稳定排序。{2,4,1,2},2和1一组4和2一组,进行希尔排序,第一个2和最后一个2会发生位置上的变化。

public static void main(String [] args)
{
 int[]a={49,38,65,97,76,13,27,49,78,34,12,64,1};
  System.out.println("排序之前:");
  for(int i=0;i<a.length;i++)
  {
   System.out.print(a[i]+" ");
  }
  //希尔排序
  int d=a.length;
   while(true)
   {
    d=d/2;
    for(int x=0;x<d;x++)
    {
     for(int i=x+d;i<a.length;i=i+d)
     {
      int temp=a[i];
      int j;
      for(j=i-d;j>=0&&a[j]>temp;j=j-d)
      {
       a[j+d]=a[j];
      }
      a[j+d]=temp;
     }
    }
    if(d==1)
    {
     break;
    }
   }
   System.out.println();
   System.out.println("排序之后:");
    for(int i=0;i<a.length;i++)
    {
     System.out.print(a[i]+" ");
    }
  }
}

二、交换类排序

1.冒泡排序

时间复杂度:T(n) = O(n²)。

空间复杂度:S(n) = O(1)。

稳定性:稳定排序。

public class BubbleSort
{
 public void sort(int[] a)
 {
  int temp = 0;
  for (int i = a.length - 1; i > 0; --i)
  {
   for (int j = 0; j < i; ++j)
   {
    if (a[j + 1] < a[j])
    {
     temp = a[j];
     a[j] = a[j + 1];
     a[j + 1] = temp;
    }
   }
  }
 }
}

2.快速排序

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

时间复杂度:平均T(n) = O(n㏒n),最坏O(n²)。

空间复杂度:S(n) = O(㏒n)。

稳定性:不稳定排序

首先把数组的第一个数拿出来做为一个key,在前后分别设置一个i,j做为标识,然后拿这个key对这个数组从后面往前遍历,及j--,直到找到第一个小于这个key的那个数,然后交换这两个值,交换完成后,我们拿着这个key要从i往后遍历了,及i++;一直循环到i=j结束,当这里结束后,我们会发现大于这个key的值都会跑到这个key的后面

三、选择类排序

1.简单选择排序

时间复杂度:T(n) = O(n²)。

空间复杂度:S(n) = O(1)。

稳定性:不稳定排序

思路:

1)从待排序的序列中,找到关键字最小的元素

2)如果最小的元素不在第一位,就和第一个元素互换位置

3)从余下的N-1个元素中,找到关键字最小的元素,重复 1)、2)步

public class SelectionSort {
 public void selectionSort(int[] list) {
  // 需要遍历获得最小值的次数
  // 要注意一点,当要排序 N 个数,已经经过 N-1 次遍历后,已经是有序数列
  for (int i = 0; i < list.length - 1; i++) {
   int temp = 0;
   int index = i; // 用来保存最小值得索引
   // 寻找第i个小的数值
   for (int j = i + 1; j < list.length; j++) {
    if (list[index] > list[j]) {
     index = j;
    }
   }
   // 将找到的第i个小的数值放在第i个位置上
   temp = list[index];
   list[index] = list[i];
   list[i] = temp;
   System.out.format("第 %d 趟:\t", i + 1);
   printAll(list);
  }
 }
 // 打印完整序列
 public void printAll(int[] list) {
  for (int value : list) {
   System.out.print(value + "\t");
  }
  System.out.println();
 }
 public static void main(String[] args) {
  // 初始化一个随机序列
  final int MAX_SIZE = 10;
  int[] array = new int[MAX_SIZE];
  Random random = new Random();
  for (int i = 0; i < MAX_SIZE; i++) {
   array[i] = random.nextInt(MAX_SIZE);
  }
  // 调用排序方法
  SelectionSort selection = new SelectionSort();
  System.out.print("排序前:\t");
  selection.printAll(array);
  selection.selectionSort(array);
  System.out.print("排序后:\t");
  selection.printAll(array);
 }
}

2.树形选择排序

思想:为了减少比较次数,两两进行比较,得出的较小的值再两两比较,直至得出最小的输出,然后在原来位置上置为∞,再进行比较。直至所有都输出。

时间复杂度:T(n) = O(n㏒n)。

空间复杂度:较简单选择排序,增加了n-1个额外的存储空间存放中间比较结果,就是树形结构的所有根节点。S(n) = O(n)。

稳定性:稳定排序。

3.堆排序

【待】

四.、归并排序

归并排序:

思想:假设初始序列有n个记录,首先将这n个记录看成n个有序的子序列,每个子序列的长度为1,然后两两归并,得到n/2向上取整个长度为2(n为奇数时,最后一个序列的长度为1)的有序子序列

在此基础上,在对长度为2的有序子序列进行两两归并,得到若干个长度为4的有序子序列  

如此重复,直至得到一个长度为n的有序序列为止。

时间复杂度:T(n) = O(n㏒n)

空间复杂度:S(n) = O(n)

稳定性:稳定排序

public class MergeSort {
 
 public static void merge(int[] a, int low, int mid, int high) {
  int[] temp = new int[high - low + 1];
  int i = low;// 左指针
  int j = mid + 1;// 右指针
  int k = 0;
  // 把较小的数先移到新数组中
  while (i <= mid && j <= high) {
   if (a[i] < a[j]) {
    temp[k++] = a[i++];
   } else {
    temp[k++] = a[j++];
   }
  }
  // 把左边剩余的数移入数组
  while (i <= mid) {
   temp[k++] = a[i++];
  }
  // 把右边边剩余的数移入数组
  while (j <= high) {
   temp[k++] = a[j++];
  }
  // 把新数组中的数覆盖nums数组
  for (int k2 = 0; k2 < temp.length; k2++) {
   a[k2 + low] = temp[k2];
  }
 }
 
 public static void mergeSort(int[] a, int low, int high) {
  int mid = (low + high) / 2;
  if (low < high) {
   // 左边
   mergeSort(a, low, mid);
   // 右边
   mergeSort(a, mid + 1, high);
   // 左右归并
   merge(a, low, mid, high);
   System.out.println(Arrays.toString(a));
  }
 
 }
 
 public static void main(String[] args) {
  int a[] = { 51, 46, 20, 18, 65, 97, 82, 30, 77, 50 };
  mergeSort(a, 0, a.length - 1);
  System.out.println("排序结果:" + Arrays.toString(a));
 }
}

五、分配类排序

1.多关键字排序:

【待】

2.链式基数排序:

思想:先分配,再收集,就是先按照一个次关键字收集一下,然后进行收集(第一个排序),然后再换一个关键字把新序列分配一下,然后再收集起来,又完成一次排序,这样所有关键字分配收集完后,就完成了排序。

时间复杂度:T(n) = O( d ( n + rd ) )

空间复杂度:S(n) = O(rd)

稳定性:稳定排序

以上这篇详细总结各种排序算法(Java实现)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。


# java实现排序算法  # 三种简单排序算法(使用java实现)  # Java实现几种常见排序算法代码  # java几种排序算法的实现及简单分析  # 十种JAVA排序算法实例  # Java排序算法总结之堆排序  # JAVA简单选择排序算法原理及实现  # 遍历  # 希尔  # 第一个  # 长度为  # 然后再  # 较小  # 不稳定  # 放在  # 给大家  # 链式  # 递归  # 两部分  # 组中  # 把新  # 都要  # 是从  # 拿着  # 这两个  # 跑到  # 要注意 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 如何在IIS中新建站点并解决端口绑定冲突?  免费制作统计图的网站有哪些,如何看待现如今年轻人买房难的情况?  如何快速搭建二级域名独立网站?  Laravel如何使用Vite进行前端资源打包?(配置示例)  Laravel观察者模式如何使用_Laravel Model Observer配置  高防服务器租用如何选择配置与防御等级?  javascript事件捕获机制【深入分析IE和DOM中的事件模型】  js实现点击每个li节点,都弹出其文本值及修改  javascript中的数组方法有哪些_如何利用数组方法简化数据处理  javascript中闭包概念与用法深入理解  Laravel中DTO是什么概念_在Laravel项目中使用数据传输对象(DTO)  成都品牌网站制作公司,成都营业执照年报网上怎么办理?  网站制作企业,网站的banner和导航栏是指什么?  javascript中对象的定义、使用以及对象和原型链操作小结  Laravel如何实现API资源集合?(Resource Collection教程)  Win11怎么设置虚拟桌面 Win11新建多桌面切换操作【技巧】  免费网站制作appp,免费制作app哪个平台好?  详解Huffman编码算法之Java实现  Laravel Telescope怎么调试_使用Laravel Telescope进行应用监控与调试  jquery插件bootstrapValidator表单验证详解  Windows驱动无法加载错误解决方法_驱动签名验证失败处理步骤  广州网站制作公司哪家好一点,广州欧莱雅百库网络科技有限公司官网?  Laravel API资源类怎么用_Laravel API Resource数据转换  怎么制作网站设计模板图片,有电商商品详情页面的免费模板素材网站推荐吗?  php中::能调用final静态方法吗_final修饰静态方法调用规则【解答】  如何在阿里云虚拟服务器快速搭建网站?  如何在景安服务器上快速搭建个人网站?  Laravel怎么定时执行任务_Laravel任务调度器Schedule配置与Cron设置【教程】  Java Adapter 适配器模式(类适配器,对象适配器)优缺点对比  DeepSeek是免费使用的吗 DeepSeek收费模式与Pro版本功能详解  桂林网站制作公司有哪些,桂林马拉松怎么报名?  Laravel如何实现全文搜索功能?(Scout和Algolia示例)  Laravel模型关联查询教程_Laravel Eloquent一对多关联写法  微博html5版本怎么弄发语音微博_语音录制入口及时长限制操作【教程】  nodejs redis 发布订阅机制封装实现方法及实例代码  深圳网站制作公司好吗,在深圳找工作哪个网站最好啊?  Laravel如何设置自定义的日志文件名_Laravel根据日期或用户ID生成动态日志【技巧】  制作企业网站建设方案,怎样建设一个公司网站?  想要更高端的建设网站,这些原则一定要坚持!  JS实现鼠标移上去显示图片或微信二维码  详解Nginx + Tomcat 反向代理 如何在高效的在一台服务器部署多个站点  太平洋网站制作公司,网络用语太平洋是什么意思?  高端智能建站公司优选:品牌定制与SEO优化一站式服务  html5的keygen标签为什么废弃_替代方案说明【解答】  深圳网站制作培训,深圳哪些招聘网站比较好?  黑客入侵网站服务器的常见手法有哪些?  济南网站建设制作公司,室内设计网站一般都有哪些功能?  高防服务器租用首荐平台,企业级优惠套餐快速部署  如何在IIS服务器上快速部署高效网站?  佐糖AI抠图怎样调整抠图精度_佐糖AI精度调整与放大细化操作【攻略】