今天研究了一下演算法導論,很有意思的一本書,至少可以很好的訓練人的思維。呵呵。不過被乙個課後習題難到了:stooge演算法。試著舉例來證明一下,不過沒有成功。不過找到了乙個使用迴圈不變性(有的人叫迴圈不變式,不過感覺這種叫法好一些。)證明的。答案如下: stooge-sort(a, i, j) 1 if a[i] > a[j] 2 then exchange a[i] « a[j] 3 if i+1 ≥ j 4 then return 5 k ¬ ë(j-i+1)/3û # 下取整 6 stooge-sort(a, i, j-k) # 前 2/3 7 stooge-sort(a, i+k, j) # 後 2/3 8 stooge-sort(a, i, j-k) # 再次前 2/3 這是乙個號稱很厲害的排序演算法。說它厲害並不是因為它有多麼的快,事實上它比插入排序還要慢。它的厲害之處在於,用一般的掰手指頭的方法絕對無法證明它的正確性。讓我們用迴圈不變式來證明它的正確性。 迴圈不變式:在每次 stooge-sort(a, i, j) 返回時,陣列 a[i..j] 是有序的。 初 始 化:當 i+1 ≥ j 時,不再進行遞迴,函式會立即返回。由於執行了第1、2行,可保證 a[i] ≤ a[j]。因為 i+1=j,所以陣列a[i..j]有序。迴圈不變式成立。 保 持:假設 stooge-sort(a, i, j) 內部對stooge-sort() 的所有遞迴呼叫都滿足迴圈不變式,即stooge-sort(a, i, j-k) 可使 a[i..j-k] 有序,stooge-sort(a, i+k, j) 可使 a[i+k..j] 有序。 ∵ k = ë(j-i+1)/3û ∴ j-i+1 ≥ 3k ∴ (j-i+1)-2k ≥ k ∵ a[i..j-k] 與 a[i+k..j] 重疊的部分為 a[i+k..j-k],共(j-k)-(i+k)+1 = (j-k+1) - 2k ≥ k 個元素 而 a[i..j-k] 與 a[i+k..j] 不重疊的部分為 a[j-k+1..j] 共 j-(j-k+1)+1 = k 個元素。即,a[i..j-k] 與 a[i+k..j] 重疊部分的元素個數大於等於不重疊部分的元素個數。 ∴ 在執行了第 6、7 行的stooge-sort(a, i, j-k) 和 stooge-sort(a, i+k, j),分別使a[i..j-k] 和 a[i+k..j]有序後,可保證 a[j-k+1..j] 中的元素是 a[i..j] 中最大的 k 個元素,且是有序的。 ∵ 在執行了第8行的stooge-sort(a, i, j-k)後,可保證 a[i..j-k] 有序。 ∴ 綜上,可保證在 stooge-sort(a, i, j) 返回後,a[i..j] 是有序的。迴圈不變式成立。 終 止:在最外層的 stooge-sort(a, 1, n) 返回後,可使陣列 a 有序,演算法是正確的。 下面說明一下這個演算法的複雜性分析: 由上面的偽**可知:問題每一次被分解,變成乙個較小的問題,原問題和子問題之間的關係如下:t(n) = 3t(2n/3) + 1。由主定理很容易知道他的演算法複雜性為:t(n) = o(n^log(3/2, 3))。很顯然log(3/2, 3))>2,也就是說這個演算法比插入排序的o(n^2)效能還差。不過《演算法導論》的作者有種鄙視他們的意思。呵呵。 #include
#include
using namespace std; /* 演算法導論裡有這個演算法。 屬於交換排序,是對快排的劃分方法的乙個改進,不是劃分為2個部分,而是劃分為3個部分,從而提高排序效能。 stooge-sort(a, i, j) 對陣列a中第i個元素到第j個元素進行公升序排序。 排序的思想: 1.使a[i]、a[j]有序。 2.對a中前2/3進行排序,使a中前2/3的元素保持公升序。 3.對a中後2/3進行排序,使a中後2/3的元素保持公升序。 至此可以知道,對後2/3排序後,會打亂中間1/3部分的元素順序,從而使得前2/3無序。 4.再對前2/3進行排序,這時,整個陣列中的元素即為有序。 遞迴出口,是只有兩個元素時,這是很明顯的。 */ void stoogesort(int arr, int low, int high) if(low+1 > high) return; int k = (high - low + 1) / 3; stoogesort(arr, low, high-k);//對前2/3進行排序 stoogesort(arr, low+k, high);//對後2/3進行排序 stoogesort(arr, low, high-k);//在對前2/3進行排序 } int main(int argc, char *ar**) ; int size = sizeof(arr) / sizeof(int); stoogesort(arr, 0, size-1); for(int i=0; i
排序演算法 排序演算法彙總
排序演算法無疑是學習資料結構中的重點內容,本文將給出排序演算法的彙總。下面是具體的實現 include include include define n 1000000 int array n int temp n 1 氣泡排序 void bubblesort int a,int n if tag ...
排序演算法 排序演算法彙總
排序演算法無疑是學習資料結構中的重點內容,本文將給出排序演算法的彙總。下面是具體的實現 include include include define n 1000000 int array n int temp n 1 氣泡排序 void bubblesort int a,int n if tag ...
排序演算法 排序演算法彙總
排序演算法無疑是學習資料結構中的重點內容,本文將給出排序演算法的彙總。下面是具體的實現 include include include define n 1000000 int array n int temp n 1 氣泡排序 void bubblesort int a,int n if tag ...