[英]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]
。如果根据n和k在此数组上应用插入排序,时间复杂度是多少?
我对这个问题进行了很多研究,但无法在 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.