数据结构与算法冒泡排序

冒泡排序的基本思想: 两两比较相邻的元素,如果反序则交换,直到没有反序的元素为止。
<一. 冒泡排序的初级版(交换排序)>
交换排序: 当前位置的元素与后面的元素比较。

//冒泡排序初级版(交换排序)--->当前位置的元素与后面的元素比较
void sortOne(int*arr,int len)
{
    for (int i=0;i<len-1;i++)
    {
        for (int n=i+1;n<len;n++)
        {
            if (arr[i]>arr[n])
            {
                int temp = arr[i];
                arr[i] = arr[n];
                arr[n] = temp;
            }
        }
    }
}

其实从严格意义来说,这并不是冒泡排序,因为这个算法并没有满足两两相邻元素比较。它的思想就是当前位置的元素与其后面的元素比较,如果反序则交换。经过第一次比较,其第一个位置的元素是最小值。
如图所示,我们观察第一次比较过程:
这里写图片描述
证明这个算法严格来说并不是冒泡算法。
接下来,这个算法的时间复杂度:(大O记法)

  • 最好时间复杂度: 数组本来就是有序的,只需要比较n-1次,则最好时间复杂度:O(n);
  • 最坏时间复杂度: n+n-1+…+1—->根据数列求和公式和大O记法可得:O(n^2);
  • 平均时间复杂度: O(n^2)

<二. 冒泡排序的正版>
冒泡排序: 从后面的元素开始,和前面的元素比较。

//冒泡排序的正版
void sortTwo(int*arr, int len)
{
    //确定前面有元素的个数
    for (int i=0;i<len-1;i++)
    {
        //从最后的元素比较
        for (int n=len-1;n>i;n--)
        {
            if (arr[n]<arr[n-1])
            {
                int temp = arr[n];
                arr[n] = arr[n - 1];
                arr[n - 1] = temp;
            }
        }
    }
}

如图所示,我们观察第一次比较过程:
这里写图片描述

这个算法的时间复杂度与前面的一样。


<三. 冒泡排序优化>
为了防止防止重复比较,我们添加变量对冒泡算法优化

//第一轮比较就可以出现结果,但是还是继续比较的
int arr[]={2,1,3,4,5};
//冒泡排序的优化(防止重复比较)
void sortThree(int*arr, int len)
{
    bool state = true;
    for (int i = 0; i<len - 1&&state==true; i++)
    {
        state = false;
        //从最后的元素比较
        for (int n = len - 1; n>i; n--)
        {
            if (arr[n]<arr[n - 1])
            {
                int temp = arr[n];
                arr[n] = arr[n - 1];
                arr[n - 1] = temp;

                state = true;
            }
        }
    }
}

其时间复杂度和前面的相同。

没有更多推荐了,返回首页