内排序_算法

内排序算法包括交换排序、插入排序、选择排序和归并排序等。交换排序中的冒泡排序和快速排序,插入排序中的直接插入排序和希尔排序,选择排序中的简单选择排序和堆排序,都是基于比较的排序算法。非比较排序则有计数排序、桶排序和基数排序,这些排序方法不依赖元素间的比较。稳定性在排序算法中也是一项重要指标,稳定排序能保持相同元素的相对顺序不变。
摘要由CSDN通过智能技术生成

内排序_算法

概述

根据排序元素所在位置的不同,排序分: 内排序和外排序。

内排序:在排序过程中,所有元素调到内存中进行的排序,称为内排序。内排序是排序的基础。内排序效率用比较次数来衡量。按所用策略不同,内排序又可分为插入排序、选择排序、交换排序、归并排序及基数排序等几大类。
外排序:在数据量大的情况下,只能分块排序,但块与块间不能保证有序。外排序用读/写外存的次数来衡量其效率。

分类

图1在这里插入图片描述

比较:需要比较两个元素的大小(前后)才能进行的排序。

插入:遍历到的元素放入之前维护的已完成排序的序列中。

交换:每次只调换两个元素之间的位置。

选择:选择剩余元素中最大或最小的元素。

稳定性

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

意义:排序的内容是一个复杂对象的多个数字属性,且其原本的初始顺序存在意义,那么需要在二次排序的基础上保持原有排序的意义,才需要使用到稳定性的算法。例如要排序的内容是一组原本按照价格高低排序的对象,如今需要按照销量高低排序,使用稳定性算法,可以使得想同销量的对象依旧保持着价格高低的排序展现,只有销量不同的才会重新排序。

比较类排序

交换排序

冒泡排序

​ 冒泡排序对基本思想:通过无序区中相邻元素间关键字的比较和位置的交换,使关键字最小的元素如气泡一样逐渐上浮。

算法描述

  1. 比较相邻的元素。如果第一个比第二个大,就交换它们两个;
  2. 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对,这样在最后的元素应该会是最大的数;
  3. 针对所有的元素重复以上的步骤,除了最后一个;
  4. 重复步骤1~3,直到排序完成。
初始关键字 9 8 7 6 5 4 3 2 1 0
i=0 0 9 8 7 6 5 4 3 2 1
i=1 0 1 9 8 7 6 5 4 3 2
i=2 0 1 2 9 8 7 6 5 4 3
i=3 0 1 2 3 9 8 7 6 5 4
i=4 0 1 2 3 4 9 8 7 6 5
i=5 0 1 2 3 4 5 9 8 7 6
i=6 0 1 2 3 4 5 6 9 8 7
i=7 0 1 2 3 4 5 6 7 9 8
i=8 0 1 2 3 4 5 6 7 8 9
public static void buttleSort(int[] nums) {
   
  for (int i = 0; i < nums.length - 1; i++) {
   
    for (int j = 0; j < nums.length - 1; j++) {
   
      if (nums[j] > nums[j + 1]) {
   //两元素比较交换,升序
        int tmp = nums[j + 1];
        nums[j + 1] = nums[j];
        nums[j] = tmp;
      }
    }
  }
}
快速排序

​ 快排是由冒泡排序改进而来,基本思想:在待排序的n个元素中任取一个座位基准,把该元素放入合适位置,数据序列被分为两部分,所有比该元素小的在前一部分,所有比该元素大的在后一部分。这个过程为一趟快速排序,然后在前后两部分内分别重复上述步骤。直至子表的长度为1或者0。

算法描述:

  1. 从数列中挑出一个元素,称为 “基准”(pivot);
  2. 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作;
  3. 递归地把小于基准值元素的子数列和大于基准值元素的子数列排序。

在这里插入图片描述

private static void quickSort(int[] nums, int left, int right) {
   
  if (left < right) {
   
    int partitionIndex = partition(nums, left, right);
    quickSort(nums, left, partitionIndex - 1);
    quickSort(nums, partitionIndex + 1, right);
  }
}
private static int partition(int[] nums, int left, int right) {
   
  int pivot = left;//基准值
  int index = pivot + 1;
  for (int i = index; i <= right; i++) {
   
    if (nums[i] > nums[pivot]) {
   //降序
      int tmp = nums[i];
      nums[i] = nums[index];
      nums[index] = tmp;
      index++;
    }
  }
  int tmp = nums[pivot];
  nums[pivot] = nums[index - 1];
  nums[index - 1] = tmp;
  return index - 1;
}

插入排序

插入排序

​ 插入排序的思路:待排序列分为有序区和无序区,然后将无序区中的元素插入到有序区中合适的位置。

算法描述:

  1. 从第一个元素开始,该元素可以认为已经被排序;
  2. 取出下一个元素,在已经排序的元素序列中从后向前扫描;
  3. 如果该元素(已排序)大于新元素,将该元素移到下一位置;
  4. 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置;
  5. 将新元素插入到该位置后;
  6. 重复步骤2~5。
初始关键字 [9] 8 7 6 5 4 3 2 1 0
i=1 [8 9] 7 6 5 4 3 2 1 0
i=2 [7 8 9] 6 5 4 3
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值