论坛交流
首页办公自动化| 网页制作| 平面设计| 动画制作| 数据库开发| 程序设计| 全部视频教程
应用视频: Windows | Word2007 | Excel2007 | PowerPoint2007 | Dreamweaver 8 | Fireworks 8 | Flash 8 | Photoshop cs | CorelDraw 12
编程视频: C语言视频教程 | HTML | Div+Css布局 | Javascript | Access数据库 | Asp | Sql Server数据库Asp.net  | Flash AS
当前位置 > 文字教程 > C语言程序设计教程
Tag:新手,函数,指针,数据类型,对象,Turbo,入门,运算符,数组,结构,二级,,tc,游戏,试题,问答,编译,视频教程

两中种简单排序算法分析

文章类别:C语言程序设计 | 发表日期:2008-9-24 14:46:23

将要处理的信息按照某种次序重新排列,使之有序,称为排序(或分类)。在信息处理中,排序是最基本的运算之一。随着计算机数据处理技术的不断发展,各种各样的排序方法层出不穷,下面将跟大家介绍的是两种最简单,并且轻易实现的排序算法。

直接插入排序类似于玩扑克牌时整理手上的扑克,每次从扑克堆中摸最上面一张,插到左手的扑克牌的适当位置,当把扑克堆中的所有扑克牌全部摸完并插入到左手上,左手上的扑克牌也同时整理好了(即有序了)。在程序设计中,直接插入排序的基本思想是:每次将一个待排序的记录,按照要害字大小插入到已经排好序的序列(有序区)中,直到所有待排序记录全部插入完毕。

在进行直接插入排序时,有两个要害问题需要考虑:

一、将待排序的记录插入到有序区中的什么位置?即插入位置的确定。

二、在插入之前,必须先将需要插入记录的位置腾出来,以便待排序的记录能够插入。

例: 输入 10 个学生的信息技术考试成绩,按照从低到高的顺序输出(递增排序)。

分析: 10 个学生的成绩不妨保存在一个数组 a 中,现在需要对数组 a 进行递增排序。按照直接插入排序的思想,首先将记录 a(1) 插入有序区中,由于在 a(1) 插入之前有序区为空,所以 a(1) 的插入不存在插入位置的确定问题。接着插入 a(2) ,在 a(2) 插入之前,有序区中已经有了一个记录 a(1) ,这时就必须先确定一下插入位置,是在 a(1) 之前,还是在 a(1) 之后。按照递增排序的要求,假如 a(1)>a(2) ,就应该将 a(2) 插入在 a(1) 之前,反之,则将 a(2) 插入在 a(1) 之后。 a(1) 已经处于数组的边界,它的左边已经不能再插入记录,所以我们还必须要做一件事:将 a(1) 向右移动一个位置,腾出一个空位,以便将 a(2) 插入。接下来,按照同样的方法,依次将 a(3) 、 a(4) 、 a(5) 、…… a(10) 插入有序区。当无序区中的所有记录全部插入到有序区后,整个排序工作也就完成了,如图。

通过上面分析,可以归纳出用直接插入排序算法对数组 a 进行递增排序的步骤:

(1) 将 a(1) 直接插入有序区;

(2) 在有序区中进行搜索,找到下一个待排序记录的插入位置(插入点);

(3) 将插入点右边的记录整体向右移动一个位置;

(4) 插入待排序记录;

(5) 重复执行( 2 )到( 4 )步,直到无序区中的所有记录全部插入到有序区。

参考程序如下:

CLS

DIM a(10) AS INTEGER

rem 输入数据

FOR i = 1 TO 10

INPUT a(i)

NEXT i

rem 直接插入排序

FOR i = 2 TO 10

rem 设置监视哨 a(0) (监视哨有两个好处:一是在记录右移的过程中,可以防止元素 a(i) 的值丢失;二是可以监视数组下标是否出界)

a(0) = a(i)

rem 搜索插入位置

k = i - 1

WHILE a(i) < a(k)

k = k - 1

WEND

rem 移动记录

j = i - 1

DO UNTIL j < k + 1

a(j + 1) = a(j)

j = j - 1

LOOP

rem 出入待排序记录

a(k + 1) = a(0)

NEXT i

rem 输出数据

FOR i = 1 TO 10

PRINT a(i);

NEXT i

END

