一起养成写作习惯!这是我参与「掘金日新计划 · 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部分,左边作为已排好序,右边未排好序的。每一轮下去,都是将左边作为已排好序的,然后右边元素,依次和左边元素比较,直到遇到左边元素小于当前元素,然后进行下一元素的比较。