排序算法系列之冒泡排序

冒泡排序

1 基本原理

核心思想:冒泡排序是一种典型的 交换排序 ,通过比较相邻元素大小来决定是否交换位置

2 实例说明

如上图所示,以一组数据{20,40,30,10,60,50} 为例,进行冒泡排序的算法演示:

  • 第一轮:从数组第一个元素开始,依次比较相邻元素,如:20与40比较,位置不变;40与30比较交换位置。。。。最后,最大元素60位于数组末尾。
  • 第二轮:重复上一步操作,将数组中第二大元素50交换至数组倒数第二位。
  • 重复上述操作
  • 第五轮,比较10与20,位置不变,完成最终排序

3 代码实现

// 冒泡排序(C++)
void swap(int& a, int& b)
{
    int tmp = a;
    a = b;
    b = tmp;
}

void BubbleSort(vector<int> &vi)
{
    for (int i = 0; i < vi.size() ; i++)
    {
        for (int j = 1; j < vi.size() - i; j++)
        {
            if (vi[j] < vi[j - 1])
            {
                swap(vi[j], vi[j - 1]);
            }
        }
    }
}

//冒泡排序的算法优化
void BubbleSort(vector<int> &vi)
{
    int lastExchangeIndex=0; //记录最后一次交换的位置

    int sortBorder=vi.size()-1; //无序数列的边界,边界后的元素以及排好序,无需比较

    for (int i = 0; i < vi.size() ; i++)
    {
        bool isSorted=true;//默认有序排列

        for (int j = 0; j < sortBorder; j++)
        {
            if (vi[j] < vi[j + 1])
            {
                swap(vi[j], vi[j + 1]);
                isSorted=false;//产生元素交换,不是有序排列
                lastExchangeIndex=j; //把无序数列的边界更新为最后一次交换元素的位置
            }
        }

        sortBorder=lastExchangeIndex;

        if(isSorted)
        {
            break;
        }
    }
}

算法改进说明:1,对于是否已经是有序排列进行判断;2,对已经排序好的元素不参与重复的比较。

4 性能分析

  • 1 时间复杂度
    (1)顺序排列时,冒泡排序总的比较次数为n-1(比较一轮后就跳出循环),移动次数为0;
    (2)逆序排序时,冒泡排序总的比较次数为n(n-1)/2,移动次数为n(n-1)/2次;
    (3)当原始序列杂乱无序时,平均时间复杂度为O(n^2)
  • 2 空间复杂度
    冒泡排序排序过程中,Swap函数需要一个临时变量temp进行两两交换,所需要的额外空间为1,因此空间复杂度为O(1)
  • 3 算法稳定性
    冒泡排序在排序过程中,元素两两交换时,相同元素的前后顺序并没有改变,所以冒泡排序是一种稳定排序算法

猜你喜欢

转载自blog.csdn.net/hlc246/article/details/81011753