数据结构与算法 - 冒泡排序

冒泡排序

冒泡排序无疑是最为出名的排序算法之一,从序列的一端开始往另一端冒泡(你可以从左往右冒泡,也可以从右往左冒泡,看心情),依次比较相邻的两个数的大小(到底是比大还是比小也看你心情)。

image

[ 8,2,5,9,7 ]为例,对它进行冒泡排序:
从左往右依次冒泡,将小的往右移动

第一轮

image

首先比较第一个数和第二个数的大小,我们发现 2 比 8 要小,那么保持原位,不做改动。位置还是 8,2,5,9,7 。

指针往右移动一格,接着比较:

image

比较第二个数和第三个数的大小,发现 2 比 5 要小,所以位置交换,交换后数组更新为:[ 8,5,2,9,7 ]

指针再往右移动一格,继续比较:

image

比较第三个数和第四个数的大小,发现 2 比 9 要小,所以位置交换,交换后数组更新为:[ 8,5,9,2,7 ]

同样,指针再往右移动,继续比较:

image

比较第 4 个数和第 5 个数的大小,发现 2 比 7 要小,所以位置交换,交换后数组更新为:[ 8,5,9,7,2 ]

下一步,指针再往右移动,发现已经到底了,则本轮冒泡结束,处于最右边的 2 就是已经排好序的数字。

通过这一轮不断的对比交换,数组中最小的数字移动到了最右边。

第二轮

接下来继续第二轮冒泡:

image
image
image

由于右边的 2 已经是排好序的数字,就不再参与比较,所以本轮冒泡结束,本轮冒泡最终冒到顶部的数字 5 也归于有序序列中,现在数组已经变化成了[ 8,9,7,5,2 ]

image

第三轮

image
image

由于 8 比 7 大,所以位置不变,此时第三轮冒泡也已经结束,第三轮冒泡的最后结果是[ 9,8,7,5,2 ]

第四轮

紧接着第四轮冒泡:

image

9 和 8 比,位置不变,即确定了 8 进入有序序列,那么最后只剩下一个数字 9 ,放在末尾,自此排序结束。

代码实现

vector<int> bubble_sort(vector<int> &arr)
{
    int aSize = arr.size();
    for(int i = 0; i < aSize - 1; i++)
    {
        bool isChange = false;
        for(int j = 0; j < aSize - 1 - i; j++)
        {
            if(arr[j] > arr[j+1])
            {
                // swap arr[j] and arr[j+1]
                arr[j] = arr[j] ^ arr[j+1];
                arr[j+1] = arr[j] ^ arr[j+1];
                arr[j] = arr[j] ^ arr[j+1];
                isChange = true;
            }
        }
        if(!isChange)
        {
            break;
        }
    }
    return arr;
}

特点

稳定性:它是指对同样的数据进行排序,会不会改变它的相对位置。比如 [ 1, 3, 2, 4, 2 ] 经过排序后,两个相同的元素 2 位置会不会被交换。冒泡排序是比较相邻两个元素的大小,显然不会破坏稳定性。

空间复杂度:由于整个排序过程是在原数据上进行操作,故为 \(O(1)\) ;

时间复杂度:由于嵌套了 2 层循环,故为 \(O(n^2)\);

posted @ 2021-12-13 13:49  Logan_Xu  阅读(64)  评论(0编辑  收藏  举报