簡體   English   中英

k-shifted數組插入排序的時間復雜度

[英]Time complexity of insertion sort on k-shifted array

這個問題在我的算法課程作業中被問到。

您首先有一個n大小的排序數組。 假設n=10並且數組是[1,2,3,4,5,6,7,8,9,10] 然后循環右移k 讓我們說k=3 現在數組是[8,9,10,1,2,3,4,5,6,7]

如果根據nk在此數組上應用插入排序,時間復雜度是多少?

我對這個問題進行了很多研究,但無法在 inte.net 上找到解決方案。 如何確定這種移位數組上插入排序的時間復雜度?

首先是插入排序:

static void insertionSort(int[] array) {
    for (int i = 1; i < array.length; i++) {
        int key = array[i];
        int j = i - 1;

        while (j >= 0 && array[j] > key) {
            array[j + 1] = array[j];
            j--;           
        }

        array[j + 1] = key;
    }
}

時間復雜度主要取決於以下幾行,因為這是完成比較和交換操作的地方。

while (j >= 0 && array[j] > key) {
    array[j + 1] = array[j];
    j--;
}

拿一張紙,為每個 j 值繪制一個交換表。

在此處輸入圖像描述

最終,你會明白算法進入 while 循環(nk)次,每當進入時,它都會進行k次交換操作。 所以,時間復雜度是(nk)*k

讓我們證明一下。

將交換計數器變量放入算法中。

static int insertionSort(int[] array) {
    int swapCount = 0;

    for (int i = 1; i < array.length; i++) {
        int key = array[i];
        int j = i - 1;
        while (j >= 0 && array[j] > key) {
            array[j + 1] = array[j];
            j--;
            swapCount++;
        }

        array[j + 1] = key;
    }

    return swapCount;
}

現在,讓我們在問題中描述的數組上嘗試一下。

public class App {
    public static void main(String[] args) throws Exception {
        int[] baseArray = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

        int n = baseArray.length;
        int k = 3;

        // Shift base array by k
        int[] shiftedArray = shiftArray(baseArray, k);

        // Calculate how many swaps done by the insertion sort
        int swapCount = InsertionSort.insertionSort(shiftedArray);

        // Theroitical value is calculated by using the formula (n-k)*k
        int timeComplexityTheoritical = (n - k) * k;

        System.out.print("Theoritical Time Complexity based on formula: " + timeComplexityTheoritical);

        System.out.print(" - Swap Count: " + swapCount);

        System.out.print(" - Is formula correct:" + (timeComplexityTheoritical == swapCount) + "\n");
    }

    // Shift array to the right circularly by k positions
    static int[] shiftArray(int[] array, int k) {
        int[] resultArray = array.clone();

        int temp, previous;
        for (int i = 0; i < k; i++) {
            previous = resultArray[array.length - 1];
            for (int j = 0; j < resultArray.length; j++) {
                temp = resultArray[j];
                resultArray[j] = previous;
                previous = temp;
            }
        }

        return resultArray;
    }

    static class InsertionSort {

        static int insertionSort(int[] array) {
            int swapCount = 0;

            for (int i = 1; i < array.length; i++) {
                int key = array[i];
                int j = i - 1;
                while (j >= 0 && array[j] > key) {
                    array[j + 1] = array[j];
                    j--;
                    swapCount++;
                }

                array[j + 1] = key;
            }

            return swapCount;
        }
    }
}

output:

基於公式的理論時間復雜度:21 - 交換計數:21 - 公式是否正確:真

我試過大小為 2^16 的數組並將其移動 2^16-1 次,每次公式都是正確的。

我們發現的時間復雜度不是上限或下限,它是這種情況的嚴格限制。 因此是Theta。 Θ((nk)k)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM