排序、Math相关手写代码题

114 阅读2分钟
算法时间复杂度(最好,最坏,平均)空间复杂度稳定性
冒泡O(N),O(N^2),O(N^2)O(1)稳定
选择O(N),O(N^2),O(N^2)O(1)不稳定
快速O(N * log2N),O(N^2),O(N * log2N)O(N * log2N)~O(N)不稳定

冒泡排序

是一个两层循环,每次将最大或最小的放到数组最后。

for(var i=0;i<test.length;i++){
  for(var j=0;j<test.length-i-1;j++){
    if(test[j]>test[j+1]){
      temp=test[j];
      test[j]=test[j+1];
      test[j+1]=temp;
    }
  }
}

选择排序

选择排序,直接从待排序数组里选择一个最小(或最大)的数字,每次都拿一个最小(或最大)数字出来,顺序放入新数组,直到全部拿完。

for(var i=0;i<test.length-1;i++){
  for(var j=i+1;j<test.length;j++){
    if(test[i]>test[j]){
      temp=test[i];
      test[i]=test[j];
      test[j]=temp;
    }
  }
}

快速排序

"快速排序"的思想很简单,整个排序过程只需要三步:

  1. 在数据集之中,选择一个元素作为"基准"(pivot)。
  2. 所有小于"基准"的元素,都移到"基准"的左边;所有大于"基准"的元素,都移到"基准"的右边。
  3. 对"基准"左边和右边的两个子集,不断重复第一步和第二步,直到所有子集只剩下一个元素为止。
function quickSort(arr){
  //如果数组<=1,则直接返回(终止条件)
  if(arr.length<=1){
      return arr;
  }
  let middleIndex=Math.floor(arr.length/2);
  //找基准,并把基准从原数组删除
  let middle=arr.splice(middleIndex,1)[0];
  //定义左右数组
  let left=[];
  let right=[];
  //比基准小的放在left,比基准大的放在right
  for(let i=0;i<arr.length;i++){
      if(arr[i]<middle){
          left.push(arr[i])
      }else{
          right.push(arr[i])
      }
  }
  //递归
  return quickSort(left).concat([middle],quickSort(right))
}

大数相加

function add(a,b) {
    let maxLen=Math.max(a.length,b.length);
    a=a.padStart(maxLen,0) //补零
    b=b.padStart(maxLen,0)
    let t=0;//结果
    let f=0;// 是否进位
    let sum='';//最终结果
    for(let i=maxLen-1;i>=0;i--){
        t=parseInt(a[i])+parseInt(b[i])+f;
        f=Math.floor(t/10);
        sum=t%10+sum;
    }
    if(f==1){
        sum='1'+sum
    }
    return sum;
}
let a="9007199254740991";
let b="1234567899999999999";
console.log(add(a,b)) //1243575099254740990

解决小数精度问题

先转化为整数,在计算,计算完成后除以10^n

//加法函数,用来得到精确的加法结果
//说明:javascript的加法结果会有误差,在两个浮点数相加的时候会比较明显。这个函数返回较为精确的加法结果。
//调用:accAdd(arg1,arg2)
//返回值:arg1加上arg2的精确结果
function accAdd(arg1, arg2) {
  var r1, r2, m;
  try {
    r1 = arg1.toString().split(".")[1].length;
  } catch (e) {
    r1 = 0;
  }
  try {
    r2 = arg2.toString().split(".")[1].length;
  } catch (e) {
    r2 = 0;
  }
  m = Math.pow(10, Math.max(r1, r2));
  return (arg1 * m + arg2 * m) / m;
}
//给Number类型增加一个add方法,调用起来更加方便。
Number.prototype.add = function (arg) {
  return accAdd(arg, this);
};