内容简介:思路/原理:比较相邻的两个元素,如果前一个比后一个大,则交换位置,每一趟会将最小或最大的元素“浮”到顶端,最终达到完全有序。就好像一串气泡一样,最终从小到大或从大到小依次排下来。
冒泡排序
思路/原理:比较相邻的两个元素,如果前一个比后一个大,则交换位置,每一趟会将最小或最大的元素“浮”到顶端,最终达到完全有序。就好像一串气泡一样,最终从小到大或从大到小依次排下来。
function bubbleSort(arr) { var len = arr.length; // i表示第几趟排序 for(var i = 0; i < len - 1; i++) { // j表示交换次数 for(var j = 0; j < len - 1 - i; j++) { if(arr[j] > arr[j + 1]) { // var temp = arr[j]; // arr[j] = arr[j + 1]; // arr[j + 1] = temp; [arr[j], arr[j + 1]] = [arr[j + 1], arr[j]]; } } } return arr; } console.log(bubbleSort([3, 1, 8, 10, 5]));复制代码
时间复杂度: 平均情况O(n²) 最坏情况O(n²) 最好情况O(n)
空间复杂度: O(1)
稳定性: 稳定
由于冒泡 排序 只在相邻元素大小不符合要求时才调换他们的位置,它并不改变相同元素之间的相对顺序,因此它是稳定的排序算法。
复杂性: 简单
选择排序
思路/原理: 每一趟从待排序的记录中选出最小的元素,顺序放在已排好序的序列最后,直到全部记录排序完毕。
function selectSort(arr) { var len = arr.length; // 控制位置 for(var i = 0; i < len - 1; i++) { // 假如这个是最小的 var min = i; // 与后面的数字进行比较 寻找最小值的索引 for(var j = i + 1; j < len; j++) { if(arr[j] < arr[min]) { min = j; } } // 如果当前的值的索引和最小值的索引不相等 交换位置 if(i !== min) { [arr[i], arr[min]] = [arr[min], arr[i]]; } } return arr; }复制代码
时间复杂度: 平均情况O(n²) 最坏情况O(n²) 最好情况O(n²)
空间复杂度: O(1)
稳定性: 不稳定
Tips: 选择排序每次交换的元素都有可能不是相邻的 因此它有可能打破原来值为相同的元素之间的顺序 比如数组[2,2,1,3] 正向排序时 第一个数字2将与数字1交换 那么两个数字2之间的顺序将和原来的顺序不一致 虽然它们的值相同 但它们相对的顺序却发生了变化 我们将这种现象称作 不稳定性 .
选择排序的简单和直观名副其实 这也造就了它"出了名的慢性子" 无论是哪种情况 哪怕原数组已排序完成 它也将花费将近n²/2次遍历来确认一遍 即便是这样 它的排序结果也还是不稳定的 唯一值得高兴的是 它并不耗费额外的内存空间
插入排序
思路/原理: 将排序分为排序与未排序,将未排序的数依次向排序数进行比较。
function insertSort(arr) { var len = arr.length; for (var i = 1; i < len; i++) { var temp = arr[i]; // 要插入的元素 // 与前面的排序好的数组进行比较 var j = i - 1; while(j >= 0 && temp < arr[j]) { // 如果当前元素小于他们 则他们往后运动 并交换当前元素和他们的位置 否则不动 arr[j + 1] = arr[j]; j --; } arr[j + 1] = temp; } return arr } console.log(insertSort([2, 1, 4, 8, 3])); 复制代码
时间复杂度: 平均情况O(n²) 最坏情况O(n²) 最好情况O(n)
空间复杂度: O(1)
稳定性: 稳定
Tips: 由于直接插入排序每次只移动一个元素的位置 并不会改变值相同的元素之间的排序 因此它是一种稳定排序
归并排序
思路/原理: 归并排序建立在归并操作之上 它采取分而治之的思想 将数组拆分为两个子数组 分别排序 最后才将两个子数组合并 拆分的两个子数组 再继续递归拆分为更小的子数组 进而分别排序 直到数组长度为1 直接返回该数组为止
// 采用分而治之的思想 把数组以递归的方式分为左右相等的两个数组 function mergeSort(arr) { var len = arr.length; // 递归出口 if(len < 2) { return arr; } var mid = parseInt(len / 2), left = arr.slice(0, mid), right = arr.slice(mid); return merge(mergeSort(left), mergeSort(right)); } // 把两个数组进行排序 function merge(left, right) { var res = []; while(left.length && right.length) { if(left[0] < right[0]) { res.push(left.shift()); }else { res.push(right.shift()); } } // 把剩余的数组连接 while(left.length) { res.push(left.shift()); } while(right.length) { res.push(right.shift()); } return res; }复制代码
时间复杂度: 平均情况O(n log n) 最坏情况O(n log n) 最好情况O(n log n)
空间复杂度: O(n)
稳定性: 稳定
Tips: 由于直接插入排序每次只移动一个元素的位置 并不会改变值相同的元素之间的排序 因此它是一种稳定排序
你的点赞是我持续输出的动力 希望能帮助到大家 互相学习 有任何问题下面留言 一定回复
未完待续。。。。。。。。。。。。。。。。。。。。。。。。。
以上所述就是小编给大家介绍的《应届生必须掌握的十大排序算法》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 算法之常见排序算法-冒泡排序、归并排序、快速排序
- 排序算法之冒泡排序改进算法
- 快速排序算法,C语言快速排序算法深入剖析
- 排序算法下——桶排序、计数排序和基数排序
- 数据结构和算法面试题系列—排序算法之快速排序
- 数据结构和算法面试题系列—排序算法之基础排序
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。