面試題:一道冒泡算法筆試題的演進史


給定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();

 

 
        

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM