zoukankan      html  css  js  c++  java
  • 面试题:一道冒泡算法笔试题的演进史

    给定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();
    
    
    
    
    
  • 相关阅读:
    GZS与小公园(DFS)
    II play with GG(思维规律)
    bearBaby loves sleeping(BFS)
    湖南大学新生赛C,G,J题解
    bootstrap 标签页的使用(tab)
    js 循环生成元素,并为元素添加click事件,结果只执行最后一个点击事件
    使用原生js实现一个列表数据展示页面不同的项目状态使整行显示不同颜色。
    【Vue】详解Vue组件系统 目录
    基于TCP与UDP协议的socket通信
    ElementUI三级菜单checkBox全选实现
  • 原文地址:https://www.cnblogs.com/simfe/p/2776426.html
Copyright © 2011-2022 走看看