排序算法(冒泡、插入、快排、选择)

目录

排序算法

冒泡排序

插入排序

快速排序

选择排序


排序算法

冒泡排序

从数组最左端开始向右遍历,依次对比相邻元素大小,若 左元素 > /<右元素 则将它俩交换,最终可将最大/小元素移动至数组最右端。

 
/* 冒泡排序 */
 void bubbleSort(int[] nums) {
     // 外循环:待排序元素数量为 n-1, n-2, ..., 1
     for (int i = nums.length - 1; i > 0; i--) {
         // 内循环:冒泡操作
         for (int j = 0; j < i; j++) {
             if (nums[j] > nums[j + 1]) {
                 // 交换 nums[j] 与 nums[j + 1]
                 int tmp = nums[j];
                 nums[j] = nums[j + 1];
                 nums[j + 1] = tmp;
             }
         }
     }
 }

插入排序

选定某个待排序元素为基准数 base,将 base 与其左侧已排序区间元素依次对比大小,并插入到正确位置。

回忆数组插入操作,我们需要将从目标索引到 base 之间的所有元素向右移动一位,然后再将 base 赋值给目标索引。

  1. 第 1 轮先选取数组的 第 2 个元素base ,执行「插入操作」后,数组前 2 个元素已完成排序

  2. 第 2 轮选取 第 3 个元素base ,执行「插入操作」后,数组前 3 个元素已完成排序

  3. 以此类推……最后一轮选取 数组尾元素base ,执行「插入操作」后,所有元素已完成排序

  4.  

 /* 插入排序 */
 void insertionSort(int[] nums) {
     // 外循环:base = nums[1], nums[2], ..., nums[n-1]
     for (int i = 1; i < nums.length; i++) {
         int base = nums[i], j = i - 1;
         // 内循环:将 base 插入到左边的正确位置
         while (j >= 0 && nums[j] > base) {
             nums[j + 1] = nums[j];  // 1. 将 nums[j] 向右移动一位
             j--;
         }
         nums[j + 1] = base;         // 2. 将 base 赋值到正确位置
     }
 }

快速排序

选取数组某个元素为 基准数,将所有小于基准数的元素移动至其左边,大于基准数的元素移动至其右边。

 /* 元素交换 */
 void swap(int[] nums, int i, int j) {
     int tmp = nums[i];
     nums[i] = nums[j];
     nums[j] = tmp;
 }
 ​
 /* 哨兵划分 */
 int partition(int[] nums, int left, int right) {
     // 以 nums[left] 作为基准数
     int i = left, j = right;
     while (i < j) {
         while (i < j && nums[j] >= nums[left])
             j--;          // 从右向左找首个小于基准数的元素
         while (i < j && nums[i] <= nums[left])
             i++;          // 从左向右找首个大于基准数的元素
         swap(nums, i, j); // 交换这两个元素
     }
     swap(nums, i, left);  // 将基准数交换至两子数组的分界线
     return i;             // 返回基准数的索引
 }

选择排序

第一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,然后再从剩余的未排序元素中寻找到最小(大)元素,继续放在起始位置知道未排序元素个数为0。

 public static void selectionSort(int[] arr) {
    /*判断数组为空或为一个元素的情况,即边界检查*/
    if (arr == null || arr.length < 2) {
       return;
    }
 ​
    /*每次要进行比较的两个数,的前面那个数的下标*/
    for (int i = 0; i < arr.length - 1; i++) { 
       //min变量保存该趟比较过程中,最小元素所对应的索引,
       //先假设前面的元素为最小元素
       int minIndex = i;
       /*每趟比较,将前面的元素与其后的元素逐个比较*/
       for (int j = i + 1; j < arr.length; j++) {
          //如果后面的元素小,将后面元素的索引极为最小值的索引
          if(arr[j] < arr[minIndex]) {
             minIndex = j;
          }
       }
       //然后交换此次查找到的最小值和原始的最小值
       swap(arr, i, minIndex);
    }
 }
 ​
 public static void swap(int[] arr, int i, int j) {
    int tmp = arr[i];
    arr[i] = arr[j];
    arr[j] = tmp;
 }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

取址执行

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

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

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

打赏作者

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

抵扣说明:

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

余额充值