全面解析十大排序算法之二:选择排序
1. 十种排序算法的复杂度和稳定性
时间复杂度:一个算法消耗所需要的时间
空间复杂度:运行一个算法所需要的内存时间
稳定性:如一个排列数组:1、4、5、6、4、7. 此时有一对相等的数字 4 ,设前面的4为 a4,后一个4 为 b4。 如果排序之后 a4 仍然在 b4 前面,则表示此种算法排序是具有稳定性的;如果排序之后 a4 在 b4 后面,则表示是 不稳定性的。
2. 什么是选择排序
选择排序(Selection sort)是一种简单直观的排序算法,通过找到数组中最小的值(或者最大的值),保存它的索引值,然后将最小值放在最前面(或者最后面)。它也是一种交换排序算法,和冒泡排序有一定的相似度,可以认为选择排序是冒泡排序的一种改进。
3. 算法运行过程
算法运行过程视频演示
冒泡排序算法的运作如下:
(1) 首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,
(2) 再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。
(3) 以此类推,直到所有元素均排序完毕。
选择排序实现比较简单,由于在数组各种情况下复杂度波动小,因此一般是优于冒泡排序的。在所有的完全交换排序中,选择排序也是比较不错的一种算法。但是,由于固有的O(n^2)复杂度,选择排序在海量数据面前显得力不从心。因此,它适用于简单数据排序。
4. 代码实现
Python实现
#将最小的数放在前面
def selection_sort1(alist):
n = len(alist)
for i in range(n-1): #需要进行 n-1次的操作
min_index = i
for j in range(i+1, n): #从 i+1 开始遍历, 前面几项是已经排序好的
if alist[j] < alist[min_index]: #找出最小的数据
min_index = j
if min_index != i: #将数据进行交换
alist[i], alist[min_index] = alist[min_index], alist[i]
return alist
print(selection_sort1(li)) # [1, 11, 11, 12, 23, 24, 45, 47, 56, 89]
#将最大的数放在后面
def selection_sort2(alist): #将最大的数放在后面
n = len(alist)
for i in range(n-1, 0, -1):
max_index = i
for j in range(i-1, 0, -1):
if alist[j] > alist[max_index]:
max_index = j
if max_index != i:
alist[i], alist[max_index] = alist[max_index], alist[i]
return alist
print(selection_sort2(li))
Java实现
public class SelectSort {
public static int[] selectSort(int[] a) {
int n = a.length;
for (int i = 0; i < n - 1; i++) {
int min = i;
for (int j = i + 1; j < n; j++) {
if(a[min] > a[j]) min = j;
}
//交换
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
return a;
}
}
C++实现
using namespace std;
void swap(int &a, int &b) {
int tmp = a;
a = b;
b = tmp;
}
void selectSort(int a[], int len) {
for (int i = 0; i < len - 1; ++i) {
int minIndex = i;
for (int j = i; j < len; ++j) {//找出无序区最小元素的下标
if (a[j] < a[minIndex]) {
minIndex = j;
}
}
swap(a[i], a[minIndex]);//无序区第一个元素与最小值交换。
}
}
冒泡算法代码优化
冒泡排序每次需要遍历 非有序区域 一遍,找出最小值。那如果每次都要遍历的话,不如直接找到每次遍历的最小值、最大值,然后将每次遍历得到的最小值放在 头部有序区 的尾部,将最大值放在 尾部有序区 的头部。(有点绕)这样子就可以减少遍历的次数了。
当最小元素的位置+1 = 最大元素的位置时,表示数据已经全部有序。
Python实现
def selection_sort2(data_list):
length = len(data_list)
for i in range(length -1):
min_index = i #存储最小值的下标
max_index = length - i -1 #最大值的索引值
for j in range(i+1,length - i -1):
if data_list[min_index] > data_list[j]:
min_index = j #找出最小的值的索引
if data_list[max_index] < data_list[j]:
max_index = j
#退出条件
if min_index +1 == max_index:
break
#前面的数据与最小值交换
if min_index != i: #说明需要交换,否则不需要自己自己交换
data_list[i], data_list[min_index] =
data_list[min_index], data_list[i]
#后面的数据与最大值交换
if max_index != length - i -1:
data_list[length -i -1 ], data_list[max_index] =
data_list[max_index], data_list[length-i-1]
return data_list
END
免费分享程序员面经、机器学习、编程语言等,
1300G互联网视频、书籍资源,各种干货。
生活不止于编程,爱编程更爱生活。
文章好看点这里