上面的直接排序算法,我们是将搜索插入位置和移动记录两个过程分开,即先执行第( 2 )步,完成插入位置的确定问题,再执行第( 3 )步,将插入点右边的记录整体向右移动一个位置。实际上,我们可以将这两个过程结合起来,交替进行。参考程序如下:

CLS

DIM a(10) AS INTEGER

FOR i = 1 TO 10

INPUT a(i)

NEXT i

rem 直接插入排序

FOR i = 2 TO 10

a(0) = a(i)

j = i - 1

x = a(i)

WHILE x < a(j)

a(j + 1) = a(j)

j = j - 1

WEND

a(j + 1) = a(0)

NEXT i

FOR i = 1 TO 10

PRINT a(i);

NEXT i

END

冒泡排序的基本思想是:将要排序的记录竖直放置,按从上到下的顺序对记录两两进行比较,保证轻者(要害字小的记录)在上,重者(要害字大的记录)在下;在比较的过程中,假如发现有违反“轻者在上,重者在下”这条原则的,就将两个记录进行交换;就像水中的气泡一样,轻的总是往上漂;这样对记录进行扫描,当完成第一趟扫描以后,最大的记录自然会沉到最底部。接着对记录进行第二趟扫描、第三趟扫描、……直到所有记录都是轻者在上,重者在下为止。

还是以上面对 10 个学生的信息技术考试成绩进行递增排序为例,用冒泡思想进行排序的过程是:首先将 a(1) 和 a(2) 进行比较,若 a(1)>a(2) ,则将 a(1) 和 a(2) 进行交换,然后比较 a(2) 和 a(3) 、 a(3) 和 a(4) 、……依此类推,直到将最后两个记录 a(9) 和 a(10) 进行比较为止,如图。

上述过程称为第 1 趟冒泡排序,其结果是使得要害字最大的记录沉到数组的最底部(即被安置到最后一个记录 a(10) 的位置)。

然后进行第 2 趟冒泡排序(对前 9 个记录进行同样的操作),使得要害字次大的记录被安置到倒数第 2 个记录 a(9) 的位置。依此类推,进行第 3 趟、第 4 趟、……如图 3

显然,冒泡排序主要进行两个操作:比较和交换。

这里还有一个要害问题需要考虑:排序过程需要进行多少趟,即判别冒泡排序结束的条件是什么?

如图,我们可以假设再进行第 10 趟排序,很轻易看出,第 10 趟排序将不会进行任何交换操作,因为经过第 9 趟排序之后,数组中的数据已经递增有序了。据此,我们不妨将判别冒泡排序结束的条件定为:在一趟排序过程中没有进行过记录的交换。

用冒泡排序算法对 10 个学生的信息技术考试成绩进行递增排序的参考程序如下:

CLS

DIM a(10) AS INTEGER

rem 输入数据

FOR i = 1 TO 10

INPUT a(i)

NEXT i

rem 冒泡排序

i = 1

exchange = 1

rem 初始化标志 exchange (用来标识是否进行过交换操作, exchange=1 表示进行过交换操作, exchange=0 表示未进行过交换操作)

DO UNTIL i > 10 OR exchange = 0

exchange = 0

FOR j = 1 TO 10 - i

IF a(j + 1) < a(j) THEN

a(0) = a(j + 1)

a(j + 1) = a(j)

a(j) = a(0)

rem 交换 a(j+1) 和 a(j)

exchange = 1

END IF

NEXT j

i = i + 1

LOOP

rem 输出数据

FOR i = 1 TO 10

PRINT a(i);

NEXT i

END

结束语: 对 10 个学生的信息技术考试成绩按递增排序,这样一个简简单单的问题,这里随随便便就给出了三种解决办法。由此可见,很多问题,非凡是程序设计问题,它的解决办法不是一成不变的。在学习程序设计的过程中,我们要善于打破固定的思维模式,把学习的重点放到对问题解决方法的学习上来。 

注:此文刊于《中学生电脑》杂志2003年第1期

上一篇:{应用}迭代算法解题的一般思路 人气:4784
下一篇:{应用}初识回溯算法 人气:4668
视频教程列表
文章教程搜索
 
C语言程序设计推荐教程
C语言程序设计热门教程
看全部视频教程
购买方式/价格
购买视频教程: 咨询客服
tel:15972130058