}
程序执行后提示:
Input7integers:
8351972
2791538
【例4.4】某班有10个学生,进行了数学考试,现要求将数学成绩按由低到高的顺序排序。
(对应习题4.9)
分析:
排序是指将一组无序的数据按从小到大(升序)或从大到小(降序)的次序重新排列。
排序的方法很多,这里介绍两种简单的排序方法—冒泡法和选择法。
(1)冒泡法
333
552
225
666
777
75555
57666
66733
33372
22227
5555
6633
3362
2226
7777
32
23
55
66
77
第1轮比较4次
第2轮比较3次
第3轮比较2次
第4轮比较1次
图4.4冒泡排序法
先举一实例来说明冒泡法排序:
要求将5个数7、5、6、3、2按从小到大的次序排列。
排序方法如图4.4所示。
第一轮第1次将第1个数7和第2个数5进行比较,因7大于5,所以将它们交换,第2次将第2个数7和第3个数6进行比较,因7大于6,所以将它们交换,依次类推共进行5-1=4次,这时,第1轮比较结束,可以看到:
最大的数7已“沉底”,即成为最下面的一个数,而小的数“上升”。
第2轮第1次将第1个数5和第2个数6进行比较,因5小于6,所以不变,依次类推共进行5-1-1=3次(因第5个数已是最大数,所以不必再将第4个数与第5个数进行比较,所以少1次),这时第2轮比较结束,得到3、5、2、6、7的数据序列。
以此类推,第3轮进行2次比较,得到3、2、5、6、7的数据序列。
第4轮进行1次比较,得到2、3、5、6、7的数据序列,完成了排序工作。
所以,对5个数进行排序,要进行4轮比较,在第1轮中要进行4次相邻两个数之间的比较,在第2轮中要进行3次相邻两个数之间的比较,在第3轮中要进行2次相邻两个数之间的比较,在第4轮中只进行1次相邻两个数之间的比较,在比较时,如果前面一个数大于后面一个数,则要交换它们的值,否则就不变。
这样才能使5个数按从小到大的次序排列。
这种排序方法被形象地称为“冒泡法”,在排序的过程中,小的数就象气泡一样逐层上冒,而大的数则逐个下沉。
在程序设计时,可以将这5个数存入到一个数组a中,然后用双重循环来实现其排序操作,外循环用变量i控制轮次,i的值从1到5-1(4),内循环用变量j控制第i轮中比较的次数,j从0到5-1-i。
流程图如图4.5所示,程序如下:
fori=0toN-1
输入a[i]
fori=1toN-1
forj=0toN-i-1
真
假
a[j]与a[j+1]交换
fori=0toN-1
输出a[i]
图4.5冒泡法排序流程图
a[j]>a[j+1]
#include
#include
#defineN10
voidmain(void)
{floata[N],temp;
inti,j;
cout<<"Inputscore:
";
for(i=0;i<=N-1;i++)
cin>>a[i];
for(i=1;i<=N-1;i++)
for(j=0;j<=N-i-1;j++)
if(a[j]>a[j+1])
{temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
}
for(i=0;i<=N-1;i++)
cout<cout<}
程序运行后,提示:
Inputscore:
90786896887567859284
输出:
67687578848588909296
冒泡升序排序算法关键步骤:
定义数组为a[N],数据输入到a[0]~a[N-1],用双循环:
i=1toN-1,j=0toN-1-iifa[j]>a[j+1]则交换。
(2)选择法
222
333
765
677
556
75532
57777
66666
33355
22223
2222
7653
6777
5566
3335
22
33
55
76
67
第1轮
第2轮
第3轮
第4轮
图4.6选择排序法
同样,先举一实例来说明选择法排序:
要求将5个数7、5、6、3、2按从小到大的次序排列。
排序方法如图4.6所示。
选择排序法的基本思想是先用求最小值算法找出5个数中的最小数2,将它放在第1个数的位置;然后在余下的4个数中找出最小数3,将它放在第2个数的位置;再在余下的3个数中找出最小数5,将它放在第3个数的位置,以此类推,就能将5个数按从小到大的次序排列好。
具体实现方法是:
第1轮第1次将第1个数7与第2个数5进行比较,因7大于5,所以将它们交换,使第1个数成为5,第2次将第1个数5与第3个数6进行比较,因5小于6,所以保持原状不变。
按此方法进行5-1=4次。
这时第一轮结束,可以看到:
5个数中的最小数2已处在第1个数的位置,得到2、7、6、5、3的数据序列。
第2轮时,因第1个数已是5个数中的最小数,所以不必参与比较,只要将第2个数与其下一个数(即第3个数)到最后一个数(即第5个数)逐一进行比较,若第2个数比后面的一个数大,则要交换它们的值,否则不变,第2轮比较结束时,得到2、3、7、6、5的数据序列;以此类推,共进行4轮比较就可以将5个数按从小到大的次序排列好,得到2、3、5、6、7的数据序列。
一般情况下,将N个数按从小到大的次序排序要进行N-1轮比较,第i轮比较是取出第i个数,让它与其下一个数(即第i+1个数)到最后一个数(即第N个数)逐一进行比较,若第i个数比后面的一个数大,则要交换它们的值,否则就不变。
在设计程序时,可以将N个数存入到一个数组a中,然后用双重循环来实现其排序操作,外循环用变量i作为第i轮比较时取出的第i个数的下标,i的值从1到N-1,内循环用变量j作为与第i个数进行比较的数的下标,j的值从i+1到N。
流程图如图4.7所示,程序如下:
#include
#include
#defineN10
voidmain(void)
{floata[N+1],temp;
fori=1toN
输入a[i]
fori=1toN-1
forj=i+1toN
真
假
a[i]与a[j]交换
fori=1toN
输出a[i]
a[i]>a[j]
图4.7选择法排序流程图
inti,j;
cout<<"Inputscore:
";
for(i=1;i<=N;i++)
cin>>a[i];
for(i=1;i<=N-1;i++)
for(j=i+1;j<=N;j++)
if(a[i]>a[j])
{temp=a[i];
a[i]=a[j];
a[j]=temp;
}
for(i=1;i<=N;i++)
cout<cout<}
说明:
本例程序中,定义数组a的长度为N+1,即11,a[0]不用,只用a[1]到a[10],以符合人们的习惯。
选择升序排序算法关键步骤:
定义数组为a[N+1],数据输入到a[1]~a[N],用双循环:
i=1toN-1,j=i+1toNifa[i]>a[j]则交换。
思考题:
若定义数组为a[N],数据输入到a[0]~a[N-1],循环变量i、j应如何取值。
提示:
for(i=0;ifor(j=i+1;ja11a12…a1n
a21a22…a2n
A=…………
am1am2…amn
4.1.2多维数组的定义和使用
二维数组是一个m行n列矩阵。
即:
1.二维数组的定义与初始化赋值
(1)定义格式:
〔存储类型〕<类型><数组名>[][];
其中:
m、n为常量表达式,m=数组行数,n=数组列数。
例如:
inta[3][4];
表示定义了一个3行4列共12个元素的二维整型数组a,数组中各元素分别为:
a[0][0]a[0][1]a[0][2]a[0][3]
a[1][0]a[1][1]a[1][2]a[1][3]
a[2][0]a[2][1]a[2][2]a[2][3]
可以把二维数组看作为一种特殊的一维数组,即它的每一个元素又是一个一维数组。
(2)二维数组的初始化赋值
二维数组初始化赋值的方法有:
①所有元素赋初值
给数组的所有元素赋初值的方法有两种:
方法一:
{{0行初值},{1行初值},…,{m行初值}}
即每行一个花括号,花括号间用逗号分隔,全部初值再用一个花括号。
例如:
inta[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};
方法二:
{0行初值,1行初值,…,m行初值}
所有初值放在一个花括号中,按数组排列的顺序给各元素赋初值。
例如:
inta[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};
注意:
若对所有元素都赋初值,则定义数组时行数可不指定,而列数必须指定。
图4.8二维数组的存储方式
a[0][0]
1
a[0][1]
2
a[0][2]
3
a[0][3]
4
a[1][0]
5
a[1][1]
6
a[1][2]
7
a[1][3]
8
a[2][0]
9
a[2][1]
10
a[2][2]
11
a[2][3]
12
例如:
inta[][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};
或:
inta[][4]={1,2,3,4,5,6,7,8,9,10,11,12};
②部分元素赋初值
{{0行部分初值},{1行部分初值},…,{m行部分初值}}
例如:
inta[3][4]={{1,2},{5},{9,10,11}};
表示二维数组a的元素a[0][0]、a[0][1]、a[1][0]、a[2][0]、a[2][1]、a[2][2]赋了初值。