面试官:手写一个冒泡排序,并对其改进

简介: 之前写过一篇选择排序,很多人把它和冒泡排序搞混了,这篇文章对冒泡排序进行一个分析,希望你能分清楚,也希望能在面试的时候能够完美的回答出冒泡排序。今年的工作据说是不好找,当然运气占很大一部分,但是实力越强运气的成分就会相应降低吧。

一、认识冒泡排序


之前在学习排序算法的时候,冒泡排序往往都是第一个被介绍,就是因为其太简单。冒泡排序很简单:

依次比较相邻的两个数,将小数放在前面,大数放在后面。


注意:冒泡排序比较的是相邻的两个数,而选择排序比较的整个队列中最大或者是最小的数进行交换。


第一趟:首先比较第1个和第2个数,将小数放前,大数放后。然后比较第2个数和第3个数,将小数放前,大数放后,如此继续,直至比较最后两个数,将小数放前,大数放后。(此时最后一个数一定是整个数组中的最大值)

第二趟:和第一趟一样,不过最后一个数已经是最大值,比较到倒数第二个即可。(此时倒数第二个数一定是整个数组倒数第二大的数)

第三趟、第四趟以此类推即可。

我们来一张动图演示一下:链接


上面的这张图,你多看几遍就理解了,每次排好都能选出来一哥当前数组的最大值。OK。如果你理解了之后,下面我们就开始写代码来实现一波。


二、代码实现


1、基本实现


我们先来看一下基本的实现。

public void BubbleSort(int arr[],int n){
    int temp;
    //有N个数,所以要跑N趟
    for(int i = 0;i<n;++i)
        //每一趟比较从右往左,得到的是最小值
        //每一趟比较从左往右,得到的是最大值
        for(int j = n-1;j>i;--j)
            //如果右边的数《左边的,那就交换位置
            if(arr[j]<arr[j-1]){
                temp = arr[j];
                arr[j] = arr[j-1];
                arr[j-1] = temp;
            }
}

上面的这种写法非常简单,不过我们可能会发现,每一趟其实得到是一个值,这个值可能是当前数组的最大值又或者是最小值。


这样做的缺点:

数组有一部分是本来就有序的,每一趟冒泡那么将会在此部分浪费时间


2、改进


现在我们进行改进:如果我们换一种想法,每一趟扫描的时候,对那些有序的部分,设置一个标志,如果为true表示发生了交换,如果为false,则没有发生交换,那么我们就可以直接跳过去了。

public static void bubbleSort2(int [] a, int n){
    int j, k = n;
    //发生了交换就为true, 没发生就为false
    boolean flag = true;
    while (flag){
        flag=false;//每次开始排序前,都设置flag为未排序过
        for(j=1; j<k; j++){
            //前面的数字大于后面的数字就交换
            if(a[j-1] > a[j]){
                int temp;
                temp = a[j-1];
                a[j-1] = a[j];
                a[j]=temp;
                //表示交换过数据;
                flag = true;
            }
        }
        k--;
    }
}


3、继续改进


上面的这个虽然很好,必过还是有一定的局限性,比如说数组的数据量很大有10000个,前面3000个杂乱无章,后面7000个都是排好的,而且还都比前3000个要大,这时候只需要比较前3000个即可。但是上面的改进算法,在对前3000个进行排序的时候,每次还都要和后7000个比较。这就显得臃肿了。于是我们进行改进。

public static void bubbleSort3(int [] a, int n){
    int j , k;
    int flag = n ;
    while (flag > 0){
        k = flag; //k 来记录遍历的尾边界
        flag = 0;
        for(j=1; j<k; j++){
            if(a[j-1] > a[j]){
                int temp;
                temp = a[j-1];
                a[j-1] = a[j];
                a[j]=temp;
                //表示交换过数据;
                flag = j;
            }
        }
    }
}

这个改进就是把flag变为具体的位置了,这样我们就可以记录末尾的边界。这个边界是排序与不排序的边界。


三、总结


冒泡排序在笔试或者是面试的时候,涉及到的时间复杂度和空间复杂度都是第一种普通情况。因此它的时间复杂度是O(n^2)。虽然简单,但是时间上确实是比较长。

我们一定要注意和选择排序的区别,选择排序是走一趟找出来一个最小的值和第一个同学交换位置。而冒泡排序是相邻同学比较高低,这样走一趟,最高个就沉到末尾了。


相关文章
|
机器学习/深度学习 搜索推荐 算法
面试时常常考察的java排序算法--选择排序、冒泡排序、插入排序
面试时常常考察的java排序算法--选择排序、冒泡排序、插入排序
|
7月前
|
机器学习/深度学习 算法 搜索推荐
|
搜索推荐 Java 程序员
java实现Bubble冒泡排序详解(java面试必背)
Bubble冒泡排序 前言:学习《CoreJava》强烈推荐看王宇希老师的笔记,史上最全: 🔴《CoreJava从入门到精通笔记》 🍅 程序员小王的博客:程序员小王的博客 🍅 欢迎点赞 👍 收藏 ⭐留言 📝 🍅 如有编辑错误联系作者,如果有比较好的文章欢迎分享给我,我会取其精华去其糟粕 🍅java自学的学习路线:java自学的学习路线 冒泡排序(Bubble Sort),是一种计算机科学领域的较简单的排序算法 需求: 排序前:{4,5,6,3,2,1} 排序后:{1,2,3,4,5,6}
144 0
java实现Bubble冒泡排序详解(java面试必背)
|
前端开发 JavaScript 算法
前端开发面试题—JavaScript冒泡排序
今天分享一下我遇到的一个关于JavaScript冒泡排序的面试题,题目是笔试题目,要求用JavaScript手写一个冒泡排序,倒序输出新的数组。其实难度不大,就是太久没手写代码在纸上了,感觉有点奇怪(¬_¬ )
137 0
前端开发面试题—JavaScript冒泡排序
|
算法 搜索推荐 索引
【面试:基础篇02:冒泡排序】
【面试:基础篇02:冒泡排序】
114 0
|
算法 搜索推荐 前端开发
前端面试不会直接挂掉的题目--冒泡排序
在准备面试的过程中,我们往往容易陷入到很多难度比较高的题目中不能自拔,却忽略了比较基础的题目,面试官在不了解我们的情况下,刚开始可能会问我们一道比较基础的算法题,比如数据结构,请问你能手写下冒泡排序吗?如果此时不会的话,可能直接结束面试了。哈哈~,让我们今天来一起学习下这个比较简单的排序算法吧~
167 0
前端面试不会直接挂掉的题目--冒泡排序
|
算法 搜索推荐 前端开发
前端面试不会直接挂掉的题目--冒泡排序
前端面试不会直接挂掉的题目--冒泡排序
125 0