选择排序

维基百科,自由的百科全书
跳转至: 导航搜索
选择排序
選擇排序動畫演示
分類 排序算法
數據結構 數組
最差時間複雜度 О(n²)
最優時間複雜度 О(n²)
平均時間複雜度 О(n²)
最差空間複雜度 О(n) total, O(1) auxiliary

选择排序(Selection sort)是一种简单直观的排序算法。它的工作原理如下。首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。

选择排序的主要优点与数据移动有关。如果某个元素位于正确的最终位置上,则它不会被移动。选择排序每次交换一对元素,它们当中至少有一个将被移到其最终位置上,因此对n个元素的表进行排序总共进行至多n-1次交换。在所有的完全依靠交换去移动元素的排序方法中,选择排序属于非常好的一种。

C语言实现[编辑]

void selection_sort(int arr[], int len) {
	int i, j, min, temp;
	for (i = 0; i < len - 1; i++) {
		min = i;
		for (j = i + 1; j < len; j++)
			if (arr[min] > arr[j])
				min = j;
		if (min != i) {
			temp = arr[min];
			arr[min] = arr[i];
			arr[i] = temp;
		}
	}
}

C++实现[编辑]

template<typename T> //整數或浮點數皆可使用,若要使用物件(class)時必須設定大於(>)的運算子功能
void selection_sort(T arr[], int len) {
	int i, j, min;
	T temp;
	for (i = 0; i < len - 1; i++) {
		min = i;
		for (j = i + 1; j < len; j++)
			if (arr[min] > arr[j])
				min = j;
		if (min != i) {
			temp = arr[min];
			arr[min] = arr[i];
			arr[i] = temp;
		}
	}
}

C#语言实现[编辑]

static void selection_sort<T>(T[] arr) where T : System.IComparable<T>{//整數或浮點數皆可使用
	int i, j, min, len = arr.Length;
	T temp;
	for (i = 0; i < len - 1; i++) {
		min = i;
		for (j = i + 1; j < len; j++)
			if (arr[min].CompareTo(arr[j]) > 0)
				min = j;
		if (min != i) {
			temp = arr[min];
			arr[min] = arr[i];
			arr[i] = temp;
		}
	}
}

Python语言实现[编辑]

def selection_sort(L):
    N = len(L)
    exchanges_count = 0
    for i in range(N-1):
        min_index = i
        for j in range(i+1, N):
            if L[min_index] > L[j]:
                min_index = j
        if min_index != i:
            L[min_index], L[i] = L[i], L[min_index]
            exchanges_count += 1
        print('iteration #{}: {}'.format(i, L))
    print('Total {} swappings'.format(exchanges_count))
    return L
 
testlist = [17, 23, 20, 14, 12, 25, 1, 20, 81, 14, 11, 12]
print('Before selection sort: {}'.format(testlist))
print('After selection sort:  {}'.format(selection_sort(testlist)))

Java语言实现[编辑]

public void selectSort(Comparable[] array) {
		System.out.println("===========Insert Sort Started===========");
		Comparable temp;
		//min存放最小元素的index
		int min;
		for (int index = 0; index < array.length - 1; index++) {
			//假定第一个元素为最小元素
			min = index;
			//循环遍历元素,每遍历一个元素,与当前最小元素比较,若此元素比当前最小元素小,则将此元素置为最小元素
			for (int time = index + 1; time < array.length; time++) {
				if (array[time].compareTo(array[min]) < 0) {
					min = time;
				}
			}
			//遍历一遍,找到一个最小元素,把此最小元素的index与min交换位置
			temp = array[index];
			array[index] = array[min];
			array[min] = temp;
		}
		System.out.println("The array after sorted....");
		System.out.println(Arrays.toString(array));
		System.out.println("============Insert Sort Ended============");
	}

复杂度分析[编辑]

选择排序的交换操作介于0(n-1)次之间。选择排序的比较操作n(n-1)/2次之间。选择排序的赋值操作介于03(n-1)次之间。


比较次数O(n^2),比较次数与关键字的初始状态无关,总的比较次数N=(n-1)+(n-2)+...+1=n\times(n-1)/2。交换次数O(n),最好情况是,已经有序,交换0次;最坏情况是,逆序,交换n-1次。交换次数比冒泡排序较少,由于交换所需CPU时间比比较所需的CPU时间多,n值较小时,选择排序比冒泡排序快。

原地操作几乎是选择排序的唯一优点,当方度(space complexity)要求较高时,可以考虑选择排序;实际适用的场合非常罕见。

外部链接[编辑]