面试题:一道冒泡算法笔试题的演进史

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

 

 
  

 

 

 

你可能感兴趣的:(面试题)