1. 程式人生 > 其它 >牛客IOI周賽22-普及組 簽訂協議(c++)

牛客IOI周賽22-普及組 簽訂協議(c++)

技術標籤:李斌的部落格演算法

故事背景

假如本次考試,本學校有100個學生,對於每個學生我們記錄了他的分數,現在你需要將同學們的分數,按照從高到低排名

思路excel地址:https://docs.qq.com/sheet/DU0doeGJIcmxtdUxT

那麼該如何做呢,一種辦法是,遍歷整個資料,然後吧分數最高的加入到一個新的列表中

依次這樣做,我們可以得到一個有序列表

從計算機的角度看待一個這個問題

O(n)時間意味著檢視列表中的每個元素一次。例如,對學生列表進行簡單查詢時,意味著每個學生都要檢視一次

要找出分數最高的學生,必須檢查列表中的每個元素。正如你剛才看到的,這需要的時間為O(n)。因此對於這種時間為O(n)的操作,你需要執行n次

需要檢查的元素數越來越少

隨著排序的進行,每次需要檢查的元素數在逐漸減少,最後一次需要檢查的元素都只有一個。既然如此,執行時間怎麼還是O(n2)呢?這個問題問得好,這與大O表示法中的常數相關。
後面將詳細解釋,這裡只簡單地說一說。
你說得沒錯,並非每次都需要檢查n個元素。第一次需要檢查n個元素,但隨後檢查的元素數依次為n  1, n – 2, …, 2和1。平均每次檢查的元素數為1/2 × n,因此執行時間為O(n × 1/2 × n)。
但大O表示法省略諸如1/2這樣的常數(有關這方面的完整討論,後面我會接著討論),

因此簡單地寫作O(n × n)或O(n^2)。

選擇排序是一種靈巧的演算法,但其速度不是很快。快速排序是一種更快的排序演算法,其執行時間為O(n log n),這將在後面介紹

選擇排序(Selection sort)是一種簡單直觀的排序演算法。它的工作原理如下。首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然後,再從剩餘未排序元素中繼續尋找最小(大)元素,然後放到已排序序列的末尾。以此類推,直到所有元素均排序完畢。

選擇排序的主要優點與資料移動有關。如果某個元素位於正確的最終位置上,則它不會被移動。選擇排序每次交換一對元素,它們當中至少有一個將被移到其最終位置上,因此對 n 個元素的表進行排序總共進行至多 n -1 次交換。在所有的完全依靠交換去移動元素的排序方法中,選擇排序屬於非常好的一種

下述程式碼提供了類似的功能:將陣列元素按從小到大的順序排列。先編寫一個用於找出陣列中最小元素的函式

C 語言演示

def findSmallest(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 = findSmallest(arr)
        newArr.append(arr.pop(smallest))
    return newArr

// 進行測試
print selectionSort([5, 3, 6, 2, 10])
PHP 語言演示
 
<?php
$arr = array(5, 8, 6, 7, 3);
 
// 選擇排序演算法實現 
function SelectSort($arr = array()) {
	//獲取陣列長度
    $size = sizeof($arr);
	//外層迴圈控制比較的數值下標與輪詢次數
    for ($i=0; $i<$size; $i++) {
		// 先假設最小值的位置
        $p=$i;
		//內層迴圈控制比較次數
        for ($j=$i+1; $j<$size; $j++) {
			// 如果 j 下標的值比 p 小標的值小
            if ($arr[$p] > $arr[$j]) {
				//記錄最小值的下標
                $p = $j;
            }
        }
		// 不相同則互換位置
        if ($p != $i){
            $tmp = $arr[$i];
            $arr[$i] = $arr[$p];
            $arr[$p] = $tmp;
        }
    }
    return $arr;
}
 
// 測試執行
print_r(SelectSort($arr));

動畫演示

選擇排序

選擇排序的示例動畫。紅色表示當前最小值,黃色表示已排序序列,藍色表示當前位置。