冒泡排序
首先来个概念
冒泡排序的英文Bubble Sort,是一种最基础的交换排序。之所以叫做冒泡排序,因为每一个元素都可以像小气泡一样,根据自身大小一点一点向数组的一侧移动。
冒泡排序的原理: 每一趟只能确定将一个数归位。即第一趟只能确定将末位上的数归位,第二趟只能将倒数第 2 位上的数归位,依次类推下去。如果有 n 个数进行排序,只需将 n-1 个数归位,也就是要进行 n-1 趟操作。 而 “每一趟 ” 都需要从第一位开始进行相邻的两个数的比较,将较大的数放后面,比较完毕之后向后挪一位继续比较下面两个相邻的两个数大小关系,重复此步骤,直到最后一个还没归位的数。
!!! 目前在力扣这个排序数组这道题目中提交可以执行成功,但是提交不了,超出时间限制,之前我3月份都可以提交成功,同样的代码,这里近做学习!
1.1 简单版本
/**
* @param {number[]} nums
* @return {number[]}
*/
var sortArray = function (nums) {
/*
冒泡排序只会操作相邻的两个数据。
每次冒泡操作都会对相邻的两个元素进行比较,看是否满足大小关系要求。如果不满足就让它俩互换。
一次冒泡会让至少一个元素移动到它应该在的位置,重复 n 次,就完成了 n 个数据的排序工作。 */
for (let i = 0; i < nums.length - 1; i++) {
for (let j = 0; j < nums.length - 1-i; j++) {
if (nums[j] > nums[j + 1]) {
[nums[j], nums[j + 1]] = [nums[j + 1], nums[j]]
}
}
}
};
1.2 优化版本
比如[1,3.2,4]类似这种的数组,只需要外层循环走一遍就行了,以后都不需要再走了,上面的代码,暴力不管那么多,我就是有多少走多少.所以出现了下面这优化版本,判断一下,排序正确的都不走了!
var sortArray = function (arr) {
for (let i = 0; i < arr.length - 1 ; i++) {
let flag = true;
for (let j = 0; j < arr.length - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
[arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];
flag = false;
}
}
if (flag) {
break;
}
}
return arr;
};
选择排序
1 首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置。
2 再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。
3 重复第二步,直到所有元素均排序完毕。
/* // 方法二
*/
let minIndex = 0;
for (let i = 0; i < nums.length ; i++) {
console.log(minIndex, i)
minIndex = i;
// 第一次层for循环是nums.length- 1,其实-1也可以去掉
// 而这这二层for循环得条件 最少是nums.lengt 不能-1 也可以+1 +2
for (let j = i + 1; j < nums.length; j++) {
if (nums[j] < nums[minIndex]) {
minIndex = j;
}
};
console.log(minIndex);
[nums[i], nums[minIndex]] = [nums[minIndex], nums[i]];
}
return nums;
归并排序
步骤如下,简单的说就是把大数组(无序)化成小数组,在小数组拼接成大数组(有序)
1、将给定的列表分为两半(如果列表中的元素数为奇数,则使其大致相等)。
2、以相同的方式继续划分子数组,直到只剩下单个元素数组。
3、从单个元素数组开始,合并子数组,以便对每个合并的子数组进行排序。
4、重复第 3 步单元,直到最后得到一个排好序的数组。
具体代码如下,有两个点需要注意一下
1 到merge里面的两个数组都是有序的,是因为从小数组变大的时候都判断排序了
2 这里就是合并代码的时候merge最后返回数组,用es6写法老是报超时,但是用concat就不会超时
var sortArray = function (nums) {
if (nums.length < 2) {
return nums;
}
const midI = Math.floor(nums.length / 2);
const leftArr = nums.splice(0, midI);
return merge(sortArray(leftArr), sortArray(nums))
};
function merge(ls, rs) {
let result = [];
while (ls.length && rs.length) {
// 这里需要注意的就是 进到这里面的数组都是有序的
// 这里就是 哪个小先王数组里面推哪个 记得数字推进新数组老数组的数要去掉
ls[0] > rs[0] ? result.push(rs.shift()) : result.push(ls.shift())
}
// 一种方法
// if(ls.length == 0){
// result = result.concat(rs);//拼接
// }
// if(rs.length == 0){
// result = result.concat(ls);
// }
// return result;
// 两种方法
return result.concat(ls, rs)
// 这个不行老是保超时
// return [...result, ...ls, ...rs]
}