【排序算法】什么是冒泡排序 ?

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_42351033/article/details/101907701

一:什么是冒泡排序

1、定义:

冒泡排序(Bubble Sort)是一种简单直观的排序算法,它通过依次比较相邻两个元素的大小,在每一次的比较的过程中,通过交换来达到有序的目的。

就像碳酸饮料中的气泡一样,从底部一直冒泡到顶部。

2、原理:

  • 比较相邻的元素,如果第一个比第二个大或小,就交换它们两个。
  • 对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对,最后的元素会是最大或者最小的数。
  • 针对所有的元素重复以上的步骤,除了最后一个。
  • 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

3、动态图演示:
在这里插入图片描述
4、C# 代码实现:

namespace AlgorithmTest
{
    class Program
    {
        static void Main(string[] args)
        {
            // 定义一个长度为5的数组
            int[] array = new[]{ 5, 4, 2, 3, 8 };
            BubbleSort(array);
            Console.ReadKey();
        }

        static void BubbleSort(int[] array)
        {
            // 临时变量,用来接收两元素中较大或者较小的元素
            int temp = 0;
            // 外循环控制轮数
            for (int i = 0; i < array.Length - 1; i++)
            {
                // 内循环两两元素比较
                for (int j = 0; j < array.Length - 1 - i; j++)
                {
                    // 从左往右,依次递增
                    if (array[j] > array[j + 1])
                    {
                        temp = array[j];
                        array[j] = array[j + 1];
                        array[j + 1] = temp;
                    }
                }
            }
            
			// 通过循环打印结果
            foreach (var item in array)
            {
                Console.Write(item + " ");
            }

        }
    }
}

控制台输出结果如下所示
在这里插入图片描述
冒泡排序通过两次 for循环 实现,内循环进行两两元素之间的比较,而外循环决定将进行几次这样的内循环,才能彻底将所有元素比较一遍,完成冒泡排序。

二:冒泡排序的优化

1、分析:

冒泡排序有一个最大的问题就是这种算法不管有序还是没序,先执行循环再说。

举个数组例子:[ 1,2,3,4,5 , 6],很明显,这是一个有序的数组,根本不需要排序,如果你用了冒泡排序,它仍会双层循环一个不少的把数据遍历一遍,这是没必要做的事情,属于浪费资源。

针对这个问题,我们可以设定一个临时布尔值变量,来标记该数组是否已经有序,如果有序了就不用遍历了。

2、C# 代码:

为了更直观的做优化前后执行轮数的对比,我定义了一个 { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 11 } 的数组,代码如下

namespace AlgorithmTest
{
    class Program
    {
        static void Main(string[] args)
        {
            // 定义一个长度为12的数组
            int[] array = new[]{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 11 };
            BubbleSort(array);
            Console.ReadKey();
        }

        static void BubbleSort(int[] array)
        {
            int temp = 0; // 临时变量,用来接收两元素中较大或者较小的元素
            int flag = 0; // 仅用来记录循环轮数

            // 外循环控制轮数
            for (int i = 0; i < array.Length - 1; i++)
            {
                bool isSort = true;
                // 内循环两两元素比较
                for (int j = 0; j < array.Length - 1 - i; j++)
                {
                    // 从左往右,依次递增
                    if (array[j] > array[j + 1])
                    {
                        temp = array[j];
                        array[j] = array[j + 1];
                        array[j + 1] = temp;
                        isSort = false;
                    }
                }
                if (isSort)
                {
                    break;
                }
                else
                {
                    flag++;
                }
            }
            // 通过循环打印结果
            foreach (var item in array)
            {
                Console.Write(item + " ");
            }

            Console.WriteLine("总共循环了 " + flag + " 轮");
        }
    }
}

我们知道,优化前执行的轮数 = 数组的长度 - 1 = 12 - 1 = 11 ,那优化后需要执行多少轮呢 ?如下所示
在这里插入图片描述
冒泡排序优化后的效果还是显而易见的。

虽然这样的优化对现在的计算机而言,也许并没有提高多大的效能,但更多的是我们对于算法思维的提高。

扩展:
一:冒泡排序什么时候最快 ? 答:当数据是正序时,时间复杂度 O(n)
二:冒泡排序什么时候最慢 ? 答:当数据是反序时,时间复杂度 O(n²)

三:多种编程语言实现冒泡排序(参考)

1:Java

public class BubbleSort implements IArraySort 
{
    @Override
    public int[] sort(int[] sourceArray) throws Exception 
    {
        // 对 arr 进行拷贝,不改变参数内容
        int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);

        for (int i = 1; i < arr.length; i++) 
        {
            // 设定一个标记,若为true,则表示此次循环没有进行交换,也就是待排序列已经有序,排序已经完成。
            boolean flag = true;

            for (int j = 0; j < arr.length - i; j++) 
            {
                if (arr[j] > arr[j + 1]) 
                {
                    int tmp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = tmp;
                    flag = false;
                }
            }

            if (flag) 
            {
                break;
            }
        }
        return arr;
    }
}

2:JavaScript

function bubbleSort(arr) 
{
    var len = arr.length;
    for (var i = 0; i < len - 1; i++) 
    {
        for (var j = 0; j < len - 1 - i; j++) 
        {
            // 相邻元素两两对比
            if (arr[j] > arr[j+1]) 
            {       
                // 元素交换 
                var temp = arr[j+1];        
                arr[j+1] = arr[j];
                arr[j] = temp;
            }
        }
    }
    
    return arr;
}

3:Python

def bubbleSort(arr):
    for i in range(1, len(arr)):
        for j in range(0, len(arr)-i):
            if arr[j] > arr[j+1]:
                arr[j], arr[j + 1] = arr[j + 1], arr[j]
    return arr

4:PHP

function bubbleSort($arr)
{
    $len = count($arr);
    for ($i = 0; $i < $len - 1; $i++) 
    {
        for ($j = 0; $j < $len - 1 - $i; $j++) 
        {
            if ($arr[$j] > $arr[$j+1]) 
            {
                $tmp = $arr[$j];
                $arr[$j] = $arr[$j+1];
                $arr[$j+1] = $tmp;
            }
        }
    }
    return $arr;
}

5:GO

func bubbleSort(arr []int) []int 
{
    length := len(arr)
    for i := 0; i < length; i++ 
    {
        for j := 0; j < length-1-i; j++ 
        {
            if arr[j] > arr[j+1] 
            {
                arr[j], arr[j+1] = arr[j+1], arr[j]
            }
        }
    }
    return arr
}

6:C++

void swap(int *a, int i, int j)
{
    int t = a[i];
    a[i] = a[j];
    a[j] = t;
}

void buddle_sort(int *a,int len)
{
    int max = len-1;
    int i,j;
    for (int i = 0; i < max; i++)
    {
        for (int j = 0; j < max-i; j++)
        {
            if (a[j+1] < a[j])
            {
                swap(a,j,j+1);
            }
        }
    }
}

声明:
一:博文中用到的动态效果图,录取自 vx 公众号《五分钟学算法》以及《程序员小灰》,对算法感兴趣的可以关注下。
二:文章思路开源项目地址,整理人 hustcc


结束语

如果这篇博客有幸帮到了您,欢迎点击下方链接,和更多志同道合的伙伴一起交流,一起进步。

Web开发者俱乐部

猜你喜欢

转载自blog.csdn.net/qq_42351033/article/details/101907701
今日推荐