給定N個整數,請使用冒泡算法按照從大到小的順序排序
1.可對N個整數的某一段(連續的M整數)排序
2.要求具有一定的可測試性
3.C#語言
--------------------
思路:
1.冒泡算法
2.針對部分排序
3.可測試性
先上一段最簡單的代碼實現冒泡算法--這里錯誤的使用了選擇排序,請參看改進版本的修正
1 int[] list= new int[] {1, 2, 3, 4, 5}; 2 for (int i=0;i<list.Length;i++) 3 for (int j=i+1;j<list.Length;j++) 4 { 5 if (list[i]<list[j]) 6 { 7 int tmp=list[i]; 8 list[i]=list[j]; 9 list[j]=tmp; 10 } 11 } 12 for (int i=0;i<list.Length;i++) 13 System.Console.Write("{0}\t",list[i]); 14 System.Console.WriteLine("");
觀看上述代碼,有如下發現
1)行1,主要進行數據的初始化工作,准備數據
2)行2-11,主要實現冒泡排序算法
3)行12-14,主要是顯示結果
4)行1-14,包含算法實現,調用,實現和使用糅合在一起
第一次改進:
1)數據初始化部分,其實屬於調用部分,此時用的是數組,擴展性較差,這里改成List<int>,並將此步重構成函數
//初始化N個數據 void Init(List<int> list,int count) { System.Random a=new Random(); for (int i=0;i<count;i++) list.Add(a.Next(100)); }
這里初始化數據,主要是減少人工干預,自動產生測試數據,實際生產過程中,是需要按照實際情況,選取一些比較特殊的數據作為測試數據的.
2)冒泡排序算法實現過程部分,也可以重構成函數
1 //實現冒泡算法——這里錯誤的使用了選擇排序 2 void Bubble(List<int> list) 3 { 4 for (int i=0;i<list.Count;i++) 5 for (int j=i+1;j<list.Count;j++) 6 { 7 if (list[i]<list[j]) 8 { 9 int tmp=list[i]; 10 list[i]=list[j]; 11 list[j]=tmp; 12 } 13 } 14 }
正確的冒泡排序為
1 void Bubble(List<int> list) 2 { 3 bool bFlag=false; 4 for (int i=0;i<list.Count;i++) 5 { 6 bFlag=false; 7 for(int j=list.Count-1-1 ;j>i-1;j--) 8 { 9 if (list[j]<list[j+1]) 10 { 11 int tmp=list[j+1]; 12 list[j+1]=list[j]; 13 list[j]=tmp; 14 bFlag=true; 15 } 16 } 17 if (!bFlag) break; 18 } 19 }
將排序的代碼,重構成函數,使得算法可以非常容易進行測試,只需要將精心設計的測試數據傳給函數,就可以了
3)顯示結果,也是重構成函數
1 //顯示結果 2 void Print(List<int> list) 3 { 4 for (int i=0;i<list.Count;i++) 5 System.Console.Write("{0}\t",list[i]); 6 System.Console.WriteLine(""); 7 }
4)最終調用過程
public static void Main() { List<int> list=new List<int>(); //產生測試數據 Init(list,8); //打印測試數據 Print(list); //按照從大到小的順序排序 Bubble(list); //打印排序后的結果 Print(list); }
第二次改進:
第一次改進中,基本解決冒泡算法和可測試性的問題,但是還有一個重要問題沒有解決,就是針對N個整數中的某一段連續M個數據進行排序,所以這次的改進主要集中在<冒泡排序算法實現>函數的改進
很明顯,要實現這個功能,只需要,在 Bubble這個函數增加兩個參數,標識出M的上下限,Bubble變成如下形式
1 void Bubble(List<int> list,int low,int high)
新的實現(注意,這里我的冒泡算法的實現是不對的,我用的是選擇排序,經過一個園子里的兄弟提醒,我查過資料,發現的確用錯了)
選擇排序(Selection sort)
首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再從剩余未排序元素中繼續尋找最小(大)元素,然后放到已排序序列的末尾。
void Bubble(List<int> list,int low,int high) { int iHigh= list.Count<high+1? list.Count : high+1 ; int iLow=low<0? 0 :low ; //System.Console.WriteLine("{0}\t{1}",iLow,iHigh); for (int i=iLow;i<iHigh;i++) for (int j=i+1;j<iHigh;j++) { if (list[i]<list[j])//比較不一定相鄰 { int tmp=list[i]; list[i]=list[j]; list[j]=tmp; } } }
下面是更正后的冒泡排序代碼
冒泡排序(BubbleSort)
依次比較相鄰的兩個數,將小數放在前面,大數放在后面。
1 static void Bubble(List<int> list,int low,int high) 2 { 3 int iHigh= list.Count<high+1? list.Count : high+1 ; 4 int iLow=low<0? 0 :low ; 5 6 bool bFlag=false; 7 for (int i=iLow;i<iHigh;i++) 8 { 9 bFlag=false; 10 for(int j=iHigh-1-1 ;j>i-1;j--) 11 { 12 if (list[j]<list[j+1])//比較相鄰 13 { 14 int tmp=list[j+1]; 15 list[j+1]=list[j]; 16 list[j]=tmp; 17 bFlag=true; 18 } 19 } 20 if (!bFlag) break; 21 } 22 }
並提供一個重載函數
1 void Bubble(List<int> list) 2 { 3 Bubble(list,0,list.Count-1); 4 }
調用:
1 public static void Main() 2 { 3 List<int> list=new List<int>(); 4 //產生測試數據 5 Init(list,8); 6 //打印測試數據 7 Print(list); 8 //按照從大到小的順序排序,針對序號2-5的之間的數據 9 Bubble(list,2,5); 10 //打印排序后的結果 11 Print(list); 12 }
至此,題目要求的目的全部達到,不過還是少了點什么,下面進行第三次改進
第三次改進:
第一次改進和第二次改進的結果,還是采用面向過程的方法,第三次改進側重與面向對象的方法,就是封裝
三個主要函數中都有List<int> list參數,這個是主要數據,我們用類來封裝它,如下給出完整代碼
1 public class BubbleSort 2 { 3 List<int> _list; 4 public BubbleSort() 5 { 6 _list=new List<int>(); 7 } 8 public BubbleSort(List<int> list) 9 { 10 _list=list; 11 } 12 13 public void Sort() 14 { 15 Sort( _list,0,_list.Count-1); 16 } 17 public void Sort(int low,int high) 18 { 19 Sort( _list,low,high); 20 } 21 //實現冒泡算法--這里錯誤使用選擇排序,請替換為第二次改進中的正確實現 22 public void Sort(List<int> list,int low,int high) 23 { 24 //int iHigh= list.Count<low+count? list.Count : high ; 25 int iHigh= list.Count<high+1? list.Count : high+1 ; 26 int iLow=low<0? 0 :low ; 27 //System.Console.WriteLine("{0}\t{1}",iLow,iHigh); 28 for (int i=iLow;i<iHigh;i++) 29 for (int j=i+1;j<iHigh;j++) 30 { 31 if (list[i]<list[j]) 32 { 33 int tmp=list[i]; 34 list[i]=list[j]; 35 list[j]=tmp; 36 } 37 } 38 } 39 40 //初始化N個數據 41 public void Init(int count) 42 { 43 _list.Clear(); 44 System.Random a=new Random(); 45 for (int i=0;i<count;i++) 46 _list.Add(a.Next(100)); 47 } 48 //顯示結果 49 public void Print(List<int> list) 50 { 51 Print(list,0,list.Count-1,true); 52 } 53 public void Print(List<int> list,int low,int high,bool IsNewLine) 54 { 55 int iHigh= list.Count<high+1? list.Count : high+1 ; 56 int iLow=low<0? 0 :low ; 57 58 for (int i=iLow;i<iHigh;i++) 59 System.Console.Write("{0}\t",list[i]); 60 if (IsNewLine) 61 System.Console.WriteLine(""); 62 } 63 public void Print(int low,int high,bool IsNewLine) 64 { 65 Print(_list,low,high,IsNewLine); 66 } 67 //將排序的M個數據用紅色顯示 68 public void Print(int low,int high) 69 { 70 Print(0,low-1,false); 71 System.Console.ForegroundColor=ConsoleColor.Red; 72 Print(low,high,false); 73 System.Console.ResetColor(); 74 Print(high+1,_list.Count,true); 75 } 76 77 public void Print() 78 { 79 Print(_list); 80 } 81 //for test 82 public void Test() 83 { 84 //產生測試數據 85 Init(10); 86 //打印測試數據 87 Print(); 88 //按照從大到小的順序排序 89 int[] iLowHigh=new int[]{4,7}; 90 Sort(iLowHigh[0],iLowHigh[1]); 91 //Sort(-1,8); 92 //Sort(0,18); 93 //Sort(-1,18); 94 //打印排序后的結果 95 //Print(); 96 Print(iLowHigh[0],iLowHigh[1]); 97 98 } 99 }
調用代碼:
1 BubbleSort bs=new BubbleSort(); 2 bs.Test();