题目
考虑对数组A中的n个数的排序问题:首先找出A中的最小元素,并将其与A[1]中的元素交换;接着,找出A中的次小元素,并将其与A[2]中的元素进行交换。对A中头n-1个元素继续这一过程。写出这个算法的伪代码,这个算法称为选择排序(selection sort)。对于这个算法来说,循环不变式是什么?为什么它仅需要在头n-1个元素上运行,而不是在所有n个元素上运行?以
形式写出选择排序的最佳运行时间和最坏运行时间。
分析
根据题意,程序需要两个循环,外循环使用变量i遍历A[1...n-1],内循环找到A[i+1...n]中的最小值;然后在外循环中将最小值与A[i]交换。所以除i外还需要变量j遍历A[i+1...n],变量index指示A[i+1...n]中的最小值的位置。
伪代码
SELECTION-SORT(A) | cost | time |
---|---|---|
1 n = length(A) | c1 | 1 |
2 for i <- 1 to n-1 | c2 | n-1 |
3 do index <- i | c3 | n-2 |
4 for j <- i+1 to n | c4 | |
5 do if A[j] < A[index] | c5 | |
6 then index <- j | c6 | |
7 exchange A[i] <-> A[index] | c7 | n-2 |
SELECTION_SORT(A)
1 n = length(A)
2 for i <- 1 to n-1
3 do index <- i
4 for j <- i+1 to n
5 do if A[j] < A[index]
6 then index <- j
7 exchange A[i] <-> A[index]
循环不变式和比较n-1次的原因
在外循环的每次迭代开始前,子数组A[1...i-1]保存A中最小的i-1个数,并且是已经排序好的;子数组A[i...n]是A中剩余的未排序元素。
从循环不变式中可知,当循环结束时,即i=n时,A[1...n-1]中是排序好的A中最小的n-1个数,所以剩下的A[n]必然是A中最大的元素,所以不用再比较了。
最佳运行时间和最坏运行时间
程序运行时各部分运行的次数分析如伪代码所示。
所以,最佳情况下,ti=0,T(n)=
最坏情况下,ti=1,T(n)=
代码
def selection_sort(a):
n = len(a)
for i in range(0, n-1):
index = i
for j in range(i+1, n):
if a[j] < a[index]:
index = j
temp = a[i]
a[i] = a[index]
a[index] = temp