数据结构与算法(二):带你读懂冒泡排序(Bubble Sorting)

栏目: 编程工具 · 发布时间: 5年前

内容简介:冒泡排序(Bubble Sorting),是一种计算机科学领域的较简单的排序算法。它的基本思想是:通过对待排序序列从前向后(从下标较小的元素开始), 依次比较相邻元素的值,若发现逆序则交换,使值较大的元素逐渐从前移向后部,就象水底下的气泡一样逐渐向上冒。故名“冒泡排序”。我们先通过图来简单理解一下一次冒泡的过程图中可以看出,经过一次冒泡,9这个当前数组中最大的元素飘到了最上面,如果进行N次这样操作,那么数组中所有元素也就到飘到了它本身该在的位置,就像水泡从水中飘上来,所以叫冒泡排序。
数据结构与算法(二):带你读懂冒泡排序(Bubble Sorting)
数据结构与算法(二):带你读懂冒泡排序(Bubble Sorting)

1. 基本介绍

冒泡排序(Bubble Sorting),是一种计算机科学领域的较简单的 排序 算法。它的基本思想是:通过对待排序序列从前向后(从下标较小的元素开始), 依次比较相邻元素的值,若发现逆序则交换,使值较大的元素逐渐从前移向后部,就象水底下的气泡一样逐渐向上冒。故名“冒泡排序”。

2. 冒泡排序理解

2.1 冒泡排序动图

数据结构与算法(二):带你读懂冒泡排序(Bubble Sorting)
数据结构与算法(二):带你读懂冒泡排序(Bubble Sorting)

2.2 图解冒泡排序

我们先通过图来简单理解一下一次冒泡的过程

数据结构与算法(二):带你读懂冒泡排序(Bubble Sorting)

图中可以看出,经过一次冒泡,9这个当前数组中最大的元素飘到了最上面,如果进行N次这样操作,那么数组中所有元素也就到飘到了它本身该在的位置,就像水泡从水中飘上来,所以叫冒泡排序。

具体实现过程:

  1. 首先 9 和 2 比较,由于 9 > 2,所以两者交换位置,即从A[0]到A[1]的转变。
  2. 然后继续下标为 1 的同下标为 2 的进行比较,由于 9 > 7,所以继续进行位置移动。
  3. 直至 A[4],9 和 3 进行比较,继续发生位置交换;
  4. 在比较的过程中,找到最大的某一个数,并进行移动。经过一次冒泡排序,最终在无序表中找到一个最大值 9,第一次冒泡结束。

看下整个冒泡过程

数据结构与算法(二):带你读懂冒泡排序(Bubble Sorting)

从图中我们可以看到,在第三次冒泡的时候,就已经达到了 有序状态 。因此我们可以做一个 标识 ,当冒泡操作没有进行 数据交换 时,就可以认为已经达到了 有序状态 。也是我们后面要说的 冒泡排序的优化

3. 冒泡排序代码

通过图片理解完冒泡排序整个过程后,我们开始准备些冒泡排序的算法了。

3.1 冒泡排序过程模拟

在写算法之前,我们先用 最笨 的办法,把冒泡排序手写一遍,总结下其中的规律在哪?

数据结构与算法(二):带你读懂冒泡排序(Bubble Sorting)

从上图整个冒泡排序过程,我们可以 小结 一下:

(1)一共进行 数组的大小-1 次大的循环 (2)每一趟排序的次数在逐渐的 减少 (3)在冒泡排序中, 没有发生一次交换 ,可以提前结束冒泡排序。这个就是 优化

3.2 冒泡排序法算法口诀

口诀

  • 外层循环 0到n-1 //控制比较轮数 n 表示元素的个数
  • 内层循环 0到n-i-1 //控制每一轮比较次数
  • 两两比较做交换

3.3 冒泡排序法算法代码

/**
 * @author: Coder编程
 * @create: 2019-6-18 21:31
 * @description: 冒泡排序
 **/
 
public class BubbleSort {


    public Integer[] bubbleSort(Integer[] arr) {
        //如果只有一个元素就不用排序了
        if (arr.length <= 1) return arr;
 
        for (int i = 0; i < arr.length; ++i) {
            // 提前退出冒泡循环的标志位,即一次比较中没有交换任何元素,这个数组就已经是有序的了
            boolean flag = false;
            for (int j = 0; j < arr.length - i - 1; ++j) {        //此处的 arr.length - i - 1就是每趟排序的减少
                // 数组下标又是从0开始的,i下标后面已经排序的个数就得多减1,总结就是i增多少,j的循环位置减多少
                if (arr[j] > arr[j + 1]) {        //前一位与后一位与前一位比较,如果前一位比后一位要大,那么交换
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                    flag = true;
                }
            }
            //没有数据交换,数组已经有序,退出排序
            if (!flag) break;
        }
        return arr;
    }
 
