【初级算法】排序算法-01

210 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第3天,点击查看活动详情

前言

排序的算法有 7 种:

  • 基本排序算法:冒泡排序、插入排序
  • 常考的排序算法:归并排序、快速排序、拓扑排序
  • 其他排序:堆排序、桶排序

冒泡排序和插入排序经常被作为基础算法,考察能否快速写出无 bug 的代码。归并、快排,拓扑排序可以用来解决大部分涉及排序的问题。

题目

定数组 [2, 1, 7, 9, 5, 8],要求按照从左到右、从小到大的顺序进行排序。

冒泡排序

一组数组,对数组内的元素相互之间进行比较,按照大小顺序依次输出。像水里面的气泡一样,越往水面上浮,气泡就越大。

解题思路:

从左到右依次冒泡,把较大的数往右边移动

第一组:2>1, 所以两两交换 1,2,7,9,5,8

第二组:2<7, 保持不动,此时 7 时最大的那个数 1,2,7,9,5,8

第三组:2<9,保持不动,此时 9 时最大的那个数. 1,2,7,9,5,8

第四组:9>5 则交换位置 1,2,7,5,9,8

第五组:9>8 则交换位置 1,2,7,5,8,9

接下来就进行第二轮比较,重新从第一位开始遍历,重复上面的操作,最后结果:1,2,5,7,8,9

接下来进行第三轮比较,没有发生两两交换的情况,说明数组已经排序好了

AC 代码

function sort(nums) {
    let hasChange = true; 
    for (let i = 0; i < nums.length - 1 && hasChange; i++) {
        hasChange = false;
        for (let j = 0; j < nums.length - 1 - i; j++) {
            if (nums[j] > nums[j + 1]) {
                swap(nums, j, j + 1);
                hasChange = true;
            }
        }
     }
 }

插入排序

不断将尚未排序好的数拆入到已经排好序的部分。将数组划分成两部分,一般将左边第一个元素为已经排好序的组,右边剩余元素作为未排好序的,然后依次把右边的元素进行处理放在左边。

解题思路

1、右边第一个元素比左边元素 2 小,所以放在2的前面,即两两交换位置 1,2,7,9,5,8

2、7>2 所有要将 7 插入 2 的后面,即保持位置不变 1,2,7,9,5,8

3、同理 9>7,9 也不做位置变动 1,2,7,9,5,8

4、5 < 9 ,所以 两两交换, 1,2,7,5,9,8 ,5 也比7 小,继续交换。1,2,5,7,9,8 , 最后由于 5>2 ,所以本轮结束

5、最后8 比 9 小,进行交换,再比较 7<8 则此轮结束

AC 代码

function sort(nums) {
    for (let i = 1, j, current; i < nums.length; i++) {
        current = nums[i];
        for (j = i - 1; j >= 0 && nums[j] > current; j--) {
            nums[j + 1] = nums[j];
            }
        nums[j + 1] = current;
    }
}

总结

插入排序,先将数组拆成2部分,左边作为已排好序,右边未排好序的。每一轮下去,都是将左边作为已排好序的,然后右边元素,依次和左边元素比较,直到遇到左边元素小于当前元素,然后进行下一元素的比较。