一、前言
简单选择排序是一种选择排序。
选择排序:每趟从待排序的记录中选出关键字最小的记录,顺序放在已排序的记录序列末尾,直到全部排序结束为止。
二、算法思想
简单排序很简单,它的大致处理流程为:
- 从待排序序列中,找到关键字最小的元素;
- 如果最小元素不是待排序序列的第一个元素,将其和第一个元素互换;
- 从余下的 N - 1 个元素中,找出关键字最小的元素,重复(1)、(2)步,直到排序结束。
动态效果示意图:
举例说明,处理过程示意图如下所示:
如图所示,每趟排序中,将当前第 i 小的元素放在位置 i 上。
1、代码
Java:
package test;
/**
* 1.原理:每一趟从待排序的记录中选出最小的元素,顺序放在已排好序的序列最后,直到全部记录排序完毕。
* 也就是:每一趟在n-i+1(i=1,2,…n-1)个记录中选取关键字最小的记录作为有序序列中第i个记录。
* 基于此思想的算法主要有简单选择排序、树型选择排序和堆排序。(这里只介绍常用的简单选择排序)
* 2.简单选择排序的基本思想:给定数组:int[] arr={里面n个数据};
* 第1趟排序,在待排序数据arr[1]~arr[n]中选出最小的数据,将它与arrr[1]交换;
* 第2趟,在待排序数据arr[2]~arr[n]中选出最小的数据,将它与r[2]交换;
* 以此类推,第i趟在待排序数据arr[i]~arr[n]中选出最小的数据,将它与r[i]交换,直到全部排序完成。
*
* 以上为了好理解,从下标1解释的,写的代码是从0开始的。
* @author 高小硕
* @version 创建时间:2018年5月12日 下午20:01:55
*/
public class SelectSort {
public static void main(String[] args) {
int[] arr = {9, 1, 2, 5, 7, 4, 8, 6, 3, 5};
//排序前
System.out.println("排序前:");
for(int num:arr)
{
System.out.print(num+" ");
}
//选择排序
selectSort(arr);
//排序后
System.out.println();
System.out.println("排序后:");
for(int num:arr)
{
System.out.print(num+" ");
}
}
//核心代码
public static void selectSort(int[] arr) {
// 要注意一点,当要排序 N 个数,已经经过 N-1 次遍历后,已经是有序数列
for(int i=0;i<arr.length-1;i++)
{
//存储最小元素的索引
int min_index = i;
//进行元素值的大小比较,获得本轮中最小元素的索引(即下标)
for(int j=i+1;j<arr.length;j++)
{
if(arr[j]<arr[min_index])
min_index = j;//小的索引存在min_index里
}
//在内层循环结束,也就是找到本轮循环的最小的数以后,再进行交换
if(min_index!=i)
{ //交换
int temp=arr[i];
arr[i] = arr[min_index];
arr[min_index] = temp;
}
}
}
}
排序前:
9 1 2 5 7 4 8 6 3 5排序后:
1 2 3 4 5 5 6 7 8 9
Python:
def SelectSort(input_list):
'''
函数说明:简单选择排序(升序)
Author:
高硕
Parameters:
input_list - 待排序列表
min_index - 临时保存最小元素的索引
temp - 交换辅助
'''
if len(input_list) == 0:
return []
length = len(input_list)
# 外层循环,控制循环的趟数
for i in range(length-1):
# 存储最小元素的索引
min_index = i
# 进行大小比较,获取最小元素的下标
for j in range(i + 1, length):
if input_list[min_index] > input_list[j]:
min_index = j
# 一轮大小比较完毕,现在获得了本轮中最小元素的索引(即下标)
#在内层循环结束,也就是找到本轮循环的最小的数以后,再进行交换
if(i!=min_index):
temp = input_list[i]
input_list[i] = input_list[min_index]
input_list[min_index] = temp
# 输出每一趟的排序结果
print('第%d趟的排序结果:' % (i + 1), input_list)
return input_list
if __name__ == '__main__':
input_list = [9, 1, 2, 5, 7, 4, 8, 6, 3, 5]
print('排序前:', input_list)
sorted_list = SelectSort(input_list)
print('排序后:', sorted_list)
图解算法书上代码:
def findSmalllest(arr):
smallest = arr[0]
smallest_index = 0
for i in range(1,len(arr)):
if arr[i]<smallest:
smallest = arr[i]
smallest_index = i
return smallest_index
def selectionSort(arr):
newArr = []
for i in range(len(arr)):
smallest = findSmalllest(arr)
newArr.append(arr.pop(smallest))#在新数组的末尾直接添加,不需元素间交换位置了
return newArr
print(selectionSort([5,3,6,2,10]))
三、算法分析
1、简单算法排序性能
其中,N2为N^2。
2、时间复杂度
简单选择排序的比较次数与序列的初始排序无关。 假设待排序的序列有 N 个元素,则比较次数总是N (N - 1) / 2。
而移动次数与序列的初始排序有关。当序列正序时,移动次数最少,为 0.
当序列反序时,移动次数最多,为3N (N - 1) / 2。
所以,综合以上,简单排序的时间复杂度为 O(N^2)。
3、空间复杂度
O(1)
四、小结
计算机内存犹如一大堆抽屉。
需要存储多个元素时,可使用数组或链表。
数组的元素都在一起。
链表的元素是分开的,其中每个元素都存储了下一个元素的地址。
数组的读取速度很快。
链表的插入和删除速度很快。
在同一个数组中,所有元素的类型都必须相同(都为int、double等)。
内容整合自算法图解和一些博客。