一、选择排序
选择排序是一种简单直观的排序算法,它的基本思想是在待排序的列表中,每次从未排序部分选择最小(或最大)的元素,将其放在已排序部分的末尾。
Python代码实现:
def selection_sort(arr):
n = len(arr)
for i in range(n-1):
min_index = i
for j in range(i+1, n):
if arr[j] < arr[min_index]:
min_index = j
arr[i], arr[min_index] = arr[min_index], arr[i]
代码详细解析:
1.定义了一个名为 selection_sort 的函数,它接受一个列表 arr 作为参数,用于进行排序操作。
2.获取列表的长度 n,这将用于控制外层循环的迭代次数。
3.外层循环 for i in range(n-1) 控制排序的轮数,每轮从未排序部分选择最小(或最大)元素,并将其放置在已排序部分的末尾。
4.内层循环 for j in range(i+1, n) 依次遍历未排序部分的元素,从中找到最小(或最大)的元素。
5.在内层循环中,使用条件语句 if arr[j] < arr[min_index] 来比较当前元素和已记录的最小元素。如果当前元素更小,更新最小元素的索引 min_index。
6.内层循环结束后,已经找到未排序部分的最小(或最大)元素。
7.使用多重赋值的方式 arr[i], arr[min_index] = arr[min_index], arr[i] 将最小(或最大)元素与已排序部分的末尾元素交换位置。
8.外层循环会继续进行迭代,每轮迭代会找到一个最小(或最大)元素放置在已排序部分的末尾,直到所有元素都有序排列。
时间复杂度分析:
当 i = 0 的时候,j 从 1 到 n-1,内层循环执行次数为 n-1 次;
当 i = 1 的时候,j 从 2 到 n-1,内层循环执行次数为 n-2 次;
当 i = n-2 的时候,j 从 n-1 到 n-1,内层循环执行次数为 1 次;
所以总的执行次数就是 (1 + (n-1)) * (n-1) / 2 = n * (n - 1) / 2;
所以时间复杂度就是 O(n^2)。
选择排序的时间复杂度为 O(n^2),其中 n 是列表的长度。尽管选择排序的性能比冒泡排序好一些,但仍然不适用于大规模数据的排序。
算法优化
选择排序的基本思想是每次从未排序部分选择最小(或最大)的元素,并将其放在已排序部分的末尾。虽然选择排序的时间复杂度始终为 O(n^2),但可以进行一些优化来减少比较和交换的次数。下面简单介绍两种常见的选择排序优化方法:
1.最小/最大元素同时查找:传统的选择排序每轮内循环都会分别找出最小或最大的元素索引,然后进行交换。优化的方法是同时查找最小和最大元素的索引,然后将它们分别放置在已排序部分的开头和末尾。这样可以减少了每轮内循环的比较次数和交换次数。
def optimized_selection_sort(arr):
n = len(arr)
start = 0
end = n - 1
while start < end:
min_index = start
max_index = end
for i in range(start, end + 1):
if arr[i] < arr[min_index]:
min_index = i
if arr[i] > arr[max_index]:
max_index = i
arr[start], arr[min_index] = arr[min_index], arr[start]
if max_index == start: # 如果最大元素的索引是已排序部分的开头,交换后需要更新最大元素的索引
max_index = min_index
arr[end], arr[max_index] = arr[max_index], arr[end]
start += 1
end -= 1
2.提前终止内循环:在每次内循环中,通过设置一个标志位来判断是否有进行过交换。如果某轮内循环没有发生交换,说明列表已经是有序的,可以提前终止排序。这样可以减少不必要的比较和交换次数。
def early_termination_selection_sort(arr):
n = len(arr)
for i in range(n-1):
min_index = i
is_sorted = True
for j in range(i+1, n):
if arr[j] < arr[min_index]:
min_index = j
is_sorted = False
if is_sorted:
break
arr[i], arr[min_index] = arr[min_index], arr[i]
以上两种优化方法可以在一定程度上提高选择排序的性能。尽管选择排序仍然不是最但这些优化措施可以减少比较和交换次数,从而改进算法的效率。