/* 手撕排序 + 算法总结 */ //比较类排序:通过比较来决定元素间的相对次序,由于其时间复杂度不能突破O(nlogn),因此也称为非线性时间比较类排序。 //非比较类排序:不通过比较来决定元素间的相对次序,它可以突破基于比较排序的时间下界,以线性时间运行,因此也称为线性时间非比较类排序。 // 1.冒泡排序 //时间复杂度O(n^2) 最好情况O(n),空间O(1) 稳定 //它重复地走访过要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。 //走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。 var num = [1,2,4,3,5,6,8,7,9] var bubbleSort = function(num){ var temp=0; var i=num.length; while(i--){ for(let j=0;j<i-1;j++){ if(num[j]>num[j+1]){ temp = num[j+1]; num[j+1]=num[j]; num[j]=temp; } } } return num; } var a=bubbleSort(num); console.log(a); // 2.选择排序 //时间复杂度O(n^2) 最好情况O(n^2),空间O(1) 不稳定 //首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置; //然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。 var selectionSort = function(num){ for(let i=0;i<num.length;i++){ let temp=0; for(let j=i+1;j<num.length;j++){ if(num[i]>num[j]){ temp=num[j]; num[j]=num[i]; num[i]=temp; } } } return num; } var b=selectionSort(num); console.log(b); // 3.插入排序 //时间复杂度O(n^2) 最好情况O(n),空间O(1) 稳定 //通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。 var insertionSort = function(num){ var temp=0; for(let i=0;i<num.length;i++){ for(let j=i;j>0;j--){ temp = num[j]; if(num[j]<num[j-1]) num[j] = num[j-1]; else{ num[j]=temp; break; } } } return num; } var c=insertionSort(num); console.log(c) // 4.归并排序 //该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。 //将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。 function mergeSort(arr) { var len = arr.length; if (len < 2) { return arr; } var middle = Math.floor(len / 2), left = arr.slice(0, middle), right = arr.slice(middle); return merge(mergeSort(left), mergeSort(right)); } function merge(left, right) { var result = []; while (left.length>0 && right.length>0) { 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; } var d=mergeSort(num); console.log(d); // 5.快速排序 //通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小, //则可分别对这两部分记录继续进行排序,以达到整个序列有序。 //steps //从数列中挑出一个元素,称为 “基准”(pivot); //重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作; //递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。 var quickSort = function(nums){ var len = nums.length; if(len<2) return nums; var pivot = nums[Math.floor(len/2)]; var left = 0,right = nums.length-1; var temp = 0; while(left!=right){ if(nums[left]<pivot) left++; if(nums[right]>pivot) right--; temp = nums[right]; nums[right] = nums[left]; nums[left] = temp; } quickSort(nums.slice(0,left)); quickSort(nums.slice(right,len)); return nums; } var e=quickSort(num); console.log(e);
全部评论
(0) 回帖