冒泡排序

思想

  首先要明确的是,已排序序列在后,待排序序列在前,第一轮的待排序序列就是整个序列;每一轮都从待排序序列首部开始,比较相邻元素,如果前一个元素比后一个元素大,则交换两元素的位置,这么一轮下来,本轮最大的那个元素就到了末尾,成为已排序序列,待排序序列的元素个数相应减1,不断重复,最终达到完全有序

代码实现

普通版:

void sortBubble(vector<int>& nums)
{
    int n = nums.size();
    for (int count = 0; count < n - 1; ++count)//count表示已经有count个最大元素在末尾,循环n-1次
    {
        for (int i = 0; i <= n - 2 - count; ++i)
        {
            if (nums[i] > nums[i + 1])
                swap(nums[i], nums[i + 1]);
        }
    }
}

改良版:

加入change变量,一轮下来,元素有交换的话,change为true,没有交换,则为false;

一轮下来都没有元素交换的话,那么下一趟就肯定不会有交换了,那就提前跳出循环吧;

void sortBubble(vector<int>& nums)
{
    int n = nums.size();
    for (int count = 0; count < n - 1; ++count)//count表示已经有count个最大元素在末尾,循环n-1次
    {
        bool change = false;
        for (int i = 0; i <= n - 2 - count; ++i)
        {
            if (nums[i] > nums[i + 1])
            {
                swap(nums[i], nums[i + 1]);
                change = true;
            }
        }
        if (change == false)
            break;
    }
}

单循环版

通过在循环体内部改变循环变量 i 和循环中止变量的值来实现单循环冒泡,其实就是把双循环展开成单循环,没什么很大的不同

void sortBubble(vector<int>& nums)
{
    int times = nums.size() - 1;
    bool change = false;
    for (int i = 0; i < times; ++i)//循环n-1次
    {
        if (nums[i] > nums[i + 1])
        {
            swap(nums[i], nums[i + 1]);
            change = true;
        }
        if (i == times - 1)//最后一次时
        {
            if (change == false)
                break;
            i = -1;//等会for循环会++i,i变为0
            --times;
            change = false;
        }
    }
}

时间复杂度

  最好情况O(n):本身有序,比较完第一轮后就不用比较了,比较次数为n-1次

  最坏情况O(n2):本身逆序

  平均情况O(n2)

空间复杂度

  O(1)

稳定性

  都是对相邻元素交换,这种相邻关系可以保证相同元素排序前后的相对顺序不变,所以是稳定的

原文地址:https://www.cnblogs.com/Joezzz/p/9647163.html