七种比较排序算法

1. 冒泡排序:O(n²)                            

前一项和后一项进行比较,一轮循环后,将最大的数放置在数组末尾,并使计算的数组长度减一,减少一次比较,然后进入下一轮循环

let arr = [3,64,43,7,74,10];
let len = arr.length;
for(let i = 0; i < len - 1; i++) {         // n个数比较n-1次
   for(let j = 0; j < len - 1 - i; j++) {   // 每次有一个数被被确定,确定的数的量就是i,不用比较
      if(arr[j] > arr[j + 1]) {
         temp = arr[j];
         arr[j] = arr[j + 1];
         arr[j + 1] = temp;
      }
    }
}
console.log(arr);

 2. 选择排序:O(n²)

let arr = [3,64,43,7,74,10];
let len = arr.length;
let temp;
for(let i = 0; i < len - 1; i++) {
    for(let j = 0; j < len; j++) {
    temp = arr[i];
    arr[i] = arr[j];
    arr[j] = temp;
  }
}

 

3. 插入排序:O(n²)

let arr = [3,64,43,7,74,10];
let len = arr.length;
1.第一种方式
for (let i = 1; i < len; i++) {
      for (let j = i; j > 0; j--) {
          if (arr[j] < arr[j - 1]) {
              temp = arr[j];
              arr[j] = arr[j - 1];
              arr[j - 1] = temp;
          }
      }
}
2.第二种方式: 优化的插入排序,减少数组的访问次数
let preIndex;
for(let i = 1; i < len; i++) {
    preIndex = i - 1;
    current = arr[i];                                   //将当前项先存储
    while(preIndex >= 0 && arr[preIndex] > current) {   //使当前项与前一项进行比较
        arr[preIndex + 1] = arr[preIndex];              //如果前面的项大于当前项就使前一项的索引加1
        preIndex--;                                     //然后再使当前项(保留值current)与前一项比较,直到小于当前项,退出循环
    }
    arr[preIndex + 1] = current;                        //此时的preIndex为比当前项小的项,所以将当前项插入到它的后面
}
console.log(arr);

4. 希尔排序:O(n^1.3)

    let arr = [3,64,43,7,74,10];
    let len = arr.length,
        temp,
        gap = Math.floor(len / 2),                 //将数组划分,可以自己选,但是一定要小于len
        multiPreIndex;        
        while(gap > 0) {
            for (let i = gap; i < len; i++) {
                temp = arr[i];                      //与插入排序一样,保留当前值      
                for (multiPreIndex = i - gap; multiPreIndex > 0 && arr[multiPreIndex]> temp; multiPreIndex -= gap) {
                    arr[multiPreIndex + gap] = arr[multiPreIndex];       //如果前面的那个项大于当前项,就将前面的项索引往后移gap个单位
                }
                arr[multiPreIndex + gap] = temp;     //将当前值插入到比它小的项后面gap个单位索引的地方
            }
            gap = parseInt(gap / 2);     //因为JS的数值都是浮点数,需要使用parseInt将其转化为整数,或者使用Math.floor,每次缩小范围
        }
    console.log(arr);

5. 归并排序:O(nlog2^n)

    let arr = [3,67,43,7,74,10];
    function mergeSort(arr) {
        let len = arr.length;
        if (len < 2) {
            return arr;
        }
        let middle = parseInt(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());           //将小的首项添加到result数组,并且删除原数组该首项
            } else {
                result.push(right.shift());
            }
        }
        while (left.length)
            result.push(left.shift());              //将剩下的未比较项全部添加入result数组
        while (right.length)
            result.push(right.shift());
        return result;
    }
    let array = mergeSort(arr);
    console.log(array);

6. 快速排序:O(nlog2^n)

        let arr = [3,67,43,7,74,10];
        let array = quickSort(arr);
        console.log(array);
        function quickSort(arr, left, right) {
            var len = arr.length,
                partitionIndex,
                left = typeof left != 'number' ? 0 : left,                    
                right = typeof right != 'number' ? len - 1 : right;         
            if (left < right) {
                partitionIndex = partition(arr, left, right);    //返回基准,基准的左边都是比基准小的,右边都是比基准大的      
                quickSort(arr, left, partitionIndex - 1);       //缩小范围,创建新的基准,进行比较
                quickSort(arr, partitionIndex + 1, right);
            }
            return arr;
        }

        function partition(arr, left, right) {     
            var pivot = left,                          //将最左边(除去已经排好的)的数作为基准
                index = pivot + 1;                     // 
            for (var i = index; i <= right; i++) {
                if (arr[i] < arr[pivot]) {              //基准右边的值与基准进行比较
                    swap(arr, i, index);                //将比基准小的值放左边,比基准大的值放右边(都在基准后面)
                    index++;                            //index可以作为比基准小的数的个数
                }
            }
            swap(arr, pivot, index - 1);                //将基准插入到比它小的最右边数的后面
            return index - 1;
        }

        function swap(arr, i, j) {
            var temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
        }

7. 堆排序:O(nlog2^n)

    let arr = [3,67,43,7,74,10];
    let len = arr.length;
    let array = heapSort(arr);
    console.log(array);
    function buildMaxHeap(arr) {                    // 建立大顶堆
        len = arr.length;
        for (var i = Math.floor((len - 2) / 2); i >= 0; i--) {   // len-2 防止超出数组长度
            heapify(arr, i);
        }
    }
    function heapify(arr, i) {                      // 堆调整
        var left = 2 * i + 1,                       // 左结点,如第一个左节点的索引为1,层次i为0, 2 * 0 + 1 = 1
            right = 2 * i + 2,
            largest = i;                            // 把根结点i先当做最大值
        if (left < len && arr[left] > arr[largest]) { //如果左结点存在且大于根结点
            largest = left;                           //将左结点的索引赋值给根结点索引保存值
        }
        
        if (right < len && arr[right] > arr[largest]) {
            largest = right;
        }

        if (largest != i) {                         //如果根结点索引保存值被赋值了新的值
            swap(arr, i, largest);                  //就将新的索引和原根结点索引上的值互换
            heapify(arr, largest);             
        }

    }
    function swap(arr, i, j) {
        var temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
    function heapSort(arr) {
        buildMaxHeap(arr);
        for (var i = arr.length - 1; i > 0; i--) {
            swap(arr, 0, i);                            //将顶点(确定的最大值)和数组最后一个互换
            len--;                                      //使接下去的计算数组计算长度减一(不是原数组长度减一)
            heapify(arr, 0);                            //因为最后一个数被放到最前面,不确定这个数和后面两个数的大小关系,因为没它们之间进行结点比较运算,所以需要再对前3项进行根结点和子节点的比较排序,后面的数之前已经按结点进行过比较
        }
        return arr;
    }

推荐:https://www.cnblogs.com/onepixel/articles/7674659.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值