Js实现冒泡排序
// 是一种计算机科学领域的较简单的排序算法
// 它重复的走访过要排序的元素列,依次比较两个相邻的元素,如果顺序(如从大到小,首字母)错误就把他们交换过来。走访元素的工作是重复地进行直到没有相邻元素需要交换,也就是该元素列已经排序完成。
冒泡排序是效率最低的排序算法,由于算法嵌套了两轮循环,所以时间复杂度委O(n^2)
最好的情况给出一个已经排序的数组进行冒泡排序,时间复杂度为O(n)
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 
 | // 冒泡排序function bubbleSort(arr) {
 let len = arr.length;
 // 遍历数组的长度,以确定循环次数
 for (let i = 0; i < len;i++) {
 // 遍历数组len次,忽略后面的i项
 for (let j = 0; j < len - 1 - i; j++) {
 // 将每一项与后一项进行对比,不符合要求的就换位
 if (arr[j] > arr[j + 1]) {
 
 [arr[j + 1], arr[j]] = [arr[j], arr[j + 1]]
 }
 }
 }
 return arr
 }
 
 | 
实现一个快排
快速排序:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行上述递归排序,以此达到整个数据变成有序序列,时间复杂度为 O(n log n)。
// 1.Quickersort通过数组选取一个元素表示为基准点,把数组中的所有其他元素分为两类-(大于和小于此基准点的数组)
// 2.然后把作为这一轮排序结果的两个数组(数组元素都小于基准点的数组和数组元素都大于基准点的数组)再进行相同的排序。即分别再选个基准点,然后基于基准点分为两个数组元素分别小于和大于基准点的数组。
// 3.最终,由于最后数组中没有元素或只有一个元素,因此不用再比较了。剩下的值都已经基于基准点拍好序了。
(时间复杂度(平均)O(nlogn))
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 
 | const quickSort1 = arr => {if (arr.length <= 1) {
 return arr;
 }
 const midIndex = Math.floor(arr.length / 2)
 
 
 
 const arrArr = arr.splice(midIndex, 1)
 const midIndexVal = arrArr[0]
 const left = []
 const right = []
 for (let i = 0; i < arr.length; i++) {
 if (arr[i] < midIndexVal) {
 left.push(arr[i]);
 } else {
 right.push(arr[i])
 }
 }
 return quickSort1(left).concat(midIndexVal, quickSort1(right));
 }
 
 | 
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 
 | // 快速排序const testQuickSort = arr => {
 if (arr.length <= 1) {
 return arr;
 }
 const mid = arr[0];// 基准值
 const left = []
 const right = [];
 for (let i = 1; i < arr.length; i++) {
 if (arr[i] < mid) {
 left.push(arr[i])
 } else {
 right.push(arr[i])
 }
 }
 return [...testQuickSort(left), mid, ...testQuickSort(right)]
 }
 
 | 
选择排序 (O^2)
从上面可以看到,对于具有 n 个记录的无序表遍历 n-1 次,第i 次从无序表中第 i 个记录开始,找出后序关键字中最小的记录,然后放置在第 i 的位置上
直至到从第n个和第n-1个元素中选出最小的放在第n-1个位置
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 
 | 
 function testSelectSort(arr) {
 let len = arr.length;
 let minIndex;
 for (let i = 0; i < len - 1; i++) {
 minIndex = i;
 for (let j = 0; j < len; j++) {
 if (arr[j] < arr[minIndex]) {
 minIndex = j;
 }
 }
 [arr[i], arr[minIndex]] = arr[minIndex], arr[i];
 }
 return arr;
 }
 
 | 
第一次内循环比较N - 1次,然后是N-2次,N-3次,……,最后一次内循环比较1次 共比较的次数是 (N - 1) + (N - 2) + … + 1,求等差数列和,得 (N - 1 + 1)* N / 2 = N^2 / 2,舍去最高项系数,其时间复杂度为 O(N^2)
从上述也可以看到,选择排序是一种稳定的排序
插入排序
// 插入排序
// 将第一待排序序列第一个元素看做一个有序序列,把第二个元素到最后一个元素当成是未排序序列。
// 从头到尾依次扫描未排序序列,将扫描到的每个元素插入有序序列的适当位置
// 如果待插入的元素与有序序列中的某个元素相等,则将待插入元素插入到相等元素的后面
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 
 | function testInsertSort(arr) {const len = arr.length;
 let preIndex, current;
 for (let i = 1; i < len; i++) {
 preIndex = i - 1;
 current = arr[i];
 while (preIndex >= 0 && arr[preIndex] > current) {
 arr[preIndex + 1] = arr[preIndex];
 preIndex
 }
 arr[preIndex + 1] = current;
 }
 return arr;
 }
 
 | 
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 
 | function InsertSort(arr) {for (let i = 0; i < arr.length; i++) {
 for (let j = 0; j < i; j++) {
 if (arr > arr) {
 =
 }
 }
 }
 return arr;
 }
 
 | 
// 在插入排序中,当待排序数组是有序时,是最优的情况,只需当前数跟前一个数比较一下就可以了,这时一共需要比较N- 1次,时间复杂度为O(n)
// 最坏的情况是待排序数组是逆序的,此时需要比较次数最多,总次数记为:1+2+3+…+N-1,所以,插入排序最坏情况下的时间复杂度为O(n^2)
// 通过上面了解,可以看到插入排序是一种稳定的排序方式
参考文章