算法与数据结构之四种算法

104 阅读2分钟

写算法的思路

  • 写算法之前先把思路写出来
  • 把一个大的函数尽快能拆成小函数先实现小函数的目标一步步接近

所有的递归都可以改写成循环

处理数组长度0或者1的方式最简单就是if... return

哈希表和JS对象的区别:

  • JS对象只是哈希表的一种具体实现
  • JS对象的key仅仅支持string,而哈希表支持所有类型
  • JS对象有原型链,哈希表没这种东西

传值与传地址要分清

把数组一整个当参数扔过去才能修改原数组

// 错误写法1
// 试图写一个函数用于修改二元数组的元素顺序
var arr=[1,2]
let swap=([a,b])=>{ // 复制了一份值分别给ab两个变量
	let temp=a;
    a=b;
    b=temp;
}
swap(arr);
// 这样根本无法改变arr

// 错误写法2
var arr=[1,2]
let swap=(a,b)=>{ // 和上面的错误一模一样的 ab接收的是arr[0][1]里面存的数据
	let temp=a;
    a=b;
    b=temp;
}
swap(arr[0],arr[1]);
// 正确写法
var arr=[1,2]
let swap=(array)=>{ // 收到的是一份地址
	let temp=array[0];
    array[0]=array[1];
    array[1]=temp;
}
swap(arr); // 把数组一整个当参数扔过去才能修改原数组

选择排序法

  • 每次从一堆中选最大或者最小的,选完就排完了
// 用选择排序法写了个minIndex
var arr=[5,3,2,1,0];
var minIndex=function(arr){
let index=0;
    for(let i=index;i<arr.length-1;i++){
        if(arr[i]>arr[i+1]){
            index=i+1
        }
    }    
     return index
}
// 用选择排序法写了个sort
var arr=[5,3,2,1,0];
function swap(arr,i,index){
	let temp=arr[index];
    arr[index]=arr[i];
    arr[i]=temp;
    return arr.shift();
}
function sort(arr){
	let arrLength=arr.length
	let newArr=[]
    for(let i=0;i<arrLength;i++){
        let index=minIndex(arr);
        newArr.push(swap(arr,0,index));
    }
	return newArr
}

快速排序法

  • 快排法的优点就是快
  • 思想是:
    • 找一个基准点把一个数组一分为二 --- 步骤1
    • 把数组中所有比这个基准点小的放到左边的箩筐 然后持续步骤1
    • 把数组中所有比这个基准点大的放到右边的箩筐 然后持续步骤1
    • 直到把原数组中每一项都拆成最小的独立的数组
    • 最后把这些所有数组拼到一起去
// 以下为递归写法
function quickSort(arr){
	if(arr.length<=1){
	return arr
	}
  let pivot=Math.floor(arr.length/2);
  let arrPivot=arr.splice(pivot,1)[0];
  let left=[];
  let right=[];
  for(let i=0;i<arr.length;i++){
	if(arr[i]<arrPivot){
    	left.push(arr[i])
    }else{
    	right.push(arr[i])
	}
  }
  return quickSort(left).concat([arrPivot],quickSort(right))
}

归并排序法

  • 先把一个数组拆成最小单位 也就是 [0],[1]...
  • 然后再把一个个最小单位合并在一起并两两排序
  • Math.floor() 这个可以学到一手,当你数组不是偶数的时候你总要有一个基准点以分割左右两部分
  • arr.slice(3) 注意这个api 意思是从下标3开始切 一直切到最后
let mergeSort = arr =>{
	let k=arr.length
    if(k===1){return arr} // 这句话是mergeSort最终的终点 
    //  mergeSort的最终结果一定是要return给你[0] [1]这样类似的结构的
    let left=arr.slice(0,Math.floor(k/2))
    let right=arr.slice(Math.floor(k/2))
    return merge(mergeSort(left),mergeSort(right))
    // 然后压在call stack最后的mergeSort函数会回到上一级的栈,与另外一个小伙伴一同运行merge函数
}
let merge=(a,b)=>{
	if(a.length===0) return b
    if(b.length===0) return a
    return a[0] > b[0]?
    	[b[0]].concat(merge(a,b.slice(1))):
        [a[0]].concat(merge(a.slice(1),b))
}

计数排序法