1. 程式人生 > >怎樣將不穩定排序變為穩定的排序

怎樣將不穩定排序變為穩定的排序

初次學到資料結構的排序部分,很多同學對於排序的穩定性搞不懂,不知道穩定性是什麼意思。舉個栗子,上高中,大家最關心的是自己的名次了,那麼最讓人尷尬的事情就是同樣分數的人該怎樣排名呢!比如說高三年級的一二三班各有一個考了總分250分的同學,一班的叫劉備,二班的叫關羽,三班的叫張飛,學校統計成績的時候是按照劉關張所在班級的順序將成績依次錄入全年級的成績庫中,然後按照總分分數進行排名。可是排出來的名次是關羽、劉備、張飛。就有同學發現了。這同樣的分數,學校排出的名次是按照學生姓名的第一個字母的順序將分數相同的同學進行排序的。學校給出的名次是關羽、劉備、張飛。這種情況的排名就是不穩定的排序,當你看到這名次覺得,學號看著很變扭,不是從小到大拍的。如果看著順眼,那順序還得是劉關張。那就得自己調整了,很麻煩。(這就如同一組資料中錄入三個2,排序後憑什麼第二個2就排在最前面呢!排序可是按照大於或者小於排序的。相同的2是不可以和2交換的。)因為學校錄入成績是按照劉關張順序錄入,按理說最終排名應該還是劉關張。而這種情況是穩定排序。(成績相同,不滿足交換的條件) 就有同學說了,同樣分數,一個前一兩名和後一兩名有必要分的這麼清嗎?這個問題就牽扯到了排序演算法的穩定性重要性問題了。我們再瞭解排序演算法的穩定性的作用吧!高考報志願,名次重要吧!一百個人靠同樣分數很常見。假如清華只錄取其中前3名。錄入順序肯定是按照地區的代號錄入成績。排序穩定了,大家就提前預知名次了。很簡單就體現了穩定性的作用。 怎樣判斷是不是穩定的排序呢!這就需要你對八大排序的演算法很瞭解。舉出造成該演算法不穩定的資料順序。沒有竅門。根本方法就是按照定義套,舉反例。沒有反例就是穩定排序。接下來是這篇文章重點。當面試官問道:如何將不穩定的演算法變成穩定的演算法呢!這個問題或許難倒所有初學者。並且很多重點大學學生未必都會。 方法就是換。怎麼換,排序最基本的方式就是將下標為m和下標為n的兩個數進行交換。那麼無論怎樣都會有從m到n的一段資料。 如圖所示: 這是升序排序的一部分,3和2交換就會發生不穩定情況,我們從該陣列的這兩個及交換的元素之間進行便利,找到與之相等的元素,然後和兌換。如圖: 從下標為4的元素開始尋找,找到5號下標元素為2,與被交換的元素2(下標為8的元素)相等,那麼將這兩個等值元素交換。然後繼續遍歷陣列,當找到3時,發現與被交換的3(下標為4的元素)相等,這時將兩個等值元素交換。直到遍歷到下標為8時結束遍歷。也就是說遍歷的長度是下標4到下標8之間的元素。只要遇到與值相等的就交換,即使是3個4個3也要交換。 如下是函式實現:
void Stable (int *arr, int start, int end)//(陣列名,交換元素開始下標,交換元素結束的下標)
{
	int tmp;
	for (int i= start+1; i<end-1; i++)
	{
		if (arr[start] == arr[i])//從start+1開始遍歷,找到與start下標元素相等的元素
		{
			tmp = arr[start];//交換元素
			arr[start] = arr[i];
			arr[i] = tmp;
		}

		 if(arr[i] == arr[end])//找到與end下標元素相等的元素
		{
			tmp = arr[end];//交換
			arr[end] = arr[i];
			arr[i] = tmp;
		}
	}
}