js算法排序

107 阅读2分钟

image.png

排序

排序属于算法入门,所以很容易考到。
请自行在谷歌或维基百科搜索这些算法并搞懂:

1.快速排序

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

  • 在数据集之中,选择一个元素作为"基准"(pivot)
  • 所有小于"基准"的元素,都移到"基准"的左边;所有大于"基准"的元素,都移到"基准"的右边。
  • 对"基准"左边和右边的两个子集,不断重复第一步和第二步,直到所有子集只剩下一个元素为止。
var arr = [5,4,8,1,3,7,0,9,2,6];
        var len = arr.length;
        var qsort = function(arr){
            var len = arr.length;
            if (len < 2) return arr;
            var basic = arr[0];            //默认第一个为基准数
            var left = [];
            var right = [];
            
            for(var j=1; j<len ; j++){
                if(arr[j] < basic){
                    left.push(arr[j]);
                }else {
                    right.push(arr[j]);
                }

            }

            return qsort(left).concat(basic, qsort(right))
        }
qsort(arr)

2.计数排序

计数排序就是简单的桶排序,一个桶代表数组中一个数出现的个数,所以需要一个和数组数字范围一样大的辅助数组,一般用在范围小于100的排序,时间复杂度为O(n),空间复杂度为数组的数字范围。

Array.prototype.countSort = function() {
    let len = this.length
    if (len < 2) {
        return
    }
    // 桶数组
    var suportArr = new Array(len + 1);
    // 结果数组
    var resArr = new Array(len);
    // 初始化桶数组
    for (i = 0; i < suportArr.length; i++) {
        suportArr[i] = 0;
    }
    // 待排序数组中的数组出现,在桶子对应位置+1代表这个数出现的个数+1了
    for (let i = 0; i < len; i++) {
        suportArr[arr[i]]++;
    }
     // 从第1项开始,桶数组加上前一个桶的个数,现在辅助数组的意义变成了每一项的排名了。
      for (let i = 1; i < suportArr.length; i++) {
        suportArr[i] += suportArr[i - 1];
      }
      // 根据辅助数组的排名,从后往前赋值
      for (let i = len - 1; i >= 0; i--) {
        resArr[suportArr[arr[i]] - 1] = arr[i];
        suportArr[arr[i]]--;
      }
    // 这里this不能直接赋值数组,我们就只能采取splice剪切数组再替换新的
    this.splice(0, this.length, resArr)
}
let arr = [2,9,5,7,1,1,6,3,3,4]
arr.countSort()
console.log("c排序后:", arr.toString())

3.冒泡排序

var arr = [5,4,8,1,3,7,0,9,2,6];
var len = arr.length;
var tmp = null;
for(var j=0; j<len-1; j++){      //循环9次
    for(var i=0; i<len-1-j; i++){    //每次比较10-j-1次数
    if(arr[i]>arr[i+1]){
        tmp = arr[i+1];
        arr[i+1] = arr[i];
        arr[i] = tmp;
    }
    }  console.log('第'+(j+1)+'次循环',arr);<br> }

大数相加

function add(a ,b){
   //取两个数字的最大长度
   let maxLength = Math.max(a.length, b.length);
   //用0去补齐长度
   a = a.padStart(maxLength , 0);//"0009007199254740991"
   b = b.padStart(maxLength , 0);//"1234567899999999999"
   //定义加法过程中需要用到的变量
   let t = 0;
   let f = 0;   //"进位"
   let sum = "";
   for(let i=maxLength-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 parseInt(sum);
}

两数之和

给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。
示例:
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]

var nums = [2, 7, 11, 15];
function twoSum(arr, target) {
      var brr = [];
      for (var i = 0; i < arr.length; i++) {
          for (var j = 0; j < arr.length; j++) {
              if (arr[i] + arr[j] === target) {
                  brr[0] = j;
                  brr[1] = i;
              }
          }
      }
      return brr;
  }
let result = twoSum(nums, 18);
console.log(result)

方法二:

一层循环:

 var nums = [2, 7, 11, 15];
    function twoSum(arr, target) {
        var obj = {};
        var brr = [];
        //debugger;
        for (var i = 0; i < arr.length; i++) {
            let a = arr[i];
            let b = target - a;
            if (obj[a] !== undefined) {
                brr = [obj[a], i];
            } else {
                obj[b] = i;   
            }
        }
        return brr;
    }
    let result = twoSum(nums, 9);
    console.log(result)

js算法排序 - 知乎 (zhihu.com)