排序算法总结JAVA详细版(复杂度和稳定性)

本文总结了各种排序算法,包括冒泡排序、选择排序、插入排序、快速排序、归并排序和堆排序等,分析了它们的时间复杂度、稳定性以及适用场景。其中,稳定排序算法有冒泡排序、归并排序等,不稳定排序算法有快速排序、堆排序等。快速排序、堆排序和归并排序的时间复杂度为O(nlog2n),而冒泡排序和选择排序的时间复杂度为O(n2)。
摘要由CSDN通过智能技术生成

排序算法

性质记忆

1、关于稳定性

不稳定: 快选堆希(快速排序、选择排序、堆排序、希尔排序)

稳 定: 插冒归计基(简单插入排序、冒泡排序、归并排序、计数排序、基数排序)

2、关于时间复杂度

平方阶 (O(n2)) 排序

​ 各类简单排序:直接插入、直接选择和冒泡排序。

线性对数阶 (O(nlog2n)) 排序

​ 快速排序、堆排序和归并排序;

O(n1+§)) 排序,§ 是介于 0 和 1 之间的常数

​ 希尔排序

线性阶 (O(n)) 排序

​ 基数排序,此外还有桶、箱排序。

3、关于移动次数和关键字顺序无关的排序

​ 堆排序、归并排序、选择排序、基数排序

In-place:占用常数内存,不占用额外内存

Out-place:占用额外内存

冒泡排序

每次遍历,都将最大的元素移到最后。

相邻两个元素之间的比较。

在这里插入图片描述

  1. 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
  2. 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。
  3. 针对所有的元素重复以上的步骤,除了最后一个。
  4. 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
public void bulbSort(int[] arr) {
   
  // 当前个与后一个相比,所以外循环只需n-1次
  for (int i = 0; i < arr.length-1; i++) {
   
    // 内循环比较大小,因为当第i次循环完后,最后的i+1个已排完序,下一次可以不用参与
    // 如:3 1 4 2
    // 第i=0次循环完(4-1-0=3次):1 3 2 4,最后一个排完序,下一次可以不用参与
    // 第i=1次循环完(4-1-1=2次):1 2 3 4,最后两个排完序,下一次可以不用参与
    for (int j = 0; j < arr.length - i - 1; j++) {
   
      // 相邻元素两两对比,如果第一个比第二个大,就交换他们两个
      if (arr[j]>arr[j+1]) {
   
        int temp = arr[j];
        arr[j] = arr[j+1];
        arr[j+1] = temp;
      }
    }
  }
}

选择排序

在未排序序列中找到最小(大)元素,存放到排序序列的起始位置。

在这里插入图片描述

  1. 首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置。
  2. 再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。
  3. 重复第二步,直到所有元素均排序完毕。
public void selectionSort(int[] arr) {
   
  // 当前个与后一个相比,所以外循环只需n-1次
  for (int i = 0; i < arr.length - 1; i++) {
   
    // 每次循环,i前面的都是已经排完序了的
    // 初始将当前i位置的数认为是最小的
    int minIndex = i;
    // 从i后面的所有数中,寻找值最小的数
    for (int j = i+1; j < arr.length; j++) {
   
      // 判断是否比当前已知的最小的数还要小
      if (arr[j]<arr[minIndex]) {
   
        // 将最小数的索引保存
        minIndex = j;
      }
    }
    // 如果两者不相等,说明存在比它更小的数,需要交换
    if (i!=minIndex){
   
      // 将i位置的数与最小值的数交换
      int temp = arr[i];
      arr[i] = arr[minIndex];
      arr[minIndex] = temp;
    }
  }
}

插入排序

依次将元素插入对应位置,不符合的元素后移。

从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。

当前元素与它前面所有元素的对比。

在这里插入图片描述

  1. 从第一个元素开始,该元素可以认为已经被排序;
  2. 取出下一个元素,在已经排序的元素序列中从后向前扫描;
  3. 如果该元素(已排序)大于新元素,将该元素移到下一位置;
  4. 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置;
  5. 将新元素插入到该位置后;
  6. 重复步骤2~5。

                
  • 5
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
1.实验目的 掌握内排序,比较各种排序的优、缺点。 2 需求分析 2.1原理 2.1.1、直接排序 算法描述:经过i-1遍处理后,L[1..i-1]己排好序。第i遍处理仅将L[i]插入L[1..i-1]的适当位置,使得L[1..i]又是排好序的序列。要达到这个目的,我们可以用顺序比较的方法。首先比较L[i]和L[i-1],如果L[i-1]≤ L[i],则L[1..i]已排好序,第i遍处理就结束了;否则交换L[i]与L[i-1]的位置,继续比较L[i-1]和L[i-2],直到找到某一个位置j(1≤j≤i-1),使得L[j] ≤L[j+1]时为止。 2.1.2、冒泡排序 算法描述:核心思想是扫描数据清单,寻找出现乱序的两个相邻的项目。当找到这两个项目后,交换项目的位置然后继续扫描。重复上面的操作直到所有的项目都按顺序排好。 2.1.3、快速排序 算法描述:首先检查数据列表中的数据数,如果小于两个,则直接退出程序。如果有超过两个以上的数据,就选择一个分割点将数据分成两个部分,小于分割点的数据放在一组,其余的放在另一组,然后分别对两组数据排序。通常分割点的数据是随机选取的。这样无论你的数据是否已被排列过,你所分割成的两个字列表的大小是差不多的。而只要两个子列表的大小差不多。 2.1.4、选择排序 算法描述:首先找到数据清单中的最小的数据,然后将这个数据同第一个数据交换位置;接下来找第二小的数据,再将其同第二个数据交换位置,以此类推。 2.1.5、堆排序 (1) 基本思想:堆排序是一树形选择排序,在排序过程中,将R[1..N]看成是一颗完全二叉树的顺序存储结构,利用完全二叉树中双亲结点和孩子结点之间的内在关系来选择最小的元素。 (2) 堆的定义: N个元素的序列K1,K2,K3,...,Kn.称为堆,当且仅当该序列满足特性: Ki≤K2i Ki ≤K2i+1(1≤ I≤ [N/2]) 2.1.6、希尔排序 算法描述:在直接插入排序算法中,每次插入一个数,使有序序列只增加1个节点,并且对插入下一个数没有提供任何帮助。如果比较相隔较远距离(称为增量)的数,使得数移动时能跨过多个元素,则进行一次比较就可能消除多个元素交换。 2.2要求 1.本程序对以下六种常用内部排序算法进行实测比较:冒泡排序,插入排序,选择排序,希尔排序,快速排序,堆排序。 2.排序的元素关键字为整数。用正序,逆序,不同乱序的数据作测试比较。比较的指标为有关键字参加的比较次数关键字移动次数。 3.程序以人机对话的形式进行,每次测试完毕显示各种比较指标值 。 2.3任务 设计一个测试程序比较几种内部排序算法关键字比较次数移动次数以取得直观感受。 2.4运行环境 (1)WINDOWSXP系统 (2)C++ 编译环境 3.实验方法 本实验主要是内排序,通过比较的次数移动次数判断排序的好坏。主要子函数的说明如下。 1.简单选择排序XuanzePaixu(); 2.冒泡排序MaopaoPaixu(); 3. 直接插入排序CharuPaixu(); 4. 快速排序KuaisuPaixu(); 5. 堆排序DuiPaixu(); 6. 希尔排序 XierPaixu(); 以上的排序算法均采用书中所用的算法。程序采用输入的时候仅输入所要的个数,具体的输入数据由程序随机产生个数,并且输出。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

努力不熬夜的小喵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值