用最少的並行交換完成排序

2021-05-28 16:24:31 字數 1859 閱讀 6802

一次「交換」操作是指將數列中的兩個數字置對換。我們假設,互不相交的若干個交換操作可以一次同時進行;換句話說,如果k個交換中任兩個都不會對同乙個數進行操作,那麼這k個操作可以並行完成。例如,在數列

10, 6, 8, 5, 2, 3, 1, 4, 7, 9

中,我們可以同時交換第4個數和第6個數,第8個數和第9個數,以及第3個數和第7個數。經過這一次「並行交換」後,數列變為:

10, 6, 1, 3, 2, 5, 8, 7, 4, 9

任意給定乙個長度為n的全排列,請問對該序列進行排序最壞情況下需要多少次並行交換?給出一種具體的演算法,說明這個次數足夠了;並且給出一種最壞情況,證明這個次數是必需的。

這種「並行交換」是如此的強大,以致於我們要問自己的第乙個問題是,是否有可能對所有數列都只需要一次並行交換就夠了。不難發現,除了n=1和n=2之外,對於其它的n,我們總能找到乙個數列,它至少需要兩次並行交換才能完成排序。考慮到一次並行交換只能變動偶數個數的位置,因此我們只需要弄出乙個有奇數個數不在正確位置上的排列就可以了。對於n≥3的情況,這總是可以辦到的,例如數列2, 3, 1, 4, 5, 6, 7, ..., n(僅讓最前面的1、2、3三個數字置順次挪一位)就可以了。這樣的話,我們要不然就無法處理完所有要移動的數,要不然就會動到已經在目標位置上的數,總之一次交換是怎麼也不能滿足要求。

令人吃驚的是,不管n有多大,不管數列有多亂,最多隻需要2次並行交換就可以排好序了。為了證明這一點,我們首先看一種特殊情況:對於「順次挪動一位」,即「2佔了1該在的位置,3又佔了2應該在的位置,……,n佔了n-1的位置,最後1又佔了n本該在的位置」的情況,如何用兩次並行交換調整順序。回想一下線性時間常數附加空間的陣列迴圈移動的演算法,我們立即得到了我們需要的演算法:由於迴圈移動一位相當於兩次逆序操作,而一次逆序操作可以由前後對稱位置上的n/2組交換完成,因此我們只需要兩次並行交換即可。具體地說,對於下面這個數列

2, 3, 4, ..., n-1, n, 1

首先將整個序列進行逆序,即2和1交換,3和n交換,4和n-1交換,……,於是得到:

1, n, n-1, ..., 4, 3, 2

接下來,將得到的序列的後面n-1位再逆序一次,即n和2交換,n-1和3交換,……,於是數列就變成了

1, 2, 3, 4, ..., n-1, n

這樣,我們就可以只用兩次並行交換完成「迴圈移動一位」型的數列了。

到這裡,我們離最終的答案已經很近很近了。最關鍵的一點是,這個「迴圈移動一位」可以是廣義的。換句話說,只要是「數字1應該到現在4的位置上去,而4又該移到7的位置上去,7則本該在現在2的位置上,而2又該替代現在的1」一類的「圈」,我們都可以用上面的方法在兩步以內還原為應有的順序。一旦想到了任何乙個排列總能分解成若干個互不相交的迴圈時,我們的問題也就立即解決了。

舉個例子,我們對原題中的例子

10, 6, 8, 5, 2, 3, 1, 4, 7, 9

進行排序。這個數列包含了兩個迴圈:10 -> 9 -> 7 -> 1 -> 10,以及6 -> 3 -> 8 -> 4 -> 5 -> 2 -> 6。也就是說,我們要把[10,9,7,1]四個數依次變成[1,10,9,7],同時把[6,3,8,4,5,2]變成[2,6,3,8,4,5]。在第一步,我們把第乙個迴圈中的(10,1)和(9,7)進行交換以實現逆序,同時並行地在另乙個不相交的迴圈中進行同樣的操作,將(6,2)、(3,5)和(8,4)進行交換;第二步,我們把每個迴圈中的後面一段進行逆序,即交換第乙個迴圈中的(10,7),同時交換第二個迴圈中的(6,5)和(3,4)。

10, 6, 8, 5, 2, 3, 1, 4, 7, 9  <--- 初始

1, 2, 4, 3, 6, 5 10, 8, 9, 7  <--- 第一步後

1, 2, 3, 4, 5, 6, 7, 8, 9 10  <--- 第二步後

用這種方法,任何乙個序列都可以在兩步以內排好序。

通過交換相鄰數來完成排序所需要的最少交換次數

對乙個無序序列進行排序,要求一次只能交換相鄰的兩個數,那麼最少需要交換多少次才可以完成排序呢?本問題假設序列所有數各不相同。概念介紹 1 逆序。一般認為從左向右序列的數字增大認為是正序的,那麼從左到右序列的序列數字出現減小就認為是逆序的。乙個 逆序 的數學定義是這樣的,如果存在正整數 i,j 使得 ...

陣列排序 計算最少交換次數

交換瓶子 有n個瓶子,編號 1 n,放在架子上。比如有5個瓶子 2 1 3 5 4 要求每次拿起2個瓶子,交換它們的位置。經過若干次後,使得瓶子的序號為 1 2 3 4 5 對於這麼簡單的情況,顯然,至少需要交換2次就可以復位。如果瓶子更多呢?你可以通過程式設計來解決。輸入格式為兩行 第一行 乙個正...

用Parallel For進行並行快速排序

用parallel for 進行並行快速排序 注 本文主要內容摘自筆者所著的 多核計算與程式設計 一書,略有修改,後續還會繼續發布系列文章,如有需要,可以考慮將一下位址加入到您的瀏覽器收藏夾中 http software.intel.com zh cn blogs category multicor...