1. 程式人生 > 實用技巧 >用選擇法對10個整數排序

用選擇法對10個整數排序

用選擇法對10個整數排序

【答案解析】

選擇排序原理:

總共兩個迴圈,外迴圈控制選擇的趟數,內迴圈控制具體選擇的方式。

用maxPos標記區間中首元素位置,然後用後序元素依次與maxPos標記的元素進行比較,如果有元素大於maxPos位置的元素,用maxPos標記該元素的位置,直到區間的末尾。

該趟選擇完成後,即找到該區間中最大元素,如果maxPos標記的最大元素不在區間末尾,用maxPos位置元素與區間末尾的元素進行交換。

繼續新一趟選擇,直到區間中剩餘一個元素

【程式碼實現】

#include<stdio.h>
int main()
{
	int array[] = {2,8,3,9,5,7,1,4,0,6};
	int size = sizeof(array) / sizeof(array[0]);
	// 輸出原陣列
	printf("排序前陣列中資料為:");
	for (int i = 0; i < size; ++i)
		printf("%d ", array[i]);
	printf("\n");

	// 選擇排序過程:
	// 外迴圈控制選擇的趟數,總共選擇size-1趟,
	// 減1是因為最後一趟選擇區間中剩餘一個元素,該趟選擇可以忽略
	for (int i = 0; i < size-1; ++i)
	{
		// 用maxPos標記[0, size-i)區間中最大元素
		// 在該趟選擇沒有開始前,預設認為0號位置就是最大元素
		int maxPos = 0;
		for (int j = 1; j < size - i; ++j)
		{
			// 遍歷區間[0, size-i)中元素,如果有元素比maxPos位置元素大,maxPos記錄該元素位置
			if (array[j] > array[maxPos])
				maxPos = j;
		}

		// 如果最大元素不在區間末尾時,將最大元素與區間末尾元素交換
		if (maxPos != size - i - 1)
		{
			int temp = array[maxPos];
			array[maxPos] = array[size - i - 1];
			array[size - i - 1] = temp;
		}
	}

	// 輸出原陣列
	printf("選擇排序後陣列中資料為:");
	for (int i = 0; i < size; ++i)
		printf("%d ", array[i]);
	printf("\n");
	return 0;
}

【結果截圖】

優化:既然一趟選擇能找到最大的元素,那麼也可以找到最小的元素,因此在一趟中可以找到最小和最大兩個元素,最小元素放在區間左側,最大元素放在區間右側,可以減少選擇的趟數。

#include<stdio.h>
int main()
{
	int array[] = {2,8,3,9,5,7,1,4,0,6};
	int size = sizeof(array) / sizeof(array[0]);
	// 輸出原陣列
	printf("排序前陣列中資料為:");
	for (int i = 0; i < size; ++i)
		printf("%d ", array[i]);
	printf("\n");

	
	int begin = 0, end = size - 1;
	// [begin, end]區間中進行選擇
	while (begin < end)
	{
		int maxPos = begin;  // 標記區間中最大元素的位置
		int minPos = begin;  // 標記區間中最小元素的位置
		int index = begin + 1;
		while (index <= end)
		{
			if (array[index] > array[maxPos])
				maxPos = index;

			if (array[index] < array[minPos])
				minPos = index;
			++index;
		}

		// 如果最大元素不在區間末尾,則交換
		if (maxPos != end)
		{
			int temp = array[maxPos];
			array[maxPos] = array[end];
			array[end] = temp;
		}

		// 如果在交換前區間末尾剛好儲存的是最小的元素,則最小的元素被交換到maxPos位置
		// 此時需要更新minPos
		if (minPos == end)
			minPos = maxPos;

		// 如果最小元素不在區間起始位置,則交換
		if (minPos != begin)
		{
			int temp = array[minPos];
			array[minPos] = array[begin];
			array[begin] = temp;
		}

		// 最大與最小元素已經在區間的起始和末尾的位置,
		// 因此begin往後移動,end往前移動
		begin++;
		end--;
	}

	// 輸出原陣列
	printf("選擇排序後陣列中資料為:");
	for (int i = 0; i < size; ++i)
		printf("%d ", array[i]);
	printf("\n");
	return 0;
}