【アルゴリズムの基礎(1)】時間計算量とよく使われるソートアルゴリズムを理解する

1 時間計算量を理解する

1.1 時間計算量とは何ですか?

時間計算量は、アルゴリズムの実行時間を定性的に記述する関数です。ソフトウェア開発では、時間計算量は、開発者がプロ​​グラムの実行時間を見積もるのを容易にするために使用されます。通常、時間を表すためにアルゴリズムの演算単位の数が使用されます。ここで、デフォルトでは、CPU の各ユニットの実行には同じ時間がかかります。アルゴリズムの問​​題サイズを とするとn、演算単位の数はf(n)関数で表され、データサイズがn増加するにつれてアルゴリズムの実行時間の増加率とf(n)増加率は一定の関係を示し、これを漸近関数といいます。アルゴリズムの時間計算量。時間計算量と呼ばれ、 として示されますO(f(n)。ここで、n は命令セットの数を指します。

1.2 ビッグオーとは

ビッグオーはアルゴリズムの実行時間の上限を表すために使用されます. 最悪の場合の実行時間としても理解できます. データの量と順序はアルゴリズムの実行時間に大きな影響を与える.ここでは、特定の入力データが使用されるため、このアルゴリズムの実行時間は他のデータの計算時間よりも長くなります。

挿入ソートの時間計算量は であると言われますO(n^2)が、挿入ソートの時間計算量は入力データと大きな関係があります。入力データが完全に順序付けされている場合、挿入ソートの時間計算量は です。入力データが In の場合、挿入ソートの時間計算量は ですO(n)。順序が完全に逆の場合、時間計算量は であるO(n^2)ため、最悪の場合のO(n^2)時間計算量は、挿入ソートの時間計算量は であると言えますO(n^2)

クイックソートは でありO(nlogn)、最悪の場合のクイックソートの時間計算量はO(n^2)一般に なのでO(nlogn)ビッグ O の定義から厳密に言えば、クイックソートの時間計算量は O(n^2) であるはずですが、それでもクイック ソートの時間計算量は ですO(nlogn)。これは業界のデフォルト ルールです。

二分探索の時間計算量は、O(logn)データ サイズが 1 になるまで毎回半分になります。最終的に、n に等しい 2 の累乗を求めることと同じになり、これを 1 回で割ることと同じになりますlogn

マージ ソートの時間計算量はO(nlogn)、トップダウン マージの場合、データ スケールを n から 1 に分割したときの時間計算量は O(logn)、その後、連続的な上向きマージの時間計算量は 、全体の時間計算量は ですO(n)O(nlogn)

ツリーの走査複雑さは一般に でありO(n)nこれはツリー内のノードの数であり、選択ソートの時間計算量は です。O(n^2)対応する章で各データ構造とアルゴリズムの複雑さを徐々に分析していきます。時間計算量の解析と導出の詳細については、主定理を参照してください。

1.3 一般的な時間計算量

1.3.1 O(1): 一定の複雑さ
let n = 100;
1.3.2 O(logn): 対数複雑度
//二分查找非递归
var search = function (nums, target) {
    
    
  let left = 0,
    right = nums.length - 1;
  while (left <= right) {
    
    
    let mid = Math.floor((left + right) / 2);
    if (nums[mid] === target) {
    
    
      return mid;
    } else if (target < nums[mid]) {
    
    
      right = mid - 1;
    } else {
    
    
      left = mid + 1;
    }
  }
  return -1;
};
1.3.3 O(n): 線形時間計算量
for (let i = 1; i <= n; i++) {
    
    
  console.log(i);
}
1.3.4 O(n^2): 正方形 (ネストされたループ)
for (let i = 1; i <= n; i++) {
    
    
  for (let j = 1; j <= n; j++) {
    
    
    console.log(i);
  }
}
  
for (let i = 1; i <= n; i++) {
    
    
  for (let j = 1; j <= 30; j++) {
    
     //嵌套的第二层如果和n无关则不是O(n^2)
    console.log(i);
  }
}
1.3.5 O(2^n): 指数関数的な複雑さ
for (let i = 1; i <= Math.pow(2, n); i++) {
    
    
  console.log(i);
}
1.3.6 O(n!): 階乗
for (let i = 1; i <= factorial(n); i++) {
    
    
  console.log(i);
}

2 一般的な並べ替えアルゴリズム

2.1 選択範囲の並べ替え

アルゴリズムのステップ:

まず、ソートされていないシーケンス内の最小 (最大) 要素を見つけて、それをソートされたシーケンスの開始位置に格納します。

次に、ソートされていない残りの要素から最小 (最大) の要素を検索し、それをソートされたシーケンスの最後に置きます。

すべての要素が並べ替えられるまで、手順 2 を繰り返します。

選択ソートはシンプルで直観的なソート アルゴリズムであり、どのようなデータが入力されても、時間計算量は O(n²) です。したがって、使用する場合はデータサイズが小さいほど良いです。唯一の利点は、追加のメモリ領域を占有しないことです。

function selectSort(arr) {
    
    
    for (let i=0;i<arr.length-1;i++) {
    
    
        let min = i;
        for (let j=min+1;j<arr.length;j++) {
    
    
            if (arr[min] > arr[j]) {
    
    
                min = j;
            }
        }
        let temp = arr[i];
        arr[i] = arr[min]
        arr[min] = temp;
    }
    return arr;
}

2.2 バブルソート

隣接する要素を比較します。最初の値が 2 番目の値より大きい場合は、両方を交換します。

0 ~ n のループの最初のパスでは、最大値を見つけて先頭にバブルすることによって n の値が決定されます。

0-n-1 の 2 番目のループで n-1 の値が決定されます。

3 番目のパスは 0-n-2 をループして、n-2 の値を決定します。

function bubleSort(arr) {
    
    
    for (let i = 0;i<arr.length-1;i++) {
    
      // 循环轮次
        for (let j=0;j< arr.length-i-1;j++) {
    
     // 每轮比较次数
            if (arr[j] > arr[j+1]) {
    
     // 相邻比较
                let temp = arr[j]
                arr[j] = arr[j+1]
                arr[j+1] = temp
            }
        }
    }
    return arr;
}

2.3 挿入ソート

最初の 2 つの値がソートされます

2 番目のループは、最初の 3 つの値を並べ替え、最後の値と新しい値を比較して、指定された位置に挿入します。

ここに画像の説明を挿入します

ここに画像の説明を挿入します

function insertSort(arr) {
    
    
    for (let i = 1;i<arr.length;i++) {
    
      // 循环轮次
        let end = i;
        let curr = arr[i]
        while(end > 0 && curr < arr[end-1]) {
    
     // 直到第一位 或者 当前的数不是最小值
            arr[end] = arr[end - 1] // 移动比当前值小的值到后一位
            end--
        }
        arr[end] = curr // 插入当前值
    }
    return arr;
}

2.4 XOR演算

式の 1 ビットのみが 1 の場合に限り、結果は 1 になります。それ以外の場合、結果のビットは 0 になります。簡単に言うと、同じ場合は -----0、異なる場合は 1 になります。

構文: 結果 = 式 1 ^ 式 2
按位异或 是对两个表达式执行 按位异或,先将两个数据转化为二进制数,然后进行 按位异或运算,只要位不同结果为 1,否则结果为 0

例如:
let a = 5;
let b = 8;
let c = a ^ b;
console.log(c) // 13

解析:
a 转二进制数为:0101
b 转二进制数为:1000
那么按照 按位异或 运算之后得到:1101(相同为 0,不同为 1),得到 c 的值就是 13
特徴

1. 為替レートを守る

a ^ b == b ^ a

2. 2 つの同一の数値の XOR 演算の結果は 0 でなければなりません

a^a === 0

3. 其他数字0 と XOR 演算によって得られる結果は、其他数字

0^a === a

2.5 演習

1. 空ではない整数配列を指定すると、1 回だけ出現する 1 つの要素を除いて、各要素が 2 回出現します。1 回だけ出現する要素を見つける

let arr = [1, 3, 1, 2, 2, 7, 3, 6, 7]

// es5 解决方案
function fnc(arr){
    
    
    let result = 0;
    for(let i = 0; i < arr.length; i++){
    
    
        result  = result ^ arr[i];
    }
    return result;
}

// es6 解决方案
function fnc(arr){
    
    
    return arr.reduce((a, b) => a ^ b, 0);
}

おすすめ

転載: blog.csdn.net/sinat_29843547/article/details/128617361
おすすめ