Hi,大家好,我是编程小6,很荣幸遇见你,我把这些年在开发过程中遇到的问题或想法写出来,今天说一说「算法与数据结构」梳理6大排序算法「建议收藏」,希望能够帮助你!!!。
这次梳理了一遍6种排序算法,从掌握思想到实现它,还是画了不少时间,又通过笔记梳理一遍,正好整理出来,对大家起一个抛砖引玉的效果吧。
6中常见的排序算法有GIF动图,更加容易帮助你理解其中的排序思想。
代码点这里GitHub
图片失效点这里阅读文章
6种排序如下👇
时间复杂度如下图👇
以下动图GIF来自知乎 帅地
这个名字的由来是向泡泡一样浮
起来,脑补一下,就是每次比较相邻的两个元素大小,然后慢慢'漂浮'起来,我瞎掰的,看思路吧。
「时间复杂度O(n*n)」
// 最外层循环控制的内容是循环次数
// 每一次比较的内容都是相邻两者之间的大小关系
let BubbleSort = function (arr, flag = 0) {
let len = arr.length
for (let i = 0; i < len - 1; i++) {
for (let j = 0; j < len - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
[arr[j], arr[j + 1]] = [arr[j + 1], arr[j]]
}
}
}
return flag ? arr.reverse() : arr
}
let arr = [2, 9, 6, 7, 4, 3, 1, 7]
console.log(BubbleSort(arr, 1))
从名称上就知道,它的思想:就是把数组元素作为数组的下标,然后用一个临时数组统计该元素出现的次数。
数组的数据必须是整数,而且最大最小值相差的值不要过大,对于「数据是负数的话,我实现的方案对此有优化」。
「时间复杂度:O(n+k)」
1.计算出差值d,最小值小于0,加上本身add
2.创建统计数组并统计对应元素个数
3.统计数组做变形,后面的元素等于前面的元素之和,也就是排名数组
4.遍历原始数组,从统计数组中找到正确位置,输出到结果数组
// 计数排序
let countingSort = function(arr, flag = 0) {
let min = arr[0],
max = arr[0],
len = arr.length;
// 求最大最小值
for(let i = 0; i < len; i++) {
max = Math.max(arr[i], max)
min = Math.min(arr[i], min)
}
// 1.计算出差值d,最小值小于0,加上本身add
let d = max - min,
add = min < 0 ? -min : 0;
//2.创建统计数组并统计对应元素个数
let countArray = new Array(d+1+add).fill(0)
for(let i = 0; i < len; i++){
let demp = arr[i]- min + add
countArray[ demp ] += 1
}
//3.统计数组做变形,后面的元素等于前面的元素之和,也就是排名数组
let sum = 0;
// 这里需要遍历的是countArray数组长度
for(let i = 0; i < d+1+add; i++){
sum += countArray[i]
countArray[i] = sum;
}
let res = new Array(len)
4.遍历原始数组,从统计数组中找到正确位置,输出到结果数组
for(let i = 0; i < len; i++){
let demp = arr[i] -min + add
res[ countArray[demp] -1 ] = arr[i]
countArray[demp] --;
}
return flag ? res.reverse() : res
}
let arr = [2, 9, 6, 7, 4, 3, 1, 7,0,-1,-2]
console.log(countingSort(arr))
基本思想:通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。
「时间复杂度:O(nlogn)」
let quickSort = function (arr) {
// 递归出口就是数组长度为1
if (arr.length <= 1) return arr
//获取中间值的索引,使用Math.floor向下取整;
let index = Math.floor(arr.length / 2)
// 使用splice截取中间值,第一个参数为截取的索引,第二个参数为截取的长度;
// 如果此处使用pivot=arr[index]; 那么将会出现无限递归的错误;
// splice影响原数组
let pivot = arr.splice(index, 1)[0],
left = [],
right = [];
console.log(pivot)
console.log(arr)
for (let i = 0; i < arr.length; i++) {
if (pivot > arr[i]) {
left.push(arr[i])
} else {
right.push(arr[i])
}
}
return quickSort(left).concat([pivot], quickSort(right));
}
//let arr = [2, 9, 6, 7, 4, 3, 1, 7]
// console.log(quickSort(arr))
将两个有序数列合并成一个有序数列,我们称之为“归并”
基本思想与过程:先递归的分解数列,再合并数列(分治思想的典型应用)
「时间复杂度: O(nlog(n))」
const merge = (left, right) => { // 合并数组
let result = []
// 使用shift()方法偷个懒,删除第一个元素,并且返回该值
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
}
let mergeSort = function (arr) {
if (arr.length <= 1)
return arr
let mid = Math.floor(arr.length / 2)
// 拆分数组
let left = arr.slice(0, mid),
right = arr.slice(mid);
let mergeLeftArray = mergeSort(left),
mergeRightArray = mergeSort(right)
return merge(mergeLeftArray, mergeRightArray)
}
let arr = [2, 9, 6, 7, 4, 3, 1, 7, 0, -1, -2]
console.log(mergeSort(arr))
顾名思义:通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。
「时间复杂度: O(n*n)」
let insertionSort = function (arr) {
let len = arr.length
for (let i = 0; i < len; i++) {
let preIndex = i - 1,
cur = arr[i];
while (preIndex >= 0 && arr[preIndex] > cur) {
arr[preIndex + 1] = arr[preIndex]
preIndex--;
}
arr[preIndex + 1] = cur
}
return arr
}
let arr = [2, 9, 6, 7, 4, 3, 1, 7, 0, -1, -2]
console.log(insertionSort(arr))
思路:每一次从待排序的数组元素中选择最大(最小)的一个元素作为首元素,直到排完为止
「时间复杂度O(n*n)」
let selectSort = function (arr, flag = 0) {
let len = arr.length,
temp = 0;
// 一共需要排序len-1次
for (let i = 0; i < len - 1; i++) {
temp = i;
for (let j = i + 1; j < len; j++) {
if (arr[j] < arr[temp])
temp = j;
}
// 每一趟保证第i位为最小值
if (temp !== i) {
[arr[i], arr[temp]] = [arr[temp], arr[i]]
}
}
return flag ? arr.reverse() : arr
}
let arr = [2, 9, 6, 7, 4, 3, 1, 7, 0, -1, -2]
console.log(selectSort(arr, 1))
如果你觉得这篇内容对你挺有有帮助的话: