zoukankan      html  css  js  c++  java
  • 排序

    ⭐时间复杂度

    1、常数阶O(1)

    只要代码中没有复杂的循环条件,无论代码的函数是多少,一律为常数阶O(1)。

    1 for(int i=0;i<n;i++){
    2     int j=o;
    3     j++;
    4 }

    2、对数阶O(log2n)

    存在循环体,在不考虑循环体的代码执行情况,该循环体本该执行n次,但是循环体将改变循环变量i的大小,每执行一次,i就扩到两倍,即i=i*2,这样就导致循环体会加速趋近终止条件n;假设经过x次后,退出循环体,则有2x>=n,因此,x=log2n;同理,当i=i∗3时,x=log3n,退出循环的速度更快,时间复杂度更小。

    1 while(i<n){
    2     i=i*2;
    3 }

    3、线性阶O(n)

    存在循环体。循环体内代码执行的次数随着规模n的变化而变化,并且是线性变化。

    1 for(int i=0;i<n;i++){
    2     int j=o;
    3     j++;
    4 }

    4、线性对数阶O(nlog2n)

    将时间复杂度为O(log2n)的代码重复执行n次,即为线性对数阶O(nlog2n)。

    1 //n为一个固定的常数
    2 //i和j均为循环变量
    3 while(i<n){//线性节阶
    4     while(j<n){//对数阶
    5         j=j*2;
    6     }
    7 }

    5、平方阶O(n2)

     复杂度为O(n)的代码执行了n次。

    1 for(int i=0;i<n;i++){//执行n次
    2     for(int j=0;j<n;j++){//执行n次
    3         int m=0;
    4         m++;
    5     }
    6 }

    6、立方阶O(n3)

    和平方阶原理一样,时间复杂度为O(n2)的代码执行n次。

    1 for(int i=0;i<n;i++){//执行n次
    2     for(int j=0;j<n;j++){//执行n次
    3         for(int k=0;k<n;k++){
    4             int m=0;
    5             m++;
    6         }
    7     }
    8 }        

    O(1)<O(log2n)<O(n)<O(nlog2n)<O(n2)<O(nk)

    ⭐空间复杂度

    1、O(1)

    1 let a = 1;
    2 let b = 1;
    3 let c = 1;
    4 let d = 1;

    2、O(n)

    1 let arr = Array(n)

    3、O(n2)

    1 let arr=[]
    2 for (var i = 0; i < n; i++) {
    3   arr[i]=i
    4   for (var j = 0; j < n; j++) {
    5     arr[i][j]=j
    6   }
    7 }

    排序前数组的准备:

     1 <!DOCTYPE html>
     2 <html lang="en">
     3 
     4 <head>
     5     <meta charset="UTF-8">
     6     <meta http-equiv="X-UA-Compatible" content="IE=edge">
     7     <meta name="viewport" content="width=device-width, initial-scale=1.0">
     8     <title>Document</title>
     9 </head>
    10 
    11 <body>
    12     <script>
    13         let arr = [];
    14         for (let i = 0, len = 10; i < len; i++) {
    15             let num = Math.floor(Math.random() * 100);
    16             arr.push(num);
    17         }
    18         console.log('arr', arr);
    19 
    20         console.time('a');
    21 
    22         //排序算法位置
    23         //排序算法位置
    24 
    25         console.timeEnd('a');
    26         console.log('arr', arr);
    27     </script>
    28 </body>
    29 
    30 </html>

    ⭐冒泡排序

    从第一个元素开始,把当前元素和下一个索引元素进行比较。如果当前元素大,那么就交换位置,重复操作直到比较到最后一个元素。

    1         for (let i = arr.length - 1; i > 0; i--) {
    2             for (let j = 0; j < i; j++) {
    3                 if (arr[j] > arr[j + 1]) {
    4                     [arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];
    5                 }
    6             }
    7         }

    ⭐插入排序

    第一个元素默认是已排序元素,取出下一个元素和当前元素比较,如果当前元素大就交换位置。那么此时第一个元素就是当前的最小数,所以下次取出操作从第三个元素开始,向前对比,重复之前的操作。

    自己写的:

     1        for (let i = 1, len = arr.length; i < len; i++) {
     2             for (let j = i - 1; j >= 0; j--) {
     3                 if (arr[i] < arr[0]) {
     4                     let temp = arr[i];
     5                     arr.splice(i, 1);
     6                     arr.unshift(temp);
     7                     break;
     8                 }
     9                 if (arr[i] > arr[j - 1] && arr[i] < arr[j]) {
    10                     let temp = arr[i];
    11                     arr.splice(i, 1);
    12                     arr.splice(j, 0, temp);
    13                     break;
    14                 }
    15             }
    16         }

    正规的:

     1         for (let i = 1, len = arr.length; i < len; i++) {
     2             let nowPosition = i;
     3             let nowData = arr[i];
     4             for (let j = i - 1; j >= 0; j--) {
     5                 if (arr[j] > nowData) {
     6                     arr[nowPosition] = arr[j];
     7                     arr[j] = nowData;
     8                     nowPosition = j
     9                 }
    10             }
    11         }

    ⭐选择排序

    遍历数组,设置最小值的索引为0,如果取出的值比当前最小值小,就替换最小值索引,遍历完成后,将第一个元素和最小值索引上的值交换。如上操作后,第一个元素就是数组中的最小值,下次遍历就可以从索引 1 开始重复上述操作。

    1         for (let i = 0, len = arr.length - 1; i < len; i++) {
    2             for (let j = i + 1, len = arr.length; j < len; j++) {
    3                 if (arr[j] < arr[i]) {
    4                     let a = arr[j];
    5                     arr[j] = arr[i];
    6                     arr[i] = a;
    7                 }
    8             }
    9         }

    ⭐快速排序

    在数据集之中,找一个基准点,建立两个数组,分别存储左边和右边的数组,利用递归进行下次比较。

     1        function quickSort(theArr) {
     2             let len = theArr.length;
     3             if (len < 2) {
     4                 return theArr;
     5             };
     6             let middleNum = Math.floor(len / 2);
     7             let left = [];
     8             let right = [];
     9             let middle = theArr[middleNum];
    10             for (let i = 0; i < len; i++) {
    11                 if (i !== middleNum && theArr[i] < middle) {
    12                     left.push(theArr[i]);
    13                 } else if (i !== middleNum && theArr[i] >= middle) {
    14                     right.push(theArr[i]);
    15                 }
    16             }
    17             return quickSort(left).concat(middle, quickSort(right));
    18         }
    19         arr = quickSort(arr);

    ⭐希尔排序

    按增量序列个数 k,对序列进行 k 趟排序;

    每趟排序,根据对应的增量 ti,将待排序列分割成若干长度为 m 的子序列,分别对各子表进行直接插入排序。仅增量因子为 1时,整个序列作为一个表来处理,表长度即为整个序列的长度。

     1         let gap = Math.floor(arr.length / 2);
     2         do {
     3             for (let i = 0, len = arr.length - gap; i < len; i++) {
     4                 let nowPosition = i;
     5                 let nowData = arr[i];
     6                 for (let j = i + gap, len = arr.length; j < len; j = j + gap) {
     7                     if (nowData > arr[j]) {
     8                         arr[nowPosition] = arr[j];
     9                         arr[j] = nowData;
    10                         nowPosition = j;
    11                     }
    12                 }
    13             }
    14             gap = Math.floor(gap / 2);
    15         } while (gap >= 1);

    ⭐归并排序

    (1)把长度为n的输入序列分成两个长度为n/2的子序列;

    (2)对这两个子序列分别采用归并排序;

    (3)将两个排序好的子序列合并成一个最终的排序序列。

     1         function Merge(theArr) {
     2             if (theArr.length < 2) {
     3                 return theArr;
     4             }
     5             let middle = Math.floor(theArr.length / 2);
     6             let left = theArr.slice(0, middle);
     7             let right = theArr.slice(middle);
     8             return MergeSort(Merge(left), Merge(right));
     9         }
    10 
    11         function MergeSort(left, right) {
    12             let sortData = [];
    13             while (left.length !== 0 && right.length !== 0) {
    14                 if (left[0] < right[0]) {
    15                     sortData.push(left.shift());
    16                 } else {
    17                     sortData.push(right.shift());
    18                 }
    19             }
    20             return sortData.concat(left, right);
    21         }
    22 
    23         arr = Merge(arr);

    ⭐二分排序

    在插入第i个元素时,对前面的0~i-1元素进行折半,先跟他们中间的那个元素比,如果小,则对前半再进行折半,否则对后半 进行折半,直到left>right,然后再把第i个元素前1位与目标位置之间的所有元素后移,再把第i个元素放在目标位置上。

     1         for (let i = 1, len = arr.length; i < len; i++) {
     2             let temp = arr[i];
     3             if (arr[i] < arr[0]) {
     4                 arr.splice(i, 1);
     5                 arr.unshift(temp);
     6             } else if (arr[i] > arr[i - 1]) {
     7                 continue;
     8             } else {
     9                 let position = DichotomySort(0, i - 1, temp);
    10                 arr.splice(i, 1);
    11                 arr.splice(position, 0, temp);
    12             }
    13         }
    14 
    15         function DichotomySort(left, right, value) {
    16             if (left === right) {
    17                 return left;
    18             }
    19             let middle = Math.floor((right + left) / 2);
    20             if (value < arr[middle]) {
    21                 return DichotomySort(left, middle, value);
    22             } else {
    23                 return DichotomySort(middle + 1, right, value);
    24             }
    25         }

    Array自带的sort()和reverse()

    1、Array.reverse()倒序。

    2、Array.sort():不给参数按ascii码排序。Array.sort(function(a,b){return b - a}):降序。

  • 相关阅读:
    Codeforces Round #518 (Div. 1) Computer Game 倍增+矩阵快速幂
    BZOJ2756 [SCOI2012]奇怪的游戏 最大流
    Codeforces Global Round 1 (CF1110) (未完结,只有 A-F)
    [AtCoder] NIKKEI Programming Contest 2019 (暂缺F)
    [AtCoder] Yahoo Programming Contest 2019
    Codeforces Round #538 (Div. 2) (CF1114)
    [BZOJ3625][Codeforces Round #250]小朋友和二叉树 多项式开根+求逆
    [BZOJ2341][Shoi2011]双倍回文 manacher+std::set
    [BZOJ4278] [ONTAK2015]Tasowanie 贪心+后缀数组
    [BZOJ3451] Tyvj1953 Normal 点分治+FFT
  • 原文地址:https://www.cnblogs.com/sxushy2016/p/14986718.html
Copyright © 2011-2022 走看看