前言
这是我参与8月更文挑战的第7天,活动详情查看:8月更文挑战”。
常见的几种排序算法。
自我学习,仅供参考。
冒泡排序
算法步骤
-
比较相邻的元素。如果第一个比第二个大,就交换他们两个。
-
对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。
-
针对所有的元素重复以上的步骤,除了最后一个。
-
持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
代码实现
var arr = [4,1,6,9,3,2,8,7];
function compare(a, b) { //比较函数
if(a < b) return false //前面的小于后面的,不排序
else return true //前面的大于后面的,需要排序
}
function exchange(arr, a, b) { //交换函数
var temp = arr[a]
arr[a] = arr[b]
arr[b] = temp
}
function bubbleSort(arr) { //排序函数
for(var i = 0; i < arr.length; i++) {
for(var j = 0; j < arr.length - 1 - i; j++){ //j取最后一个 j+1就不存在了 每循环一圈,就不用和后面的大数相比了所以 -i
if(compare(arr[j], arr[j + 1])) {
exchange(arr, j, j + 1)
}
}
}
}
sort(arr)
console.log(arr) //[1, 2, 3, 4, 6, 7, 8, 9]
选择排序
算法步骤
-
首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置。
-
再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。
-
重复第二步,直到所有元素均排序完毕。 代码实现
var arr = [4,1,6,9,3,2,8,7]
function exchange(arr, a, b) { //交换函数
var temp = arr[a]
arr[a] = arr[b]
arr[b] = temp
}
function selectSort(arr) { //排序函数
let len = arr.length //保存数组长度
for (let i = 0; i < len - 1; i++) {
let minIndex = i //假设最小的是第一个,已排序
for(let j = i + 1; j < len; j++){ //第一个元素已排序,从第二个元素开始
if(arr[j] < arr[minIndex]) { // 找最小的数
minIndex = j // 保存最小数的索引
}
}
if(i !== minIndex) {
exchange(arr, i, minIndex)
}
}
return arr
}
console.log(selectSort(arr)); //[1, 2, 3, 4, 6, 7, 8, 9]
插入排序
类似于玩扑克牌
算法步骤
-
将第一待排序序列第一个元素看做一个有序序列,把第二个元素到最后一个元素当成是未排序序列。
-
从头到尾依次扫描未排序序列,将扫描到的每个元素插入有序序列的适当位置。(如果待插入的元素与有序序列中的某个元素相等,则将待插入元素插入到相等元素的后面。) 代码实现
var arr = [4,1,6,9,3,2,8,7]
function insertSort(arr) {
for( var i = 1; i < arr.length; i++) { //假设第一个元素已经排好,从第二个元素开始
let curValue = arr[i]; //保存当前元素(值)
let j = i - 1; //和当前元素的前一个比较(j是索引)
while(j >= 0 && curValue < arr[j]) { // j最小为0 并且 当前元素小于前面元素
arr[j + 1] = arr[j]; //满足条件 把前面所有比当前元素大的后移一位
j--; //终止循环的条件
}
arr[j + 1] = curValue ; //当前元素放在 大于前面元素的后面一位
}
return arr
}
console.log(insertSort(arr)) //[1, 2, 3, 4, 6, 7, 8, 9]
快速排序
算法步骤
-
从数列中挑出一个元素,称为 "基准"(pivot);
-
重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作;
-
递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序; 总结来说,取一个元素作为leader,遍历数组,小于leader的放入一个数组,大于leader的放入另一个数组。
代码实现
var arr = [4,6,1,9,3,2,8,7];
function quickSort(arr) {
if(arr == null || arr.length === 0) return [];
var leader = arr[0];
var left = [],
right = [];
for(var i = 0; i < arr.length; i++) {
if(arr[i] < leader) left.push(arr[i]);
else right.push(arr[i])
}
left = quickSort(left);
right = quickSort(right);
return left.concat(leader,right)
}
console.log(quickSort(arr)) //[1, 2, 3, 4, 6, 7, 8, 9]
归并排序
算法步骤
-
申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列;
-
设定两个指针,最初位置分别为两个已经排序序列的起始位置;
-
比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置;
-
重复步骤 3 直到某一指针达到序列尾;
-
将另一序列剩下的所有元素直接复制到合并序列尾。
代码实现
var arr = [4,6,1,9,3,2,8,7];
function mergeSort(arr) {
let len = arr.length
if(len < 2) return arr
let middle = Math.floor(len / 2) //中间数
let left = arr.slice(0, middle) //分成左右两个数组
let right = arr.slice(middle)
return merge(mergeSort(left), mergeSort(right))
}
function merge(left, right) {
let result = []
while(left.length && right.length) {
if(left[0] < right[0]) {
result.push(left.shift())
} else {
result.push(right.shift())
}
}
while(left.length) result.push(left.shift())
while(right.length) result.push(right.shift())
return result
}
console.log(mergeSort(arr));