在前几话话中深入研究了一下冒泡排序及其优化
JavaScript实现冒泡排序及双向冒泡排序
今天总结一下排序算法中也极为经典的选择排序和插入排序
一、回顾冒泡排序
为了更好的比较这几种算法,首先回顾一下之前冒泡排序的思想和简单实现
这个网站可以看到这几种排序的动图,可以手动演示一下,了解这几种排序的思想
冒泡排序算法动图展示
1、冒泡排序的思路
(1)方向:冒泡排序是向右排的
(2)第一轮会从第一个数开始跟相邻的右边的数比较,比右边大就交换一下,这样不断重复跟右边相邻的数字比较,就像冒泡一样,冒出了最大的数,放在最右边
这个过程可以看出是一个for循环了
(3)第二轮就会从第二个数开始跟相邻的右边的数比较,这样会冒出第二大的数字,放在右边倒数第二的位置
那么依次类推,就会排好了
2、理解了这个排序算法的思想,可以得出几个点
(1)首先这是一个双重循环
(2)由于每次会把第几大第几大的数排好,从最右边开始放,那么右边的几个数应该是排好的,在循环的过程中就不用再去排了
(3)这是一个跟相邻的右边元素不断交换的过程
3、编码实现
这里注意千万不要手贱用箭头函数,箭头函数是没有自己的this
Array.prototype.bubbleSort = function() {
// 相邻比较大小,双重for循环
for(let i = 0; i < this.length - 1; i += 1) {
// 注意是this.length - 1 - i
// 因为它是从左边开始排,最大的放在最右边,所以最右边的不用排了
// 每一轮都找到这一轮中最大的,第一轮中找到的是数组里最大的,放在最右边
// 第二轮找到的是第二大的放在右边倒数第二
for(let j = 0; j < this.length - 1 - i; j += 1) {
if(this[j] > this[j+1]) {
let temp = this[j];
this[j] = this[j+1];
this[j+1] = temp;
}
}
}
}
const arr = [1, 5, 9, 3, 18, 6, 2, 7]
arr.bubbleSort()
console.log(arr);
二、选择排序
1、算法思路
(1)选择排序也是向右排的
(2)选择排序是向右选择出最小的排到最左边,
那它是不是冒泡排序反过来实现呢?当然不是啦!!!
首先它不是相邻交换的过程
第一轮,它先预定住第一个数的位置
然后它要找出每一轮中值最小的下标,注意找出了但是没有交换的过程
等一轮都跑完了,确定这个下标对应的就是这一轮中最小的数了,再把这个数跟刚才预定的第一个数的位置的值做一个交换
这个就是选择排序,每一轮选择出最小的值
2、编码实现
从刚才描述的算法思路,知道还是需要双重的for循环,而且要有一个变量,去记录每一轮中最小值的下标
Array.prototype.selectionSort = function() {
// 向后排,把最小的挑到前面来
for(let i = 0; i < this.length - 1; i += 1) {
let minIndex = i;
// 先找到这一轮中最小的下标
for(let j = i; j < this.length; j += 1) {
if(this[minIndex] > this[j]) {
minIndex = j;
}
}
if(minIndex != i) {
let temp = this[minIndex];
this[minIndex] = this[i];
this[i] = temp;
}
}
}
const arr = [1, 5, 9, 3, 18, 6, 2, 7]
arr.selectionSort()
console.log(arr);
三、插入排序
1、算法思路
(1)插入排序跟前面两个排序不一样的地方是,它是向前排的
(2)它很像我们打扑克牌的时候一样,从第二个数开始,跟前面的比较,找到合适自己的位置插入
(3)而且,冒泡排序每次冒出最大的放右边,所以它的右边是慢慢排好的,
选择排序每次选择最小的放左边,所以它的左边是慢慢排好的
但是选择排序每次跟前面排,都要跟前面的每一个数比较的
2、编码实现
Array.prototype.insertionSort = function() {
// 向前排
for(let i = 1; i < this.length - 1; i += 1) {
let j = i;
const temp = this[i];
while(j) {
if(this[j-1] < temp) {
// 向后挪一个位置
this[j] = this[j-1]
} else {
break;
}
j -= 1;
}
// 这个时候的j就是合适的位置的下标了,再把刚才this[i]的值赋值给它
this[j] = temp;
}
}
const arr = [1, 5, 9, 3, 18, 6, 2, 7]
arr.insertionSort()
console.log(arr);
四、算法时间复杂度
这三个算法的时间复杂度都是O(n^2)哦,冒泡和选择是双重for循环,插入的性能稍微好一丢丢,但是也是一个for循环一个while循环~
这三个放在一起是因为是典型的实战不用,面试爱考系列~
好啦,写完了,开心,觉得写得不错的话就点个赞再走吧~