排序
1、冒泡排序
描述:最简单的排序,运行时间长
原理:从第一个开始和后面一项进行比较,较大的放在后面,直到把最大的放在最后。比较相邻的项,如果第一个比第二个大,则交换,上移至正确的排序。
代码:
function sort1(arr) {
for (let i = 0; i < arr.length; i++) {
for (let j = 0; j < arr.length - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
[arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];//解构赋值
}
}
}
return arr;
}
复杂度:时间复杂度O(n^2),空间复杂度O(1)
2、选择排序
描述:原地址比较排序算法
原理:找到数据结构中的最小值,并将其放在第一位,接着找到第二个,放在第二位,以此类推。
代码:
unction sort2(arr){
let len=arr.length;
for(let i=0;i<len-1;i++){
let min=i;
for(let j=i;j<len;j++){
if(arr[min]>arr[j]){
min=j;
}
}
if(min!=i){
[arr[min], arr[i]] = [arr[i], arr[min]];
}
}
return arr;
}
复杂度:时间复杂度O(n^2),空间复杂度O(1)
3、插入排序
描述:排小型数组的时候比冒泡和选择要好
原理:插入排序每次排一个数组项。从第二个开始,一次与之前的数进行比较后,选择合适位置插入。
代码:
function sort3(arr){
let len=arr.length,temp;
for(let i=1;i<len;i++){
let j=i;
temp=arr[i];//当前要插入的项
while(j>0&&arr[j-1]>temp){
arr[j]=arr[j-1];
j--;
}
arr[j]=temp;
}
return arr;
}
复杂度:时间复杂度O(n^2),空间复杂度O(1)
4、归并排序
描述:第一个实际使用的排序
原理:分治算法,将原始数组切分成较小的数组,直到每个小数组只有一个位置,将小数组归并成较大的数组,直到最后只有一个排序完成的大数组。
代码:
//分递归
function mergeSortRec (array){
var length=array.length;
if(length==1){
return array;
}//停止条件,长度为1
var mid = Math.floor(length/2),
left=array.slice(0,mid),
right=array.slice(mid,length);
return merge(mergeSortRec(left),mergeSortRec(right));
}
//合
var merge=function(left,right){
var result=[],il=0,ir=0;
while(il<left.length&&ir<right.length){
if(left[il]<right[ir]){//左右比较后按序放入新数组
result.push(left[il++]);
}else{
result.push(right[ir++]);
}
}
while(il<left.length){//剩余左侧
result.push(left[il++]);
}
while(ir<right.length){//剩余右侧
result.push(right[ir++]);
}
return result;
}
复杂度:时间复杂度O(nlongn),空间复杂度O(n)
5、快速排序
描述:最常用的排序算法
原理:(1)将原始数组划分为较小的数组,将数组中间项作为主元,创建两个指针,左指针指向数组的第一项,右指针指向数组的最后一项。移动左指针,直到找到第一个比主元大的元素,接着,移动右指针直到找到第一个比主元小的元素,然后交换,重复这个过程,直到左指针超过了右指针。(2)对划分后的两个数组再次重复上述操作,直到数组完全排序。
代码:
var quick = function(array,left,right){
var index;
if(array.length>1){
index = partition(array,left,right);
if(left<index-1){
//递归左边排序
quick(array,left,index-1);
}
if(index<right){
//递归右边排序
quick(array,index,right);
}
}
return array;
}
//左右分别交换
var partition=function(array,left,right){
var pivot=array[Math.floor((right+left)/2)],i=left,j=right;
while(i<=j){
while(array[i]<pivot){
i++;
}
while(array[j]>pivot){
j--;
}
if(i<=j){
//交换
[array[i],array[j]]=[array[j],array[i]];
i++;
j--;
}
}
return i;
}
console.log(quick(arr,0,arr.length-1)) ;
复杂度:时间复杂度O(nlongn),空间复杂度O(n)
搜索算法
1、顺序搜索
描述:顺序或线性搜索是最基本的搜索算法。
原理:将每一个数据结构中的元素和我们要找的元素做比较。顺序搜索是最低效的一种搜索算法。本质是循环。
2、二分搜索
描述:算法要求被搜索的数据结构已排序
原理:
(1)选择数组的中间值
(2)如果选中的值是待搜索值,那么算法执行完毕
(3)如果待搜索的值比选中值小,则返回步骤1并在选中值左边的子数组中寻找
(4)如果待搜索的值比选中值大,则返回步骤1并在选中值右边的子数组中寻找
function findtarget(nums,target){
let low =0,high=nums.length-1
while(low<=high){
const mid=Math.floor((high-low)/2)+low;//(1)
const num=nums[mid]
if(num==target){
return mid//(2)
}else if(num>target){
high=mid-1//(3)
}else if(num<target){
low=mid+1//(4)
}
}
return -1
}