這個專題因為各種原因好久沒有繼續下去了,MM吧。。。你懂的,嘿嘿,不過還得繼續寫下去,好長時間不寫,有些東西有點生疏了,
這篇就從簡單一點的一個“奇偶排序”說起吧,不過這個排序還是蠻有意思的,嚴格來說複雜度是O(N2),不過在多核的情況下,可以做到
N2 /(m/2)的效率,這裡的m就是待排序的個數,當m=100,複雜度為N2 /50,還行把,比冒泡要好點,因為重點是解決問題的奇思妙想。
下面我們看看這個演算法是怎麼描述的,既然是奇偶,肯定跟位數有關了
1:先將待排序陣列的所有奇數位與自己身後相鄰的偶數位相比較,如果前者大於後者,則進行交換,直到這一趟結束。
2:然後將偶數位與自己身後相鄰的奇數位相比較,如果前者大於後者,則進行交換,直到這一趟結束。
3:重複1,2的步驟,直到發現無“奇偶”,“偶奇” 交換的時候,就認為排序完畢,此時退出迴圈。
由於網速問題,下載幾次freehand都失敗了,我就手寫個例子吧。
① 待排序陣列: 9 2 1 6 0 7
② 所有奇數位與身後的相鄰的偶數位比較交換 2 9 1 6 0 7
③ 所有偶數位與身後的相鄰的奇數位比較交換 2 1 9 0 6 7
④ 所有奇數位與身後的相鄰的偶數位比較交換 1 2 0 9 6 7
⑤ 所有偶數位與身後的相鄰的奇數位比較交換 1 0 2 6 9 7
⑥ 所有奇數位與身後的相鄰的偶數位比較交換 0 1 2 6 7 9
我們可以看到,經過5趟排序後,我們的陣列就排序完畢了,從圖中②可以看到,如果每個執行緒分攤一個奇數位,那交換是不是隻要
一次就夠了呢,可以看到這個演算法在多核處理下面還是很有優勢的。
最後的執行程式碼:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Xml.Xsl; 6 7 namespace ConsoleApplication1 8 { 9 class Program 10 { 11 static void Main(string[] args) 12 { 13 List<int> list = new List<int>() { 9, 2, 1, 6, 0, 7 }; 14 15 Console.WriteLine("\n排序前 => " + string.Join(",", list)); 16 17 list = OddEvenSort(list); 18 19 Console.WriteLine("\n排序後 => " + string.Join(",", list)); 20 21 Console.Read(); 22 } 23 24 static List<int> OddEvenSort(List<int> list) 25 { 26 var isSorted = false; 27 28 //如果還沒有排序完,就需要繼續排序,知道沒有交換為止 29 while (!isSorted) 30 { 31 //先預設已經排序完了 32 isSorted = true; 33 34 //先進行 奇數位 排序 35 for (int i = 0; i < list.Count; i = i + 2) 36 { 37 //如果 前者 大於 後者,則需要進行交換操作,也要防止邊界 38 if (i + 1 < list.Count && list[i] > list[i + 1]) 39 { 40 var temp = list[i]; 41 list[i] = list[i + 1]; 42 list[i + 1] = temp; 43 44 //說明存在過排序,還沒有排序完 45 isSorted = false; 46 } 47 } 48 49 //再進行 奇數位 排序 50 for (int i = 1; i < list.Count; i = i + 2) 51 { 52 //如果 前者 大於 後者,則需要進行交換操作,也要防止邊界 53 if (i + 1 < list.Count && list[i] > list[i + 1]) 54 { 55 var temp = list[i]; 56 list[i] = list[i + 1]; 57 list[i + 1] = temp; 58 59 //說明存在過排序,還沒有排序完 60 isSorted = false; 61 } 62 } 63 } 64 65 return list; 66 } 67 } 68 }