經典演算法題每日演練——第二十二題 奇偶排序

一線碼農發表於2014-02-27

 

  這個專題因為各種原因好久沒有繼續下去了,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 }

 

 

相關文章