    public static void main(String[] args) {
        Integer arrays[] = {2,9,7,5,3};
        System.out.print("欢迎个人公众号Coder编程:冒泡排序前:");
        Arrays.asList(arrays).stream().forEach(x -> System.out.print(x + " "));

        BubbleSort bubbleSort = new BubbleSort();
        Integer[] result = bubbleSort.bubbleSort(arrays);

        System.out.print("\n欢迎个人公众号Coder编程:冒泡排序后:");
        Arrays.asList(result).stream().forEach(x -> System.out.print(x + " "));
    }

复制代码

输出结果:

数据结构与算法(二):带你读懂冒泡排序(Bubble Sorting)

4. 冒泡排序优化

上面的代码已经进行过优化,加了排序中, 没有发生一次交换 ,提前结束冒泡排序的标识 flag

这里推荐另外一种优化方式: 鸡尾酒排序 ,也叫 双向冒泡排序

数据结构与算法(二):带你读懂冒泡排序(Bubble Sorting)
public static Integer[] sort(Integer[] arr){
	//依次将最大的数放置到数组末尾,将第二大的数放到倒数第二位...
	boolean changed;
	for(int i = 0;i < arr.length/2;i++){
		changed = false;
		//从前往后,比较相邻两个数,把大的放在后边.之前已放置成功的可以不再参与比较
		for(int j = i;j < arr.length-1-i;j++){

			if(arr[j]>arr[j+1]) {
				swap(arr,j,j+1);
				changed =true;
			}
		}
		if(!changed){
			break;
		}
		for(int j = arr.length-1-i; j > i; j--){

			if(arr[j]<arr[j-1]) {
				swap(arr,j,j-1);
				changed = true;
			}
		}
		if(!changed){
			break;
		}
	}
	return arr;
}

public static void swap(Integer[] arr, int pos1, int pos2){
	int temp = arr[pos1];
	arr[pos1] = arr[pos2];
	arr[pos2] = temp;
}

复制代码

5. 冒泡排序性能分析

对于时间复杂度与空间复杂度概念不太了解的朋友可以看我写的上一篇文章: 数据结构与算法(一):带你了解时间复杂度和空间复杂度到底是什么?

5.1 最劣的情况 O(n^2)

计算最糟糕情况,就是全部逆序情况。时间复杂度为O(n^2)

比较次数和 移动次数 分别为 n(n-1)/23n(n-1)/2

我们以 比较次数 进行理解

冒泡排序一共要进行(n-1)次循环,每一次循环都要进行当前n-1次比较。所以一共的比较次数是:

(n-1) + (n-2) + (n-3) + … + 1 = n*(n-1)/2;

因此冒泡排序的时间复杂度是 O(n2)。

移动次数很好理解。会发生3次交换,因此常量系数为3。

5.1 最优的情况 O(n)

计算优情况时,也就是全部是顺序的情况下。冒泡排序只执行第一层for循环,而不会执行第二层for循环。

因此冒泡排序的时间复杂度是 O(n)。

6. 冒泡排序扩展阅读

6.1 C语言

void bubble ( int arr[], int n)
{
	int i;
	int temp;
	for (i = 0; i < n - 1; i++) {
		if (arr[i] > arr[i + 1]) {
			temp = arr[i];
			arr[i] = arr[i + 1];
			arr[i + 1] = temp;
		}
	}
}

void bubbleSort ( int arr[], int n)
{
	int i;
	for (i = n; i >= 1; i--) {
		bubble(arr, i);
	}
}

复制代码

6.2 Python

def sort_myarr():
    myarr=[2,9,7,5,3]
    lenth=len(myarr)
    for i in range(lenth):
        for j in range(lenth-i-1):
            if myarr[j]>myarr[j+1]:
                temp=myarr[j]
                myarr[j]=myarr[j+1]
                myarr[j + 1]=temp

    print(myarr)

复制代码

6.3 JS版

var examplearr=[8,94,15,88,55,76,21,39];
function sortarr(arr){
    for(i=0;i<arr.length-1;i++){
        for(j=0;j<arr.length-1-i;j++){
            if(arr[j]>arr[j+1]){
                var temp=arr[j];
                arr[j]=arr[j+1];
                arr[j+1]=temp;
            }
        }
    }
    return arr;
}
sortarr(examplearr);
console.log(examplearr);

复制代码

6. 冒泡排序总结

优点:比较简单,空间复杂度较低,是稳定的。 缺点: 时间复杂度太高,效率不好。

其他可看上面的 小结算法口诀

参考文章

cloud.tencent.com/developer/a…

www.pianshen.com/article/304…

blog.csdn.net/Hydra_shuan…

文末

欢迎关注个人微信公众号: Coder编程 获取最新原创技术文章和免费学习资料,更有大量精品思维导图、面试资料、PMP备考资料等你来领,方便你随时随地学习技术知识! 新建了一下qq群:315211365,欢迎大家进群交流一起学习。谢谢了!也可以介绍给身边有需要的朋友。

文章收录至 Github: github.com/CoderMerlin… Gitee: gitee.com/573059382/c…

数据结构与算法(二):带你读懂冒泡排序(Bubble Sorting)
数据结构与算法(二):带你读懂冒泡排序(Bubble Sorting)

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

浪潮之巅(上册)

浪潮之巅(上册)

吴军 / 人民邮电出版社 / 2013-5-1 / 35.00元

《浪潮之巅(第2版)(上册)》不是一本科技产业发展历史集,而是在这个数字时代,一本IT人非读不可,而非IT人也应该阅读的作品。一个企业的发展与崛起,绝非只是空有领导强人即可达成。任何的决策、同期的商业环境,都在都影响着企业的兴衰。《浪潮之巅》不只是一本历史书,除了讲述科技顶尖企业的发展规律,对于华尔街如何左右科技公司,以及金融风暴对科技产业的冲击,也多有着墨。此外,《浪潮之巅》也着力讲述很多尚在普......一起来看看 《浪潮之巅(上册)》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

MD5 加密
MD5 加密

MD5 加密工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具