經典演算法題每日演練——第二十三題 雞尾酒排序

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

 

 

  這篇我們繼續扯淡一下雞尾酒排序,為了知道為啥取名為雞尾酒,特意看了下百科,見框框的話,也只能勉強這麼說了。

 

要是文藝點的話,可以說是攪拌排序,通俗易懂點的話,就叫“雙向氣泡排序”,我想作為碼農的話,不可能不知道氣泡排序,

冒泡是一個單向的從小到大或者從大到小的交換排序,而雞尾酒排序是雙向的,從一端進行從小到大排序,從另一端進行從大

到小排序。

從圖中可以看到,第一次正向比較,我們找到了最大值9. 

                      第一次反向比較,我們找到了最小值1.

                      第二次正向比較,我們找到了次大值8.

                      第二次反向比較,我們找到了次小值2

                      。。。

                     最後就大功告成了。

 

下面我們看看程式碼:

 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>() { 8, 1, 4, 2, 9, 5, 3 };
14 
15             Console.WriteLine("\n排序前 => {0}\n", string.Join(",", list));
16 
17             list = CockTailSort(list);
18 
19             Console.WriteLine("\n排序後 => {0}\n", string.Join(",", list));
20 
21             Console.Read();
22         }
23 
24         /// <summary>
25         /// 雞尾酒排序
26         /// </summary>
27         /// <param name="list"></param>
28         /// <returns></returns>
29         static List<int> CockTailSort(List<int> list)
30         {
31             //因為是雙向比較,所以比較次數為原來陣列的1/2次即可。
32             for (int i = 1; i <= list.Count / 2; i++)
33             {
34                 //從前到後的排序 (升序)
35                 for (int m = i - 1; m <= list.Count - i; m++)
36                 {
37                     //如果前面大於後面,則進行交換
38                     if (m + 1 < list.Count && list[m] > list[m + 1])
39                     {
40                         var temp = list[m];
41 
42                         list[m] = list[m + 1];
43 
44                         list[m + 1] = temp;
45                     }
46                 }
47 
48                 Console.WriteLine("正向排序 => {0}", string.Join(",", list));
49 
50                 //從後到前的排序(降序)
51                 for (int n = list.Count - i - 1; n >= i; n--)
52                 {
53                     //如果前面大於後面,則進行交換
54                     if (n > 0 && list[n - 1] > list[n])
55                     {
56                         var temp = list[n];
57 
58                         list[n] = list[n - 1];
59 
60                         list[n - 1] = temp;
61                     }
62                 }
63 
64                 Console.WriteLine("反向排序 => {0}", string.Join(",", list));
65             }
66 
67             return list;
68         }
69     }
70 }

 

從結果上面看,我們會發現,當陣列有序的時候,我們還會繼續往下排,知道完成length/2次,這個就跟沒優化之前的氣泡排序一樣,

此時我們可以加上一個標誌位IsSorted來判斷是否已經沒有交換了,如果沒有,提前退出迴圈。。。

 1         /// <summary>
 2         /// 雞尾酒排序
 3         /// </summary>
 4         /// <param name="list"></param>
 5         /// <returns></returns>
 6         static List<int> CockTailSort(List<int> list)
 7         {
 8             //判斷是否已經排序了
 9             var isSorted = false;
10 
11             //因為是雙向比較,所以比較次數為原來陣列的1/2次即可。
12             for (int i = 1; i <= list.Count / 2; i++)
13             {
14                 //從前到後的排序 (升序)
15                 for (int m = i - 1; m <= list.Count - i; m++)
16                 {
17                     //如果前面大於後面,則進行交換
18                     if (m + 1 < list.Count && list[m] > list[m + 1])
19                     {
20                         var temp = list[m];
21 
22                         list[m] = list[m + 1];
23 
24                         list[m + 1] = temp;
25 
26                         isSorted = true;
27                     }
28                 }
29 
30                 Console.WriteLine("正向排序 => {0}", string.Join(",", list));
31 
32                 //從後到前的排序(降序)
33                 for (int n = list.Count - i - 1; n >= i; n--)
34                 {
35                     //如果前面大於後面,則進行交換
36                     if (n > 0 && list[n - 1] > list[n])
37                     {
38                         var temp = list[n];
39 
40                         list[n] = list[n - 1];
41 
42                         list[n - 1] = temp;
43 
44                         isSorted = true;
45                     }
46                 }
47 
48                 //當不再有排序,提前退出
49                 if (!isSorted)
50                     break;
51 
52                 Console.WriteLine("反向排序 => {0}", string.Join(",", list));
53             }
54 
55             return list;
56         }

 

相關文章