冒泡排序

雨燕双飞 提交于 2019-11-27 02:14:25

 

算法思路

  • 升序排列:

    • 从左到右(或右到左)比较相邻的元素,如果当前元素比下一个元素大(或者小),就交换他们两个。
    • 对下一对相邻元素做同样的工作,从开始第一对到结尾的最后一对,本轮排序完成后得到无序部分中的最大元
      素,此时这个最大元素和之前的已经排序的部分,组成新的有序部分
    • 针对所有的无序元素重复以上的步骤,直到某一轮没有发生元素交换则说明排序完成
  • 降序排列:

    • 从左到右(或右到左)比较相邻的元素,如果当前元素比下一个元素小(或者大),就交换他们两个。
    • 对下一对相邻元素做同样的工作,从开始第一对到结尾的最后一对,本轮排序完成后得到无序部分中的最大元
      素,此时这个最大元素和之前的已经排序的部分,组成新的有序部分
    • 针对所有的无序元素重复以上的步骤,直到某一轮没有发生元素交换则说明排序完成

    例:使冒泡法升序排列8,1,6,3,2,4
    从左到右进行排序:
    第一轮:


    第二轮:


    第三轮:


    第四轮:


    本轮中没有发生元素交换,就表示剩下的元素都是有序的,所以所有元素已经都是有序的了。

代码实现

bool BubbleSort(int * pUnSortAry, int nArySize)  {    if (pUnSortAry == nullptr || nArySize <= 0)    {      return false;    }      bool bFlag = false;    for (int iIndex = 0; iIndex < nArySize; iIndex++)    {      for (int jIndex = 0; jIndex < nArySize - iIndex -1; jIndex++)      {        if (pUnSortAry[jIndex] > pUnSortAry[jIndex + 1])        {          int nTemp = pUnSortAry[jIndex];          pUnSortAry[jIndex] = pUnSortAry[jIndex + 1];          pUnSortAry[jIndex + 1] = nTemp;          bFlag = true;        }      }        if (!bFlag)      {        break; //如果内存for循环中一次交换也没有发生,则说明所有元素已经有序      }    }    return true;  }  

测试代码:

void PrintData(int*pAry, int nSize)  {    for (int jIndex = 0; jIndex < nSize; jIndex++)    {      printf("%d ", pAry[jIndex]);    }    printf("\r\n");  }    int main()  {    srand(time(NULL));      int nArry[20] = { 0 };      for (int jIndex = 0; jIndex < 10; jIndex++)    {      for (int iIndex = 0; iIndex < sizeof(nArry) / sizeof(nArry[0]); iIndex++)      {        nArry[iIndex] = rand() % 150;      }      printf("排序前:");      PrintData(nArry, sizeof(nArry) / sizeof(nArry[0]));      BubbleSort(nArry, sizeof(nArry) / sizeof(nArry[0]));      printf("排序后:");      PrintData(nArry, sizeof(nArry) / sizeof(nArry[0]));    }  }  

测试结果:

时间复杂度分析

核心部分代码如下,假设待排序元素有n个

//执n次  for (int iIndex = 0; iIndex < nArySize; iIndex++)    {         //执行1+2+.....+n次      for (int jIndex = 0; jIndex < nArySize - iIndex -1; jIndex++)      {        //执行1+2+.....+(n-1)次        if (pUnSortAry[jIndex] > pUnSortAry[jIndex + 1])        {            //执行(1/n)*(1+2+3...+n-1)            int nTemp = pUnSortAry[jIndex];            pUnSortAry[jIndex] = pUnSortAry[jIndex + 1];            pUnSortAry[jIndex + 1] = nTemp;            bFlag = true;        }      }        //执行n次      if (!bFlag)      {        //执行一次          break; //如果内存for循环中一次交换也没有发生,则说明所有元素已经有序      }  }  

平均时间复杂度为:T(n) =n+n+(1+2....+n) + (1+2....+(n-1)) + (1/n)(1+2+3...+n-1))
= 2n + 2
(1+2...+n) - n + (1/n)*(1+2+3...+n-1 + n) -1
= n + n(1+n) + (1/2n)*n(1+n) -1
= n^2 + (5n)/2 -1/2
= O(n^2)

当元素已经是有序的情况下时间复杂度为T(n)=O(n)

稳定性

冒泡排序就是把小的元素往前调或者把大的元素往后调。比较是相邻的两个元素比较,交换也发生在这两个元
素之间。所以,如果两个元素相等,则不会进行交换如果两个相等的元素没有相邻,那么即使通过前面的两两
交换把两个相邻起来,这时候也不会交换,所以相同元素的前后顺序并没有改变,所以冒泡排序是一种稳定排
序算法。

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!