1. 程式人生 > >也談氣泡排序(bubble sort)---兩次‘優化’

也談氣泡排序(bubble sort)---兩次‘優化’

	public function faster_b_s($array)
	{
		$count = count($array);
		$start_time = microtime(true);
		for ($i = 1; $i < $count; ++$i)
		{
			$exchange = false;
			for($j = 0; $j < $count - $i; ++$j)
			{
				if($array[$j] > $array[$j + 1])
				{
					$exchange = true;
					list($array[$j] , $array[$j + 1]) = array($array[$j + 1], $array[$j]) ;
				}
			}
			if(!$exchange) break;
		}
		$end_time = microtime(true);
		$message = 'eplaposed timie in '.__FUNCTION__.':'.($end_time - $start_time).'<br>';
		echo $message;
	}

三:二次優化
我們再想象一種極端情況:array長度為n,但是隻有第一個和第二個元素未排序,依照原始的氣泡排序仍然需要進行n-1此冒泡,其實只要一趟冒泡即可。原始的氣泡排序我們假定了第n趟冒泡的範圍是0-(length-n).實際上第n趟的涉及範圍取決於第n-1趟的最後交換位置,例如n-1次排序的最後交換位置是index,則表明index之後的元素都已經排序完畢,所以第n趟的涉及範圍是0-index,只需要記錄每一趟冒泡的最後交換位置.
演算法實現如下:
	public function fatest_b_s($array)
	{
		$count = count($array);
		$start_time = microtime(true);
		$mark = $count - 1;
		for ($i = 1; $i < $count; ++$i)
		{
			for($j = 0; $j < $mark; ++$j)
			{
				if($array[$j] > $array[$j + 1])
				{
					//$exchange = true;
					list($array[$j] , $array[$j + 1]) = array($array[$j + 1], $array[$j]) ;
					$index = $j + 1;
				}
			}
			$mark = $index;
		}
		$end_time = microtime(true);
		$message = 'eplaposed timie in '.__FUNCTION__.':'.($end_time - $start_time).'<br>';
		echo $message;
	}


結語:
演算法描述以及‘優化’完畢。兩次優化的原則就是限界剪枝,進行更少的操作 。那麼看看結果如何。
用生成的隨機數填充陣列,並依次呼叫三個排序函式,結果如下
(1)1000陣列元素排序
eplaposed timie in original_b_s:0.38794994354248
eplaposed timie in faster_b_s:0.41779398918152
eplaposed timie in fatest_b_s:0.38996005058289
(2)5000陣列元素排序
eplaposed timie in original_b_s:10.363991975784
eplaposed timie in faster_b_s:11.036885023117
eplaposed timie in fatest_b_s:11.047054052353
(3)10000陣列元素排序
eplaposed timie in original_b_s:45.779250144958
eplaposed timie in faster_b_s:48.629040002823
eplaposed timie in fatest_b_s:48.757740974426

實驗結果很失敗,兩次優化都耗費了更多的時間。原因是兩次優化的初衷都是考慮了比較特殊的情況,想要通過減少比較次數的方法減少耗時,但是卻增加了標記的耗時。
哈哈,寫到這裡我又做了一組測試,很有意思。主要變動就是記錄了三種演算法的比較次數,結果如下:
eplaposed timie in original_b_s:38.264737129211
compare count in original_b_s:49995000
eplaposed timie in faster_b_s:41.45903301239
compare count in faster_b_s:49978710
eplaposed timie in fatest_b_s:39.778419017792
compare count in fatest_b_s:49972651

實驗結果表明,優化後比較次數並沒有減少太多,但是增加了標記的耗時,所以導致優化後耗時更多。