简体   繁体   English

k-shifted数组插入排序的时间复杂度

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

This problem was asked in my algorithm course homework.这个问题在我的算法课程作业中被问到。

You have an n sized, sorted array at first.您首先有一个n大小的排序数组。 Lets say n=10 and the array is [1,2,3,4,5,6,7,8,9,10] .假设n=10并且数组是[1,2,3,4,5,6,7,8,9,10] Then it is circularly shifted to the right by k .然后循环右移k Lets say k=3 .让我们说k=3 Now the array is [8,9,10,1,2,3,4,5,6,7] .现在数组是[8,9,10,1,2,3,4,5,6,7]

What is the time complexity if you apply insertion sort on this array, depending on n and k ?如果根据nk在此数组上应用插入排序,时间复杂度是多少?

I researched this question a lot, but couldn't find a solution on the inte.net.我对这个问题进行了很多研究,但无法在 inte.net 上找到解决方案。 How to determine the time complexity of insertion sort on such shifted array?如何确定这种移位数组上插入排序的时间复杂度?

First of all, the insertion sort:首先是插入排序:

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;
    }
}

The time complexity mostly depends on the following lines because that's where comparing and swapping operations are done.时间复杂度主要取决于以下几行,因为这是完成比较和交换操作的地方。

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

Take a paper, draw a swap table for each j value.拿一张纸,为每个 j 值绘制一个交换表。

在此处输入图像描述

Eventually, you will understand that the algorithm gets into while loop (nk) times, and whenever it gets in, it does swap operation k times.最终,你会明白算法进入 while 循环(nk)次,每当进入时,它都会进行k次交换操作。 So, time complexity is (nk)*k .所以,时间复杂度是(nk)*k

Lets prove it.让我们证明一下。

Put a swap counter variable to the algorithm.将交换计数器变量放入算法中。

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;
}

Now, lets try it on our array described in the question.现在,让我们在问题中描述的数组上尝试一下。

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;
        }
    }
}

The output: output:

Theoritical Time Complexity based on formula: 21 - Swap Count: 21 - Is formula correct:true基于公式的理论时间复杂度:21 - 交换计数:21 - 公式是否正确:真

I've tried on array sized 2^16 and shifted it 2^16-1 times, each time the formula was correct.我试过大小为 2^16 的数组并将其移动 2^16-1 次,每次公式都是正确的。

The time complexity we found is not an upper bound or lower bound, it is the exact tight bound for this case.我们发现的时间复杂度不是上限或下限,它是这种情况的严格限制。 Therefore it is Theta.因此是Theta。 Θ((nk)k) . Θ((nk)k)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM