3.排序

3.1冒泡排序
冒 泡排序的名字来源于其工作方式,在这种排序算法中,较小的数一个一个往水面上“冒”,最终所有数均变成了由小到大排列。在冒泡排序算法中我们要对待排序的 对象序列进行若干遍处理,处理的过程是:自底向上检查序列,并比较相邻对象的大小。如果发现两个相邻对象的顺序不对(较小对象在后面),就交换它们的位 置。经过一遍处理之后,最小的对象就“冒”到了最前面的位置;经过第二遍处理,次小的对象又“冒”到了次前位置,依此类推。
void CSortDlg::OnBubbleSort()
{
  CClientDC dc(this);
  dc.SetBkColor(RGB(180, 180, 180));
  int objectName[SORT_OBJECT_NUM]; //每个位置对应的成员名
  //初始化每个位置对应的成员
  for (int i = 0; i < SORT_OBJECT_NUM; i++)
  {
    objectName[i] = i;
  }
  //冒泡排序
  for (i = 1; i < SORT_OBJECT_NUM; i++)
  {
    for (int j = SORT_OBJECT_NUM - 1; j >= i; j--)
    {
      if (sortObject[objectName[j]].iNumber < sortObject[objectName[j -
        1]].iNumber)
      {
        //交换成员序号
        int iTemp;
        iTemp = sortObject[objectName[j - 1]].iSeq;
        sortObject[objectName[j - 1]].iSeq = sortObject[objectName[j]].iSeq;
        sortObject[objectName[j]].iSeq = iTemp;
        //交换成员位置
        iTemp = objectName[j];
        objectName[j] = objectName[j - 1];
        objectName[j - 1] = iTemp;
        //显示新位置
        CString strName;
        CString strNum;
        //显示j-1位置的成员
        strName.Format("%d", objectName[j - 1]);
        dc.TextOut(objectCoord[sortObject[objectName[j - 1]].iSeq].x - 5,
          objectCoord[sortObject[objectName[j - 1]].iSeq].y - 8, strName);
        if (sortObject[objectName[j - 1]].iNumber < 1000)
        {
          strNum.Format("  %d", sortObject[objectName[j - 1]].iNumber);
        }
        else
        {
          strNum.Format("%d", sortObject[objectName[j - 1]].iNumber);
        }
        dc.TextOut(objectCoord[sortObject[objectName[j - 1]].iSeq].x - 15,
          objectCoord[sortObject[objectName[j - 1]].iSeq].y - 30, strNum);
        //显示j位置的成员
        strName.Format("%d", objectName[j]);
        dc.TextOut(objectCoord[sortObject[objectName[j]].iSeq].x - 5,
          objectCoord[sortObject[objectName[j]].iSeq].y - 8, strName);
        if (sortObject[objectName[j]].iNumber < 1000)
        {
          strNum.Format("  %d", sortObject[objectName[j]].iNumber);
        }
        else
        {
          strNum.Format("%d", sortObject[objectName[j]].iNumber);
        }
        dc.TextOut(objectCoord[sortObject[objectName[j]].iSeq].x - 15,
          objectCoord[sortObject[objectName[j]].iSeq].y - 30, strNum);
        //延迟1秒进行下一次排序以便将排序过程显示为动画
        Sleep(1000);
      }
    }
  }
}
通过运行上述程序,我们非常清晰地看到了较小的数冒泡的全过程,这是缘于我们在每次排序之间利用Sleep(1000)插入了1秒钟的延迟。下面是我们追踪所得的一次冒泡排序的轨迹:
196 3993 2037 2953 318 2815 5770 960 7325 486
196 3993 2037 2953 318 2815 5770 960 486 7325
196 3993 2037 2953 318 2815 5770 486 960 7325
196 3993 2037 2953 318 2815 486 5770 960 7325
196 3993 2037 2953 318 486 2815 5770 960 7325
196 3993 2037 318 2953 486 2815 5770 960 7325
196 3993 318 2037 2953 486 2815 5770 960 7325
196 318 3993 2037 2953 486 2815 5770 960 7325
196 318 3993 2037 2953 486 2815 960 5770 7325
196 318 3993 2037 2953 486 960 2815 5770 7325
196 318 3993 2037 486 2953 960 2815 5770 7325
196 318 3993 486 2037 2953 960 2815 5770 7325
196 318 486 3993 2037 2953 960 2815 5770 7325
196 318 486 3993 2037 960 2953 2815 5770 7325
196 318 486 3993 960 2037 2953 2815 5770 7325
196 318 486 960 3993 2037 2953 2815 5770 7325
196 318 486 960 3993 2037 2815 2953 5770 7325
196 318 486 960 2037 3993 2815 2953 5770 7325
196 318 486 960 2037 2815 3993 2953 5770 7325
196 318 486 960 2037 2815 2953 3993 5770 7325
仔细的观察上述过程可以帮助我们更好地理解冒泡排序的内涵。下面的动画(GIF格式)演示了冒泡排序的过程:
对于n个待排序成员,冒泡排序需要进行n(n-1)/2次比较,平均情况下需进行3n(n-1)/4次交换;因为每交换一对不合顺序的元素,需进行三次操作,所以最坏情况下,交换次数是比较次数的三倍,即3n(n-1)/2 。因此,冒泡法是效率最差的排序方法,一般只适合于数组较小的情况。
因此,有学者提出了“拉锯法”、“双边冒泡法”等改进措施。“拉锯法”不再是总按同一方向读数组元素,而是这一遍从下到上把最小的送到最前面,下一遍从上到下把最大的元素送到最后面;“双边冒泡法”则每次除了冒出最小元素外,还“下沉”最大元素。
本文转自 21cnbao 51CTO博客,原文链接:http://blog.51cto.com/21cnbao/120750,如需转载请自行联系原作者

从趣味游戏到排序算法(2)相关推荐

  1. 伍六七带你学算法 进阶篇-排序算法

    给定一个整数数组 nums,将该数组升序排列. 示例 1: 输入:[5,2,3,1] 输出:[1,2,3,5] 示例 2: 输入:[5,1,1,2,0,0] 输出:[0,0,1,1,2,5] 各排序算 ...

  2. C++排序算法实现(更新中)

    比较排序法:如冒泡排序.简单选择排序.合并排序.快速排序.其最优的时间复杂度为O(nlogn). 其他排序法:如桶排序.基数排序等.时间复杂度可以达到O(n).但试用范围有要求. 桶排序:排序的数组元 ...

  3. 十种经典排序算法精粹(c语言版本)

    下面给出这段时间我苦心研究验证过的十种经典排序算法的C语言版本,即下面的排序算法: 插入排序,shell排序,冒泡排序,快速排序,选择排序,堆排序,归并排序,桶排序,基数排序和计数排序.整理出来以作备 ...

  4. 十大排序算法 导图总结

    以下为我们经常用到的十大典型排序算法导图,很多设计以及优化的思想值得去参考学习 因为代码较多,所以都添加到对应的实现注释中了,相关代码可以从Mind-mapping获取xmind源文件 参考文档: 基 ...

  5. C++实现十大排序算法(冒泡,选择,插入,归并,快速,堆,希尔,桶,计数,基数)排序算法时间复杂度、空间复杂度、稳定性比较(面试经验总结)

    排序算法分类 内部排序算法又分为基于比较的排序算法和不基于比较的排序算法,其分类如下: 比较排序:   直接插入排序    希尔排序 (插入)  冒泡排序     快速排序  (交换) 直接选择排序  ...

  6. C++拾取——使用stl标准库实现排序算法及评测

    今天看了一篇文章,讲各种语言的优势和劣势.其中一个观点:haskell非常适合写算法,因为使用者不用去关心具体的计算机实现,而只要关注于操作语义.这让它在专心研究算法的人中非常受欢迎.所以很多时候,语 ...

  7. 常用排序算法的C++实现

    排序是将一组"无序"的记录序列调整为"有序"的记录序列. 假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在 ...

  8. python 排序算法 简书_Python---简析八大排序算法

    前言 1 .排序的概念 排序是计算机内经常进行的一种操作,其目的是将一组"无序"的记录序列调整为"有序"的记录序列. 排序分为内部排序和外部排序. 若整个排序过 ...

  9. php常见排序算去,PHP兑现常见排序算法

    PHP实现常见排序算法 //插入排序(一维数组) function insert_sort($arr){ $count = count($arr); for($i=1; $i $tmp = $arr[ ...

最新文章

  1. 第31讲 UI组件之 Gallery画廊控件
  2. 扫描指定包并解析为BeanDefinition
  3. HashMap、TreeMap、Hashtable、HashSet和ConcurrentHashMap区别
  4. win7 64 php mysql_win7 64 搭建 64 位 apache httpd php mysql
  5. java工作笔记017---java8新特性_使用lamda表达式进行List分组_排序_去重_随时更新
  6. 类型xxx 无法反序列化。缺乏对应的数据成员。
  7. windows和Linux虚拟机或者云主机之间传输文件
  8. Bleu:此'蓝'非彼蓝
  9. 通过里程碑式管理,控制软件项目管理进度
  10. CentOS 6.9 下安装DB2
  11. JAVA窗口——Frame
  12. 一文读懂YUV的采样与格式
  13. 远程计算机桌面图标不见了怎么办,远程桌面图标不见了怎么办
  14. 如何保证虚拟机ip地址不变
  15. java 时间英文格式_Java SimpleDateFormat 中英文时间格式化转换
  16. Chrome打开网页不慢,但是卡顿,滚动滚轮卡顿,打开b站等特定网址卡顿问题解决
  17. 我在首席数据官年会上的演讲实录
  18. 程序员最爱用的在线代码编辑器合集,哪款是你的最爱?
  19. ART虚拟机 | Cleaner机制源码分析
  20. Python 高德地图经纬度与地址相互解析

热门文章

  1. java 弹出下载_java怎么实现下载弹出的对话框
  2. Matlab中3条曲线归一,matlab中关于数据归一化函数mapminmax的使用
  3. linux ddd yum,Linux环境ddd安装与使用
  4. 工程计算软件_同望BIM工程量计算软件—土石方
  5. lampp mysql 等待响应时间很长_Apache 打开网页的时候等待时间过长的解决方案
  6. redis的bitmap操作
  7. 服务器查内存型号,服务器怎样查内存型号
  8. mysql第四步安装失败_MySQL8.0版本的安装以及解决安装后MySQL服务无法启动的问题...
  9. C语言 system
  10. 图解TCPIP-传输层 UDP