選擇排序法 Selection Sort

  • 8742
  • 0
  • C++
  • 2016-01-10

選擇排序法(Selection Sort)是排序演算法的一種,其觀念是將資料分成"已排序"和"未排序"兩個部分,並且依照順序從"未排序"中尋找最大(最小)值,加入到"已排序"資料的最後端。一直執行到排序結束也就是"未排序"資料為空的時候。

本文以C++實作執行。

選擇排序法實際執行狀況如下(假設需要將資料由小排到大):

將"已排序"的資料擺在資料序列的前端,並且將"未排序"的資料擺在資料序列的後端。(如果沒有已排序的資料,則全部的資料視為未排序)

假設要將n筆資料由小排到大,一開始的時候的n筆資料是"未排序"的。這個時候就將n筆"未排序"的資料中取出最小值,並且將其放到"已排序"資料的最後端,也就是說將其和第一筆資料進行交換。

接下來在從n-1筆"未排序"的資料中取出最小值,一樣的放入到"已排序"的資料的最後端(和第2筆資料進行交換,因為弟1筆資料是已排序的第一筆資料,而第2筆資料是目前未排序資料當中的第一筆);再從剩下的n-2筆"未排序"資料取出最大值,加入到"已排序"資料的最後端(與第三筆資料進行交換)

依此類推,一直到沒有任何"未排序"的資料時停止。

範例:排序 3 7 1 2 9 4 

3 7 1 2 9 4 (已排序: 未排序:3 7 1 2 9 4  行為:發現1為未排序中最小值,將1和3交換)
1 7 3 2 9 4 (已排序: 1未排序:7 3 2 9 4  行為:發現2為未排序中最小值將2和7交換)
1 2 3 7 9 4 (已排序:1 2  未排序:3 7 9 4 行為:發現3為未排序中最小值,但也剛好在已排序資料的後端,故將其加入到已排序)
1 2 3 7 9 4 (已排序:1 2 3  未排序:7 9 4  行為:發現4為未排序中最小值,將4和7交換)
1 2 3 4 9 7 (已排序:1 2 3 4  未排序:9 7 行為:發現7為未排序中最小值,將7和9交換)
1 2 3 4 7 9 (已排序:1 2 3 4 7未排序:9 行為:發現9為未排序中最小值,但也剛好在已排序資料的後端,故將其加入到已排序)
1 2 3 4 7 9(已排序:1 2 3 4 7 9  未排序: 行為:)

時間複雜度如下:

最佳時間複雜度:O(n^2) 

平均時間複雜度:O(n^2)

最差時間複雜度:O(n^2)

說明:無論資料順序如何,都會執行兩個迴圈。

PseudoCode 大致如下:


template < typename T > //整數或浮點數皆可使用

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

void swap(int array_1, int array_2)
{
	int temp = 0;

	temp = array_1;
	array_1 = array_2;
	array_2 = temp;
}

完整程式碼如下: 本次以 "Pass by reference"的方式實作

#include <iostream>
#include <iomanip>
using namespace std;

void selectionSort(int*const, const int);
void swap(int *const,int*const);

int main() {
	int size = 0;
	int *ptr;

	cout << "請輸入陣列空間:" << endl;
	cin >> size;

	ptr = new int[size];//動態記憶體配置陣列

	cout << "請輸入陣列資料:";

	for (int i = 0; i < size; i++)
	{
		cin >> ptr[i];// ptr[i]等價於 *(ptr+i)
	}

	cout << "原本的陣列資料:" << endl;

	for (int i = 0; i < size; i++)
	{
		cout<< ptr[i]<<" ";// ptr[i]等價於 *(ptr+i)
	}

	cout << endl;

	selectionSort(ptr,size);

	cout << "排序後的資料:" << endl;

	for (int i = 0; i < size; i++)
	{
		cout << ptr[i]<<" ";// ptr[i]等價於 *(ptr+i)
	}

	cout << endl;


	system("pause");
	return 0;
}

void selectionSort(int*const array, const int arraysize)
{
	int smallest = 0;//宣告未排序序列中最小值

	for (int i = 0 ;i <arraysize;i++)
	{
		smallest = i;

		for (int j = i + 1; j < arraysize;j++)
		{
			if (array[j] < array[smallest])
			{
				smallest = j;//尋找未排序序列中最小值
			}
		}

		swap(&array[i],&array[smallest]);//將未排序序列中的最小值加入到已排序序列中的最後端
	}

}
void swap(int *const array_1, int*const array_2)
{
	int temp = 0;

	temp = *array_1;
	*array_1 = *array_2;
	*array_2 = temp;
}

執行結果如下:

有夢最美 築夢踏實

活在當下 認真過每一天

我是阿夢 也是Ace