我正在尝试了解算法的时间复杂度。我的教授已将它推到了Big O之外,并希望我们能够将算法推导出数学函数。我很难概念化这是如何完成的,并且正在寻求帮助。在我的课堂笔记中,提供了一种选择排序算法(如下面的代码所示)。这些注释提出了以下问题:"导出函数f(n),该函数对应于在最坏的情况下修改 minIndex或任何nums位置的总次数。 现在笔记告诉我答案是 f(n)= 1 / 2n ^ 2 + 5 / 2n + 3 。我想知道是否有人能解释这是怎么发生的。
我的教授告诉我们要计算内循环中的操作并努力解决问题。所以我相信在最坏的情况下,在内部循环中if语句总是执行,这意味着我们运行循环ni-1次,我通过取n(for循环必须小于的边界并减去)得到这些值它由起始条件(i + 1)。然后我看外环,我看到它从i到达n-1,所以它可以写成(n-1)-i或就像内部循环,ni-1。进一步看,外循环有三个修改,所以得到(ni-1)+3(我可以把它写成(n-i + 2)吗?
内循环最坏情况下的修改次数: N-1-1
外循环最坏情况下的修改次数: (N-1-1)3
现在我想知道你如何计算完成的两个不同的修改并成为f(n)= 1 / 2n ^ 2 + 5 / 2n + 3.
public static void selectionSort(int[] nums) {
int n = nums.length;
int minIndex;
for(int i = 0; i < n-1; i++) {
//find the index of themin number.
minIndex = i;
for(int j = i+1; j < n; j++) {
if(nums[j] < nums[minIndex]) {
minIndex = j;
}
int temp = nums[i];
nums[i] = nums[minIndex];
nums[minIndex] = temp;
}
}
}
答案 0 :(得分:0)
外循环运行多少次?
n - 1
次。
对于外循环的每次迭代,内循环运行了多少次?
从n - 1
次到1
次,随着外循环的进展,平均来说:
((n - 1) + 1) / 2
= n / 2
次。
那么,内循环在总计中运行多少次?
(n - 1) * (n / 2)
= n^2 / 2 - n / 2
次。
minIndex
修改了多少次?
每个外环一次+每个内环一次:
(n - 1) + (n^2 / 2 - n / 2)
= n^2 / 2 + n / 2 - 1
次。
nums
修改的位置的次数是多少?
每个内循环两次:
2 * (n^2 / 2 - n / 2)
= n^2 - n
次。
总数 修改的数量是什么?
(n^2 / 2 + n / 2 - 1) + (n^2 - n)
= (3*n^2 - n) / 2 - 1
次
或1½n² - ½n - 1
这和你说的笔记不一样,所以我们来证明一下。
首先,我们添加调试打印,即打印任何修改,包括修改编号。
public static void selectionSort(int[] nums) {
int mod = 0;
int n = nums.length;
int minIndex;
for(int i = 0; i < n-1; i++) {
//find the index of themin number.
minIndex = i; System.out.printf("%2d: minIndex = %d%n", ++mod, i);
for(int j = i+1; j < n; j++) {
if(nums[j] < nums[minIndex]) {
minIndex = j; System.out.printf("%2d: minIndex = %d%n", ++mod, j);
}
int temp = nums[i];
nums[i] = nums[minIndex]; System.out.printf("%2d: nums[%d] = %d%n", ++mod, i, nums[minIndex]);
nums[minIndex] = temp; System.out.printf("%2d: nums[%d] = %d%n", ++mod, minIndex, temp);
}
}
}
最坏的情况是对降序数字进行排序,所以让我们尝试3个数字:
int[] nums = { 3, 2, 1 };
selectionSort(nums);
System.out.println(Arrays.toString(nums));
我们希望(3*n^2 - n) / 2 - 1
= (3*3^2 - 3) / 2 - 1
= 24 / 2 - 1
= 11
次修改。
1: minIndex = 0
2: minIndex = 1
3: nums[0] = 2
4: nums[1] = 3
5: minIndex = 2
6: nums[0] = 1
7: nums[2] = 2
8: minIndex = 1
9: minIndex = 2
10: nums[1] = 2
11: nums[2] = 3
[1, 2, 3]
是的,11次修改。
让我们试试9:
int[] nums = { 9, 8, 7, 6, 5, 4, 3, 2, 1 };
(3*n^2 - n) / 2 - 1
= (3*9^2 - 9) / 2 - 1
= 234 / 2 - 1
= 116
次修改。
1: minIndex = 0
2: minIndex = 1
3: nums[0] = 8
4: nums[1] = 9
5: minIndex = 2
6: nums[0] = 7
. . .
111: nums[6] = 7
112: nums[8] = 8
113: minIndex = 7
114: minIndex = 8
115: nums[7] = 8
116: nums[8] = 9
[1, 2, 3, 4, 5, 6, 7, 8, 9]
是的,116修改。
通过经验证据验证的公式:
的 f(n) = (3*n^2 - n) / 2 - 1
强>