zoukankan      html  css  js  c++  java
  • 冒泡排序

    算法思路

    • 升序排列:

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

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

      例:使冒泡法升序排列8,1,6,3,2,4
      从左到右进行排序:
      第一轮:
      20190811213852.png
      第二轮:
      20190811214049.png
      第三轮:
      20190811214304.png
      第四轮:
      20190811214344.png
      本轮中没有发生元素交换,就表示剩下的元素都是有序的,所以所有元素已经都是有序的了。

    代码实现

    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("
    ");
    }
    
    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]));
      }
    }
    

    测试结果:
    20190811214924.png

    时间复杂度分析

    核心部分代码如下,假设待排序元素有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)

    稳定性

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

     

  • 相关阅读:
    mongodb群集
    AtoS查看iOS Crash log中的16进制代码日志
    Info.plist 的字段解释
    IOS --关于粘贴板 ,剪切板 ,UILabel的复制
    UItableView 所有内容保存为图片
    ios 工程图片清理shell
    检查项目图片是否被使用
    ios 联网 在mac机器上进行抓包
    还在为不停build 烦恼么?看这里~~
    修复OS X的Finder中文档 打开方式中重复程序的问题
  • 原文地址:https://www.cnblogs.com/UnknowCodeMaker/p/11337737.html
Copyright © 2011-2022 走看看