5 数据组织、筛法与排序问题 的解题思路

109
程程程程 ( 程 5 程 ) 5 数数数数 数数数数数数数 数数数数数 数数数数1 数数数数数 2 数数数数数 3 数数数数 数数数数2 数数 数数数数 数数数数

Upload: ping

Post on 08-Jan-2016

98 views

Category:

Documents


5 download

DESCRIPTION

5 数据组织、筛法与排序问题 的解题思路. 教学内容: 1 数组的概念 2 筛法求素数 3 冒泡排序. 教学方法:任务驱动. 课时安排: 2节课. 学 习 目 标. 数组的概念、定义和初始化 筛法的解题思路 冒泡排序的思路. 内 容 要 点. 数组:定义、初始化、操作与应用 筛法:do_while循环、 while循环、求质数 排序:冒泡排序的算法. 问题:哪只羊最重?. - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: 5 数据组织、筛法与排序问题 的解题思路

程序设计 ( 第 5章 )

5 数据组织、筛法与排序问题的解题思路

教学内容:1 数组的概念2 筛法求素数3 冒泡排序

课时安排: 2 节课

教学方法:任务驱动

Page 2: 5 数据组织、筛法与排序问题 的解题思路

2

数组的概念、定义和初始化数组的概念、定义和初始化

筛法的解题思路筛法的解题思路

冒泡排序的思路冒泡排序的思路

学 习 目 标学 习 目 标

Page 3: 5 数据组织、筛法与排序问题 的解题思路

3

1.1.数组:定义、初始化、操作与应用数组:定义、初始化、操作与应用

2.2.筛法:筛法: do_whiledo_while 循环、 循环、 whilewhile循循环、求质数环、求质数

3.3.排序:冒泡排序的算法排序:冒泡排序的算法

内 容 要 点内 容 要 点

Page 4: 5 数据组织、筛法与排序问题 的解题思路

4

中秋佳节,有贵客来到草原,主人要中秋佳节,有贵客来到草原,主人要从羊群中选一只肥羊宴请宾客,当然要选最从羊群中选一只肥羊宴请宾客,当然要选最重者。这样就要记录每只羊的重量,如果有重者。这样就要记录每只羊的重量,如果有成千上万只羊,不可能用一般变量来记录。成千上万只羊,不可能用一般变量来记录。可以用带有下标的变量,也就是这里要讲的可以用带有下标的变量,也就是这里要讲的数组数组。。

问题:哪只羊最重?问题:哪只羊最重?

我们先看例子:用键盘输入 10 只羊的重量存放到一个名为 sheep 的数组中

Page 5: 5 数据组织、筛法与排序问题 的解题思路

5

//************************************//************************************//* //* 程序名:程序名: 5_1.cpp5_1.cpp (数组示例) (数组示例) **//* //* 作 者:作 者: wuwh *wuwh *//* //* 编制时间:编制时间: 20022002年年 99月月 2020 日 日 **//* //* 主要功能:找出最重的羊 主要功能:找出最重的羊 **//************************************//************************************#include <iostream>#include <iostream> // // 预编译命令预编译命令#include <memory>#include <memory> // // 预编译命令预编译命令using namespace std;using namespace std;int main()int main() // // 主函数主函数{{

float sheep[10];float sheep[10]; // // 数组,有数组,有 1010 个浮点类型元素,个浮点类型元素,// // 用于存用于存 1010 只羊每一只的重量只羊每一只的重量

memset ( sheep, 0 , sizeof (sheep) );// memset ( sheep, 0 , sizeof (sheep) );// 初始化数组元素为初始化数组元素为 00float bigsheep=0.0;float bigsheep=0.0; // // 浮点类型变量,存放最肥羊的重量浮点类型变量,存放最肥羊的重量int i=0, bigsheepNo=0;int i=0, bigsheepNo=0; // // 整型变量,整型变量, i i 用于计数循环, 用于计数循环,

// bigsheepNo// bigsheepNo 用于记录最肥羊的号 用于记录最肥羊的号

Page 6: 5 数据组织、筛法与排序问题 的解题思路

6

for ( i=0; i<10; i=i+1 )for ( i=0; i<10; i=i+1 ) // // 计数循环计数循环 {{ // // 循环,开始循环,开始 cout<<"cout<<" 请输入羊的重量请输入羊的重量 sheep[sheep["<< i << ""<< i << "]=]="; // "; // 提示用提示用 cin >> sheep[i];cin >> sheep[i]; // // 输入第输入第 ii 只羊的重量只羊的重量 if ( bigsheep < sheep[i] )if ( bigsheep < sheep[i] ) // // 如果第如果第 ii 只羊比当前最肥羊大只羊比当前最肥羊大

{{ bigsheep = sheep[i];bigsheep = sheep[i]; // // 让第让第 ii 只羊为当前最肥羊只羊为当前最肥羊 bigsheepNo = i;bigsheepNo = i; // // 纪录第纪录第 ii 只羊的编号只羊的编号}}

}} // // 循环结束循环结束

// // 输出最肥羊的重量输出最肥羊的重量 cout<< "cout<< " 最肥羊的重量为最肥羊的重量为 "<<bigsheep<<endl;"<<bigsheep<<endl;

// // 输出该羊的编号输出该羊的编号 cout<< "cout<< " 最肥羊的编号为最肥羊的编号为 "<<bigsheepNo<<endl;"<<bigsheepNo<<endl;

return 0;return 0;}}

Page 7: 5 数据组织、筛法与排序问题 的解题思路

7

bigsheep = 0.0f; 将记录最重的羊的重量置 0

bigsheepNo = 0; 记录最重的羊的编号

for ( i=0; i<10; i=i+1 )

提示输入第 i只羊的重量;

键入第 i只羊的重量 sheep[i];

bigsheep < sheep[i]

是 否

bigsheep = sheep[i];

bigsheepNo = i;

存重者,记录第 i只。

输出 bigsheep ( 最重的羊的重量 )

输出 bigsheepNo ( 最重的羊的编号 )

Page 8: 5 数据组织、筛法与排序问题 的解题思路

8

类型说明符 数组名 [ 常量表达式 ]

例:例: float sheep[10];float sheep[10];

int a2001[1000];int a2001[1000];

说明说明 1. 1. 数组名的第一个字符应为英文字母;数组名的第一个字符应为英文字母;

2. 2. 用用方括号方括号将将常量表达式常量表达式括起;括起;

3. 3. 常量表达式定义了数组元素的个数;常量表达式定义了数组元素的个数;

数组的定义数组的定义

Page 9: 5 数据组织、筛法与排序问题 的解题思路

9

4. 4. 数组下标从 数组下标从 0 0 开始。如果定义 开始。如果定义 5 5 个元素,是从第 个元素,是从第 0 0 个元素至第 个元素至第 4 4 个元素;个元素;

例如例如 int a[5] int a[5] 定义了定义了 55 个数组元素如下个数组元素如下::

a[0], a[1], a[2], a[3], a[4]a[0], a[1], a[2], a[3], a[4]

这是 这是 5 5 个带下标的变量,这个带下标的变量,这 55 个变量的类型是相同的个变量的类型是相同的

a

下标 0 1 2 3 4

Page 10: 5 数据组织、筛法与排序问题 的解题思路

10

5.5. 常量表达式中不允许包含变量常量表达式中不允许包含变量

例如例如 int n;int n;

n = 5;n = 5;

int a[n];int a[n]; 不合法!不合法! 因为 因为 n n 是变量,不是常量是变量,不是常量

Page 11: 5 数据组织、筛法与排序问题 的解题思路

11

#define N 100 //#define N 100 //宏定义,宏定义, NN为常数为常数 100100#define M 200 //#define M 200 //宏定义,宏定义,MM为常数为常数 200200int a[ N ] ; //int a[ N ] ; // 定义有定义有 100100个元素的整型数组个元素的整型数组 aa

long b[ N+M ] ; //long b[ N+M ] ; // 定义有定义有 300300个元素的长整型数组个元素的长整型数组 bb

double g[ M+6 ] ; //double g[ M+6 ] ; // 定义有定义有 206206个元素的双精度实个元素的双精度实 ////型数组型数组 gg

以上定义是合法的以上定义是合法的#define N 100 #define N 100 为命令行,不是语句,程序在为命令行,不是语句,程序在 编译时遇到编译时遇到 N N 就用就用 100100替换。在命令行中定替换。在命令行中定义的符号名义的符号名 NN,也被称为符号常量,也被称为符号常量 NN。。

Page 12: 5 数据组织、筛法与排序问题 的解题思路

12

第一种方法第一种方法 直接在定义时初始化 直接在定义时初始化例如例如

int a[5] = { 3, 5, 4, 1, 2 };int a[5] = { 3, 5, 4, 1, 2 };

a[0] = 3; a[1] = 5; a[2] = 4; a[3] = 1; a[4] = 2;a[0] = 3; a[1] = 5; a[2] = 4; a[3] = 1; a[4] = 2;

a 3 5 4 1 2

下标 0 1 2 3 4

数组初始化数组初始化

Page 13: 5 数据组织、筛法与排序问题 的解题思路

13

第二种方法第二种方法 使用 使用 memset memset 函数函数

格式为格式为memset(memset( 数组名数组名 , , 初始化值初始化值 , sizeof(, sizeof( 数组数组

名名 ))))举例:举例:

memset(sheep, 0, memset(sheep, 0, sizeof( sheep ));sizeof( sheep ));

含义是将名为 含义是将名为 sheep sheep 的数组中的全部元素均初的数组中的全部元素均初始化为 始化为 0 0 。更深一层是说让系统为 。更深一层是说让系统为 sheep[10] sheep[10] 所分配的内存单元从 所分配的内存单元从 sheep[0] sheep[0] 为标志的地址单为标志的地址单元到该数组的全部地址单元都赋以 元到该数组的全部地址单元都赋以 0 0 。。调用此调用此库函数需要加入头文件 库函数需要加入头文件 <memory.h> <memory.h> 。。

Page 14: 5 数据组织、筛法与排序问题 的解题思路

14

1.1.##include <iostream>include <iostream> using namespace std;using namespace std;

int main()int main(){{

int a[4];int a[4]; // // 声明声明项项

cout << a[0] << endl;cout << a[0] << endl;cout << a[1] << endl;cout << a[1] << endl;cout << a[2] << endl;cout << a[2] << endl;cout << a[3] << endl;cout << a[3] << endl;

return 0;return 0;}}

2.2. 其他不变,改变声明项为其他不变,改变声明项为int a[4] = { 0, 1, 2, 3 };int a[4] = { 0, 1, 2, 3 };

请自己上机做 7 个实验

Page 15: 5 数据组织、筛法与排序问题 的解题思路

15

3.3. 其他不变,改变声明项为其他不变,改变声明项为int a[4] = { 3, 8 };int a[4] = { 3, 8 };

4.4. 其他不变,改变声明项为其他不变,改变声明项为int a[4] = { 2, 4, 6, 8, 10 };int a[4] = { 2, 4, 6, 8, 10 };

5.5. 其他不变,改变声明项为其他不变,改变声明项为int a[4] = { 2, 4, 6, d };int a[4] = { 2, 4, 6, d };

6.6. 其他不变,改变声明项为其他不变,改变声明项为 int d;int d;

int a[4] = { 2, 4, 6, d };int a[4] = { 2, 4, 6, d };

7.7. 其他不变,改变声明项为其他不变,改变声明项为int n=4;int n=4;int a[n] = { 0, 1, 2, 3 };int a[n] = { 0, 1, 2, 3 };

Page 16: 5 数据组织、筛法与排序问题 的解题思路

16

讨 论 问 题讨 论 问 题

使用筛法求使用筛法求 100100 以内的所有素数以内的所有素数

Page 17: 5 数据组织、筛法与排序问题 的解题思路

17

5.2 5.2 筛 法 筛 法

Page 18: 5 数据组织、筛法与排序问题 的解题思路

18

思路思路1.1. 想象将想象将 100100 个数看作沙子和小石头子,让小石头子个数看作沙子和小石头子,让小石头子

权称素数;让沙子当作非素数。弄一个筛子,只要将权称素数;让沙子当作非素数。弄一个筛子,只要将沙子筛走,剩下的就是素数了。沙子筛走,剩下的就是素数了。

2.2. 非素数一定是 非素数一定是 22 、、 33 、、 4 4 …… …… 的倍数。的倍数。3.3. 使用数组,让下标就是使用数组,让下标就是 100100 以内的数,让数组元素以内的数,让数组元素

的值作为筛去与否的标志。比如筛去以后让元素值为的值作为筛去与否的标志。比如筛去以后让元素值为11 。。

0 1 2 3 4 5 6 7 99 100

0 0 1 0 1 0 … 1 1

Page 19: 5 数据组织、筛法与排序问题 的解题思路

19

方法的依据:方法的依据:11 至至 100100 这些自然数可以分为三类:这些自然数可以分为三类: 单位数:仅有一个数单位数:仅有一个数 11 。。 素数: 是这样一个数,它大于素数: 是这样一个数,它大于 11 ,且只有,且只有 11 和它自身这样两个正因数。和它自身这样两个正因数。 合数: 除了合数: 除了 11 和自身以外,还有其他正因数。和自身以外,还有其他正因数。

11 不是素数,除不是素数,除 11 以外的自然数,当然以外的自然数,当然只有素数与合数。筛法实际上是筛去合数,只有素数与合数。筛法实际上是筛去合数,留下素数。留下素数。

Page 20: 5 数据组织、筛法与排序问题 的解题思路

20

为了提高筛法效率,注意到:为了提高筛法效率,注意到: 令 令 n n 为合数(这里是为合数(这里是 100100),),

c c 为 为 n n 的最小正因数,的最小正因数,

据初等数论,只要找到 据初等数论,只要找到 c c 就可以就可以 确认 确认 n n 为合数,将其筛去。为合数,将其筛去。

nc1

一定注意:要进行“筛”的一定注意:要进行“筛”的 1—1001—100 的数字是的数字是与数组与数组 prime[101]prime[101] 的下标相对应的,而每个数组元的下标相对应的,而每个数组元素的取值只有素的取值只有 22 个:是个:是 00或或 11 ,分别代表(标志),分别代表(标志)与下标相对应的数字是素数或不是素数。与下标相对应的数字是素数或不是素数。

Page 21: 5 数据组织、筛法与排序问题 的解题思路

21

程序框图如下:

for ( c=2; c<=100; c=c+1 )

for ( c=2; c<=100; c=c+1 )

d = 2; ( 初始化 )

prime[c] = 0;

do … while d <= sqrt ( 100 )

prime[k] = 1; k = k + d;

while ( k <= 100 )

k = k + d;

yes prime[k] == 0 no

k = d;

yes prime[c] == 0 no

cout << c << endl;

d = d + 1;

请同学来请同学来分析左边分析左边程序的结程序的结构构

从而了解从而了解算法的设算法的设计思路计思路

为程序代为程序代码的实现码的实现创造条件创造条件

Page 22: 5 数据组织、筛法与排序问题 的解题思路

22

上述框图 很清晰地描述了筛法的思路:上述框图 很清晰地描述了筛法的思路:

1.1. 第一块是一个计数型的循环语句,功能是将第一块是一个计数型的循环语句,功能是将 primeprime数组清零。数组清零。

prime[c] = 0;prime[c] = 0; c = 2, 3,… ,100c = 2, 3,… ,100

2.2. 第二块是正因数第二块是正因数 d d 初始化为 初始化为 d = 2d = 2。。

3.3. 第三块是循环筛数。这里用了一个 第三块是循环筛数。这里用了一个 do whiledo while 语句,语句,属于一种直到型循环,其一般形式为:属于一种直到型循环,其一般形式为:

dodo{{

循环体语句块循环体语句块}}while ( while ( 表达式 表达式 ))

Page 23: 5 数据组织、筛法与排序问题 的解题思路

23

dodo

{{

循环体语句块循环体语句块 ;;

}}

while ( while ( 表达式 表达式 ))

Page 24: 5 数据组织、筛法与排序问题 的解题思路

24

直到型循环框图如下:

直到表达式为假 时才退出循环,所以循环体至少执行一次。

循环体

语句块

表达式 真

当表达式为真时

继续循环

循环体

语句块

Page 25: 5 数据组织、筛法与排序问题 的解题思路

25

举 例

求 求 π π 的近似值的近似值

Page 26: 5 数据组织、筛法与排序问题 的解题思路

26

例例 ..求求 ππ 的近似值的近似值

用变量用变量 pipi 表示表示 ππ 的值。的值。

令令 表示括号中的每个项表示括号中的每个项

当最后一项的绝对值小于等于 时,忽略掉以后的项当最后一项的绝对值小于等于 时,忽略掉以后的项

7

1

5

1

3

114

a

bc

1 7 5 3 1为 ba ,,,,, 610

Page 27: 5 数据组织、筛法与排序问题 的解题思路

27

//************************************//************************************//* //* 程 序 名:程 序 名: 5_2.cpp 5_2.cpp * *//* //* 作 者:作 者: wuwh *wuwh *//* //* 编制时间:编制时间: 20022002年年 99月月 2020 日 日 **//* //* 主要功能:求主要功能:求 pipi 的近似值 的近似值 **//************************************ //************************************ #include <iostream>#include <iostream>#include <cmath>#include <cmath>using namespace std;using namespace std;int main()int main() // // 主函数主函数{{

int sum=0;int sum=0; // // 整型变量,总项数整型变量,总项数float pi=0.0, a=1.0, b=1.0, c=1.0;float pi=0.0, a=1.0, b=1.0, c=1.0; // // 浮点变量,浮点变量, aa 为分母,为分母, bb 为分子,为分子, cc为为 bb除以除以 aa

Page 28: 5 数据组织、筛法与排序问题 的解题思路

28

do do // // 直到型循环直到型循环

{{ // // 循环体,开始循环体,开始 pi = pi + c;pi = pi + c; // // 累加每一项累加每一项 sum = sum + 1;sum = sum + 1; a = a + a = a + 2.0f2.0f; // ; // 计算每一项的分母;计算每一项的分母;强制将强制将 2.02.0转换成转换成 floatfloat型型 b = -b; // b = -b; // 分子变正负号分子变正负号 c = b / a;c = b / a; // // 计算每一项计算每一项}} // // 循环体结束循环体结束while ( fabs(c) > 1e-6 ); // while ( fabs(c) > 1e-6 ); // 当当 cc的绝对值大于的绝对值大于 1010的的 -6-6次方时,继次方时,继续续 // // 执行循环体,否则退出执行循环体,否则退出pi = pi = 4.0f4.0f * pi; * pi; // // 得到最终结果;得到最终结果;将将 4.04.0作为作为 floatfloat类类型型cout << “pi= ” << pi << endl;cout << “pi= ” << pi << endl; // // 输出输出 pipi值值cout << “sum=” << sum << endl;cout << “sum=” << sum << endl; // // 输出总项数输出总项数

return 0;return 0;}}

Page 29: 5 数据组织、筛法与排序问题 的解题思路

29

do do // // 直到型循环直到型循环 {{ // // 循环体,开始循环体,开始

pi = pi + c;pi = pi + c; // // 累加每一项累加每一项sum = sum + 1;sum = sum + 1;

a = a + 2.0f;a = a + 2.0f; // // 计算每一项的分母计算每一项的分母

b = -b;b = -b; // // 分子变正负号分子变正负号c = b / a;c = b / a; // // 计算每一项计算每一项

}} // // 循环体结束循环体结束while ( fabs(c) > 1e-6 );while ( fabs(c) > 1e-6 );

Page 30: 5 数据组织、筛法与排序问题 的解题思路

30

运行结果运行结果 pi = 3.14159pi = 3.14159 , , sum = 500000sum = 500000

答:会构成答:会构成死循环死循环,即无休止地执行循环体,即无休止地执行循环体

请实验:请实验: 1. 1. 将 将 b b 定义为 定义为 int int 型看看执行结果并分析为什么型看看执行结果并分析为什么 2. 2. 将 将 11e-6 e-6 变为 变为 11e-7 e-7 或 或 11e-4 e-4 看看结果看看结果

提问:这种循环当表达式的值提问:这种循环当表达式的值永远为真永远为真时,时,会如何?会如何?

Page 31: 5 数据组织、筛法与排序问题 的解题思路

31

下面还要介绍另一种循环“下面还要介绍另一种循环“当循环当循环””一般形式:一般形式: while ( while ( 表达式 表达式 ))

{ { 语句块;语句块; (( 循环体循环体 )) }}

while (表达式)

循环体

语句块

循环体

语句块

表达式

Page 32: 5 数据组织、筛法与排序问题 的解题思路

32

while( while( 表达式 表达式 ))

{ {

语句块 ( 循环体 ) 语句块 ( 循环体 ) ;;

}}

Page 33: 5 数据组织、筛法与排序问题 的解题思路

33

思考 思考 #define N 1#define N 1

while ( N )while ( N )

{ {

cout<<“ welcome to Tsinghua \n“;cout<<“ welcome to Tsinghua \n“;

} }

程序运行后会出现什么情况程序运行后会出现什么情况 ??

Page 34: 5 数据组织、筛法与排序问题 的解题思路

34

思考 思考 #define N 1#define N 1

while ( N - 1 )while ( N - 1 )

{ {

cout<<“ welcome to Tsinghua \n“;cout<<“ welcome to Tsinghua \n“;

} }

程序运行后会出现什么情况程序运行后会出现什么情况 ??

Page 35: 5 数据组织、筛法与排序问题 的解题思路

35

举 例

求两个整数的最小公倍数

Page 36: 5 数据组织、筛法与排序问题 的解题思路

36

分析:假定有分析:假定有 x ,y x ,y 且 且 x > yx > y ,,设最小公倍数为 设最小公倍数为 zz

1. z 1. z 一定会 一定会 >= >= xx2. z = k x , k= 1, 2, …2. z = k x , k= 1, 2, …3. z 3. z 一定会被 一定会被 y y 整除整除

用两个最简单的数试一下就可以找到算法用两个最简单的数试一下就可以找到算法 ..比如 比如 x=5, y=3.x=5, y=3.

Page 37: 5 数据组织、筛法与排序问题 的解题思路

37

第一步 第一步 z z = = x // x=5x // x=5 5 % 3 != 0 5 % 3 != 0 // z % y // z % y 不能整除不能整除

第二步 第二步 z = z + xz = z + x 10 % 3 != 0 10 % 3 != 0 // z % y// z % y 不能整除不能整除

第三步 第三步 z = z + xz = z + x 15 % 3 == 0 15 % 3 == 0 // z % y // z % y 能整除能整除

找到了 找到了 z z ,, 1515 就是就是 55 和和 33 的最小公倍数的最小公倍数

Page 38: 5 数据组织、筛法与排序问题 的解题思路

38

//************************************//************************************//* //* 程 序 名:程 序 名: 5_3.cpp *5_3.cpp *//* //* 作 者:作 者: wuwh *wuwh *//* //* 编制时间:编制时间: 20022002年年 99月月 2020 日 日 **//* //* 主要功能:求两个数的最小公倍数 主要功能:求两个数的最小公倍数 **//************************************//************************************#include <iostream>#include <iostream>#include <cmath>#include <cmath>using namespace std;using namespace std;int main()int main() // // 主函数主函数{{

int x=0, y=0, z=0, w=0; // int x=0, y=0, z=0, w=0; // 整型变量整型变量cout << “cout << “ 请输入两个整数,用空格隔开:请输入两个整数,用空格隔开:”” ; // ; // 提示信息提示信息cin >> x; cin >> x; // // 键盘输入整数 键盘输入整数 xxcin >> y; cin >> y; // // 键盘输入整数 键盘输入整数 yyif ( x < y )if ( x < y ) // // 让 让 x x 表示两者中的大数表示两者中的大数{{

w = x; x = y; y = w; // w = x; x = y; y = w; // ““ 倒油瓶”方法倒油瓶”方法}}z = x;z = x; // // 将一个大数赋给 将一个大数赋给 zzwhile ( z % y != 0 )while ( z % y != 0 ) // // 当当 zz 不能被不能被 yy 整除时,就让整除时,就让 zz累加累加 xx

{z = z + x; }{z = z + x; }cout << “cout << “ 最小公倍数为最小公倍数为” ” << z << endl;<< z << endl; // // 输出最小公倍数输出最小公倍数

return 0;return 0;}}

Page 39: 5 数据组织、筛法与排序问题 的解题思路

39

cout << “cout << “请输入两个整数,用空格隔请输入两个整数,用空格隔开开::”” ; // ; // 提示信息提示信息cin >> x; cin >> x; // // 键盘输入整数 键盘输入整数 xx

cin >> y; cin >> y; // // 键盘输入整数 键盘输入整数 yy

if ( x < y )if ( x < y ) // // 让 让 x x 表示两者中的 大数 表示两者中的 大数{{

w = x; x = y; y = w;w = x; x = y; y = w;

}}

Page 40: 5 数据组织、筛法与排序问题 的解题思路

40

z = x;z = x; // // 将一个大数赋给 将一个大数赋给 zz

// // 当当 zz不能被不能被 yy整除时,就让整除时,就让 zz累加累加 xx

while ( z % y != 0 )while ( z % y != 0 ) { z = z + x; } { z = z + x; }

cout << "cout << "最小公倍数为最小公倍数为 " << z << endl;" << z << endl;

Page 41: 5 数据组织、筛法与排序问题 的解题思路

41

请同学们去比较三种循环的异同之处请同学们去比较三种循环的异同之处 1. 1. for for 循环(计数型循环)循环(计数型循环)

2. 2. 当型循环(当型循环( whilewhile 循环)循环)

3. 3. 直到型循环(直到型循环( do while do while 循环)循环)

上机将筛出素数的程序完成上机将筛出素数的程序完成

自学与比较

Page 42: 5 数据组织、筛法与排序问题 的解题思路

42

练习练习 ::

题目:某选手 题目:某选手 10000m 10000m 跑的每 跑的每 400m 400m 用用 时记录在名为 时记录在名为 RUN RUN 的数组中,请你计的数组中,请你计

算平均用时(每算平均用时(每 400 m 400 m 的平均用时)的平均用时) ,, 要求使用 要求使用 3 3 种循环语句来编程。种循环语句来编程。

1. for 1. for

2. do … while 2. do … while

3. while3. while

Page 43: 5 数据组织、筛法与排序问题 的解题思路

43

数组中已有数组中已有 2525圈的每一圈的时间圈的每一圈的时间

run 0 70 71 73 72 . . . 69 run 0 70 71 73 72 . . . 69

0 1 2 3 4 . . . 250 1 2 3 4 . . . 25

Page 44: 5 数据组织、筛法与排序问题 的解题思路

44

int main() int main() {{ int run[26]={ 70,71,… };int run[26]={ 70,71,… }; int sum=0 ,average=0; int sum=0 ,average=0; for( int i=1;i<=25;i++)for( int i=1;i<=25;i++) {{ sum=sum+run[i]; sum=sum+run[i]; }} average=sum/25; average=sum/25; cout<<average;cout<<average; system("pause");system("pause"); return 0;return 0;} } 初值 终值 增值 初值 终值 增值

Page 45: 5 数据组织、筛法与排序问题 的解题思路

45

i=1; i=1; 初值初值 while( i <= 25 )while( i <= 25 )

{ { 终值终值 sum=sum+ run[ i ];sum=sum+ run[ i ];

i = i +1; i = i +1; 增值增值 }}

Page 46: 5 数据组织、筛法与排序问题 的解题思路

46

i=1;i=1;初值初值 dodo

{{

sum=sum+ run[ i ];sum=sum+ run[ i ];

i = i +1;i = i +1;

} while( i <= 25 );} while( i <= 25 );

Page 47: 5 数据组织、筛法与排序问题 的解题思路

47

结论结论 初值,终值,增值初值,终值,增值 循环中的循环中的 33个表达式个表达式

一个也不能一个也不能少!少!

Page 48: 5 数据组织、筛法与排序问题 的解题思路

48

排 序 问 题

Page 49: 5 数据组织、筛法与排序问题 的解题思路

49

5.3 5.3 冒泡排序法

Page 50: 5 数据组织、筛法与排序问题 的解题思路

50

a 1 8 3 2 4 9a 1 8 3 2 4 9

下标 下标 1 2 3 4 5 61 2 3 4 5 6

希望排成:希望排成: a 9 8 4 3 2 1a 9 8 4 3 2 1

下标 下标 1 2 3 4 5 61 2 3 4 5 6

Page 51: 5 数据组织、筛法与排序问题 的解题思路

51

冒泡排序法

问题: 将几个数从大到小排序并输出

Page 52: 5 数据组织、筛法与排序问题 的解题思路

52

i =1 i =2 i =3 i =4 i =5 i =6 a[1] a[2] a[3] a[4] a[5] a[6] 1 8 3 2 4 9初始值1<8; 1, 8 1 8 3 2 4 9互换 8 1 3 2 4 91<3; 1, 3 8 1 3 2 4 9互换 8 3 1 2 4 91<2; 1, 2 8 3 1 2 4 9互换 8 3 2 1 4 91<4; 1, 4 8 3 2 1 4 9互换 8 3 2 4 1 91<9; 1, 9 8 3 2 4 1 9互换 1 8 3 2 4 9 1到达位置

j =1

8>3; 8 3 2 4 9 1顺序不动3>2; 8 3 2 4 9 1顺序不动2<4; 2, 4 8 3 2 4 9 1互换 8 3 4 2 9 12<9; 2, 9 8 3 4 2 9 1互换 2 8 3 4 9 2 1到达位置

j =2

Page 53: 5 数据组织、筛法与排序问题 的解题思路

53

i =1 i =2 i =3 i =4 i =5 i =6 a[1] a[2] a[3] a[4] a[5] a[6] 8 3 4 9 2 1中间结果8>3; 8 3 4 9 2 1顺序不动3<4; 3, 4 8 3 4 9 2 1互换 8 4 3 9 2 13<9; 3, 9 8 4 3 9 2 1互换 3 8 4 9 3 2 1到达位置

j =3

8>4; 8 4 9 3 2 1顺序不动4<9; 4, 9 8 4 9 3 2 1互换 4 8 9 4 3 2 1到达位置

j =4

8<9; 8, 9 8 9 4 3 2 1互换 8 9 8 4 3 2 1到达位置

j =5

Page 54: 5 数据组织、筛法与排序问题 的解题思路

54

从表中可以看出最小的一个数第一遍扫描就交换到从表中可以看出最小的一个数第一遍扫描就交换到 a[6]a[6]中。如果将中。如果将 a[1]a[1] 视为水底,视为水底, a[6]a[6] 视为水面:视为水面:

最轻的最轻的 (( 最小的最小的 )) 一个数 一个数 1 1 最先浮到水面,交换到最先浮到水面,交换到a[6];a[6];次轻的 次轻的 2 2 第二遍扫描交换到第二遍扫描交换到 a[5]a[5];;再轻的 再轻的 3 3 第三遍扫描交换到第三遍扫描交换到 a[4]a[4];;

……依此类推,有依此类推,有 66 个数,前个数,前 55 个数到位需个数到位需 55遍扫描,第遍扫描,第 66个最重的数自然落在个最重的数自然落在 a[1]a[1] 中。因此,中。因此, 66 个数只需个数只需 55遍扫遍扫描,令描,令扫描编数为 扫描编数为 JJ,, J=n-1, n=6J=n-1, n=6。。

冒泡排序算法分析:

Page 55: 5 数据组织、筛法与排序问题 的解题思路

55

再看在每遍扫描中,相邻两数组元素的比较次数。再看在每遍扫描中,相邻两数组元素的比较次数。

当当 j=1j=1 时,时, i=1,2,…,n-ji=1,2,…,n-j。。 n=6n=6 时,比较时,比较 55次之后次之后a[6]a[6] 中有一个最小数到达,这时中有一个最小数到达,这时 a[6]a[6] 不必再参与比较不必再参与比较了。了。因此在第二遍搜索时,因此在第二遍搜索时, j=2, i=1,2,…,n-jj=2, i=1,2,…,n-j ,,即即i=1,2,3,4i=1,2,3,4 。。比较比较 44次之后次小的一个数到达了次之后次小的一个数到达了a[5]a[5] 。。这时这时 a[5]a[5] 不必再参与比较了。不必再参与比较了。因此,因此, j=3j=3 时,时, i=1,2,3i=1,2,3;; j=4j=4 时,时, i=1,2i=1,2;; j=5j=5 时,时, i=1. i=1.

理出上述规律后,程序就不难编了理出上述规律后,程序就不难编了

Page 56: 5 数据组织、筛法与排序问题 的解题思路

56

int i = 0, j = 0, p = 0, a[ 7 ];// int i = 0, j = 0, p = 0, a[ 7 ];// 整型变量整型变量memset( a, 0, sizeof(a) );memset( a, 0, sizeof(a) ); // // 数组初始化数组初始化for ( i = 1; i <= 6; i++ )for ( i = 1; i <= 6; i++ ) // // 键入键入 66个数个数{{

cout<< cout<< ""请输入待排序的数请输入待排序的数 a["a["

<< i << << i << "]= “"]= “ ; ; // // 提示提示cin >> a[i]; cin >> a[i]; // // 输入整数输入整数

}}

Page 57: 5 数据组织、筛法与排序问题 的解题思路

57

为了表述方便,定义以下为了表述方便,定义以下 33 个变量:个变量:

n —— n —— 待排序的数的个数,这里 待排序的数的个数,这里 n=6n=6

j —— j —— 扫描遍数,扫描遍数, j=1,2,…,n-1j=1,2,…,n-1

i —— i —— 第第 jj遍扫描待比较元素的下标,遍扫描待比较元素的下标, i=1,2,…,n-ji=1,2,…,n-j

冒泡排序算法设计:

Page 58: 5 数据组织、筛法与排序问题 的解题思路

58

采用两重计数型循环:采用两重计数型循环:

步骤步骤 11 :将待排序的数据放入数组中;:将待排序的数据放入数组中;

步骤步骤 22 :置:置 jj 为为 11 ;;

步骤步骤 33 :让 :让 i i 从从 11到到 n-jn-j ,,比较比较 a[i]a[i]与与a[i+1]a[i+1],,

如果 如果 a[i] >= a[i+1]a[i] >= a[i+1] ,,位置不动;位置不动; 如果 如果 a[i] < a[i+1] a[i] < a[i+1] ,,位置交换,位置交换,

步骤步骤 44 :让 :让 j = j+1j = j+1 ;;只要 只要 j != n j != n 返回步骤返回步骤 33 ,, 当当 j==n j==n 时执行时执行步骤步骤 55步骤步骤 55 :输出排序结果:输出排序结果

Page 59: 5 数据组织、筛法与排序问题 的解题思路

59

//************************************//************************************//* //* 程 序 名:程 序 名: 5_4.cpp 5_4.cpp * *//* //* 作 者:作 者: wuwh *wuwh *//* //* 编制时间:编制时间: 20022002年年 99月月 2222 日 日 **//* //* 主要功能:冒泡排序 主要功能:冒泡排序 **//************************************//************************************#include <iostream>#include <iostream> // // 预编译命令预编译命令#include <memory>#include <memory> // // 预编译命令预编译命令using namespace std;using namespace std;int main()int main() // // 主函数主函数{{

int i=0, j=0, p=0, a[7];int i=0, j=0, p=0, a[7]; // // 整型变量整型变量memset( a, 0, sizeof(a) );memset( a, 0, sizeof(a) ); // // 整型数组初始化整型数组初始化for (i=1; i<=6; i++)for (i=1; i<=6; i++) // // 键入键入 66 个数,放入个数,放入 aa 数组中数组中{{

cout<< "cout<< " 请输入待排序的数请输入待排序的数 a[" << i << "]= ";a[" << i << "]= "; // // 提示提示cin >> a[i];cin >> a[i]; // // 用键盘输入整数赋给用键盘输入整数赋给 a[i]a[i]

}}for ( j=1; j<=5; j++)for ( j=1; j<=5; j++) // // 冒泡排序,外层循环冒泡排序,外层循环

for ( i=1; i<=6-j; i++ )for ( i=1; i<=6-j; i++ ) // // 内层循环内层循环if ( a[i] < a[i+1] )if ( a[i] < a[i+1] ) // // 如果 如果 a[i] < a[i+1]a[i] < a[i+1]{{ p = a[i]p = a[i];; // // 让 让 a[i] a[i] 与 与 a[i+1] a[i+1] 交换交换

a[i] = a[i+1];a[i] = a[i+1]; a[i+1] = p; a[i+1] = p; }}

for ( i=1; i<=6; i++)for ( i=1; i<=6; i++) // // 输出排序结果输出排序结果cout << a[i] << endl;cout << a[i] << endl; // // 输出 输出 a[i]a[i]

return 0;return 0;}}

Page 60: 5 数据组织、筛法与排序问题 的解题思路

60

//************************************//************************************

//* //* 程 序 名:程 序 名: 5_4.cpp 5_4.cpp * *

//* //* 作 者:作 者: wuwh *wuwh *

//* //* 编制时间:编制时间: 20022002年年 99月月 2222 日 日 **

//* //* 主要功能:冒泡排序 主要功能:冒泡排序 **

//************************************//************************************

#include <iostream>// #include <iostream>// 预编译命令预编译命令#include <#include <memorymemory>// >// 预编译命令预编译命令using namespace std;using namespace std;

Page 61: 5 数据组织、筛法与排序问题 的解题思路

61

int main()int main(){{

int i = 0, j = 0, p = 0, a[ 7 ];int i = 0, j = 0, p = 0, a[ 7 ];

memset( a, 0, sizeof( a ) );memset( a, 0, sizeof( a ) );

for ( i =1; i <=6; i++ )for ( i =1; i <=6; i++ )

{{cout<< cout<< ""请输入待排序的数请输入待排序的数 a[“a[“

<< i << << i << “ ]= ““ ]= “;;cin >> a [ i ];cin >> a [ i ]; }}

Page 62: 5 数据组织、筛法与排序问题 的解题思路

62

for ( j=1; j<=5; j++)for ( j=1; j<=5; j++) // // 外层循环外层循环

for ( i=1; i<=6-j; i++ ) // for ( i=1; i<=6-j; i++ ) // 内层循环内层循环

TT if ( a[i] < a[i+1] ) if ( a[i] < a[i+1] ) FF {{

p = a[i];p = a[i]; a[i] = a[i+1];a[i] = a[i+1];

a[i+1] = p; a[i+1] = p; }}

Page 63: 5 数据组织、筛法与排序问题 的解题思路

63

for ( for ( j = 1; j <= 5; j++j = 1; j <= 5; j++ ) ) // // 外层循外层循环环

for ( for ( i = 1; i <= 6-j; i++i = 1; i <= 6-j; i++ ) ) // // 内层循环内层循环if ( a[ i ] < a[ i+1 ] )if ( a[ i ] < a[ i+1 ] )

// // 让 让 a[i] a[i] 与 与 a[i+1] a[i+1] 交换交换{{

p = a[ i ];p = a[ i ];

a[ i ] = a[ i+1 ];a[ i ] = a[ i+1 ];

a[ i+1] = p; a[ i+1] = p;

}}

Page 64: 5 数据组织、筛法与排序问题 的解题思路

64

for ( i = 1; i <=6 ; i++)for ( i = 1; i <=6 ; i++)

// // 输出排序结果输出排序结果cout << a[ i ] << endl; cout << a[ i ] << endl;

return 0;return 0;

}}

Page 65: 5 数据组织、筛法与排序问题 的解题思路

65

小结小结与作业与作业数组是有序元素的集合,数组在内存中连数组是有序元素的集合,数组在内存中连

续存放,数组名代表首地址。续存放,数组名代表首地址。数组元素依靠序号(下标)区分(访问),数组元素依靠序号(下标)区分(访问),

使用数组便于组织循环。使用数组便于组织循环。筛法和冒泡排序是典型的算法。关键在掌筛法和冒泡排序是典型的算法。关键在掌

握算法思想。握算法思想。自学自学参考:参考:郑莉编著 《郑莉编著 《 C++C++ 语言程序设语言程序设

计(第三版)》计(第三版)》 c++6.pptc++6.ppt 下载资料及上交作业网址:下载资料及上交作业网址: ftp://ait1.ftp://ait1.

lynu.edu.cnlynu.edu.cn 用户名:用户名: szpx szpx 密码:密码: 111111作业:作业: PP7575 :: 11 、、 22 、、 44

Page 66: 5 数据组织、筛法与排序问题 的解题思路

66

55 数据组织、筛法与排序问题数据组织、筛法与排序问题的解题思路的解题思路 教学内容:教学内容:

1 1 结构与结构数组结构与结构数组 2 2 二维数组二维数组

课时安排: 2 节课

教学方法:任务驱动

Page 67: 5 数据组织、筛法与排序问题 的解题思路

67

结构与结构数组结构与结构数组::1.1. 结构体的概念结构体的概念2.2. 结构体类型的定义结构体类型的定义3.3. 结构体类型的变量的定义结构体类型的变量的定义4.4. 结构体变量的初始化结构体变量的初始化5.5. 结构数组的概念和定义结构数组的概念和定义6.6. 用冒泡排序算法对结构数组中的元素排序用冒泡排序算法对结构数组中的元素排序

内 容 要 点内 容 要 点

Page 68: 5 数据组织、筛法与排序问题 的解题思路

68

MotivationMotivation

数组:其中的每一个元素都必须是相同类数组:其中的每一个元素都必须是相同类型的数据;型的数据;

实际应用:常常需要将不同类型的数据放实际应用:常常需要将不同类型的数据放在一起,使处理起来更为直观方便。在一起,使处理起来更为直观方便。

例如:一个学生的信息,包括姓名、性别、例如:一个学生的信息,包括姓名、性别、出生年月日、身高和体重,如果能归在一出生年月日、身高和体重,如果能归在一起,对于统计个人信息会十分方便。起,对于统计个人信息会十分方便。

为此,引入结构体的概念为此,引入结构体的概念

Page 69: 5 数据组织、筛法与排序问题 的解题思路

69

结构体类型的定义结构体类型的定义 结构体可以用来表示一组不同类型的数结构体可以用来表示一组不同类型的数

据。尽管这些数据的类型不同,但却有据。尽管这些数据的类型不同,但却有内在的联系,比如学生的个人信息有如内在的联系,比如学生的个人信息有如下下 55 项:项: 姓名,汉语拼音,最多姓名,汉语拼音,最多 2020 个字符;个字符; 性别,性别, M / FM / F 生日,生日, 1984110719841107(年月日)(年月日) 身高,身高, 1.741.74(( mm )) 体重,体重, 51.551.5(( kgkg ))

Page 70: 5 数据组织、筛法与排序问题 的解题思路

70

可以定义一个名为可以定义一个名为 studentstudent的结构的结构体,将体,将 55项信息包容在一起,构成学生的个项信息包容在一起,构成学生的个人信息人信息

structstruct student // student //名为名为 studentstudent的结构类型的结构类型{{ char name[20]; //char name[20]; // 姓名姓名 char sex; //char sex; // 性别性别 unsigned long birthday; //unsigned long birthday; //生日生日 float height; //float height; // 身高身高 float weight; //float weight; // 体重体重 };};

Page 71: 5 数据组织、筛法与排序问题 的解题思路

71

定义结构体类型格式:定义结构体类型格式:struct struct 结构体名 结构体名{{ 类型名 类型名 1 1 成员名 成员名 11;; 类型名 类型名 2 2 成员名 成员名 22;; . . .. . . 类型名 类型名 n n 成员名 成员名 nn;;

} } ;;

struct struct 是结构体类型的标志,结构体名是结构体类型的标志,结构体名 studentstudent是是编程者自己选定的。编程者自己选定的。 大括号所括起来的大括号所括起来的 55条语句是结构体中条语句是结构体中 55个成个成

“ ”员的定义。结构体定义之后一定要跟一个 ; 号。“ ”员的定义。结构体定义之后一定要跟一个 ; 号。

Page 72: 5 数据组织、筛法与排序问题 的解题思路

72

//**********************************//**********************************

//* //* 程 序 名: 程 序 名: 55-- 5.CPP 5.CPP **

//* //* 作 者: 作 者: wuwh wuwh **

//* //* 编制时间:编制时间: 20022002年年 1111 月月 2020 日 日 **

//* //* 主要功能:学生个人信息 主要功能:学生个人信息**

//**********************************//**********************************

Page 73: 5 数据组织、筛法与排序问题 的解题思路

73

#include <iostream>#include <iostream>using namespace std;using namespace std;structstruct student // student // 定义结构定义结构 studentstudent{{ char name[20]; //char name[20]; // 姓名姓名 char sex; //char sex; // 性别性别 unsigned long birthday; //unsigned long birthday; // 生日生日 float height; //float height; // 身高身高 float weight; //float weight; // 体重体重 };};

Page 74: 5 数据组织、筛法与排序问题 的解题思路

74

int main() int main() { { studentstudent my; // my; //定义定义 mymy为为 studentstudent 类的结构 类的结构

cout<<“cout<<“ ”输入自己的数据”输入自己的数据 <<endl; //<<endl; //提示信息提示信息 cout<<“cout<<“姓名(汉语拼音)姓名(汉语拼音) \n” //\n” //显示提示显示提示 <<“<<“性别:性别:M/F \n”M/F \n” <<“<<“生日(年月日)生日(年月日) \n”\n” <<“<<“身高(身高( mm)) \n”\n” <<“<<“体重(体重( kgkg)) \n”\n” << endl;<< endl;

Page 75: 5 数据组织、筛法与排序问题 的解题思路

75

// // 依次输入个人信息依次输入个人信息

cin >> my.namecin >> my.name

>> my.sex>> my.sex

>> my.birthday>> my.birthday

>> my.height>> my.height

>> my.weight;>> my.weight;

Page 76: 5 数据组织、筛法与排序问题 的解题思路

76

// // 依次输出个人信息依次输出个人信息

cout<<my.name<<endl;cout<<my.name<<endl; cout<<my. sex<<endl;cout<<my. sex<<endl; cout<<my.birthday<<endl;cout<<my.birthday<<endl; cout<<my. height<<endl;cout<<my. height<<endl; cout<<my. weight<<endl;cout<<my. weight<<endl; system("pause");system("pause"); return 0;return 0;}}

Page 77: 5 数据组织、筛法与排序问题 的解题思路

77

定义类型不会分配内存空间定义类型不会分配内存空间

struct struct studentstudent ////此处为结构类型定义此处为结构类型定义 {{

char name[20]; //char name[20]; // 姓名姓名 char sex; //char sex; // 性别性别 unsigned long birthday; //unsigned long birthday; //生日生日 float height; //float height; // 身高身高 float weight; //float weight; // 体重体重 };};

studentstudent mymy ; ; ////结构变量结构变量 mymy的定义的定义 系统会为系统会为 mymy分配分配内存空间内存空间

Page 78: 5 数据组织、筛法与排序问题 的解题思路

78

变量 变量 my my (( mymy为变量的符号地址)为变量的符号地址) my.namemy.name my.sexmy.sex my.birthdaymy.birthday my.heightmy.height my.weightmy.weight

& my ( & my ( 变量的内存地址)变量的内存地址)

Page 79: 5 数据组织、筛法与排序问题 的解题思路

79

点操作符:点操作符:用于对结构体变量的成员的引用用于对结构体变量的成员的引用如:如: cout<< my . namecout<< my . name ; ;

“读作 输出结构体 “读作 输出结构体 mymy 的的 namename ”成员”成员 “ 这里 “ 这里 . ” . ” “ ”读作 的 “ ”读作 的

Page 80: 5 数据组织、筛法与排序问题 的解题思路

80

结构体变量的初始化结构体变量的初始化方法一:方法一:定义和初始化同时完成定义和初始化同时完成structstruct person person

{{

char name[10];char name[10];

unsigned long birthday;unsigned long birthday;

char placeofbirth[20];char placeofbirth[20];

}} per per = = {{ “Li ming”, 19821209, “Beijing”};“Li ming”, 19821209, “Beijing”};

Page 81: 5 数据组织、筛法与排序问题 的解题思路

81

personperson 是结构体类型是结构体类型 perper 是结构体变量是结构体变量 perper.name = “Liming”;.name = “Liming”;

perper.birthday = 19821209;.birthday = 19821209;

perper.placeofbirth = “Beijing”;.placeofbirth = “Beijing”;

Page 82: 5 数据组织、筛法与排序问题 的解题思路

82

方法二:方法二:分开完成分开完成structstruct person person

{{

char name[10];char name[10];

unsigned long birthday;unsigned long birthday;

char piaceofbirth[20];char piaceofbirth[20];

};};

personperson per per = ={“Li ming”, 19821209, “Beijing”};{“Li ming”, 19821209, “Beijing”};

Page 83: 5 数据组织、筛法与排序问题 的解题思路

83

结构数组结构数组

结构也可以构成数组,即每个数组结构也可以构成数组,即每个数组元素是一个结构;元素是一个结构;

当然,要求这一类数组的全部元素当然,要求这一类数组的全部元素都应该是同一类结构;都应该是同一类结构;

下例:同宿舍下例:同宿舍 44 名同学的数据,构名同学的数据,构成一个有成一个有 44 个元素的结构数组。个元素的结构数组。

Page 84: 5 数据组织、筛法与排序问题 的解题思路

84

student student Room [ 4 ]Room [ 4 ] = { = {

{“Li li”, ‘M’, 19840318, 1.82, 65.0 },{“Li li”, ‘M’, 19840318, 1.82, 65.0 },

{“Mi mi”, ‘M’, 19830918, 1.75, 58.0 },{“Mi mi”, ‘M’, 19830918, 1.75, 58.0 },

{“He lei”, ‘M’, 19841209, 1.83, 67.1 },{“He lei”, ‘M’, 19841209, 1.83, 67.1 },

{“Ge li”, ‘M’, 19840101, 1.70, 59.0 }{“Ge li”, ‘M’, 19840101, 1.70, 59.0 }

};};

Page 85: 5 数据组织、筛法与排序问题 的解题思路

85

name name name namename name name name

sex sex sex sexsex sex sex sex

birthday birthday birthday birthdaybirthday birthday birthday birthday

height height height heightheight height height height

weight weight weight weighweight weight weight weigh

下标下标 0 0 下标下标 1 1 下标下标 2 2 下标下标 33

RoomRoom

Page 86: 5 数据组织、筛法与排序问题 的解题思路

86

Room[ 0 ] “Li li”, ‘M’, 19840318, 1.82, 65.0,Room[ 0 ] “Li li”, ‘M’, 19840318, 1.82, 65.0,

Room[ 1 ] “Mi mi”, ‘M’, 19830918,1.75, 58.0,Room[ 1 ] “Mi mi”, ‘M’, 19830918,1.75, 58.0,

Room[ 2 ] “He lei”, ‘M’, 19841209, 1.83, 67.1,Room[ 2 ] “He lei”, ‘M’, 19841209, 1.83, 67.1,

Room[ 3 ] “Ge li”, ‘M’, 19840101, 1.70, 59.0 Room[ 3 ] “Ge li”, ‘M’, 19840101, 1.70, 59.0

Page 87: 5 数据组织、筛法与排序问题 的解题思路

87

//**********************************//**********************************

//* //* 程 序 名: 程 序 名: 55-- 6.CPP *6.CPP *

//* //* 作 者: 作 者: wuwh *wuwh *

//* //* 编制时间:编制时间: 20022002年年 1111月月 2121 日 日 **

//* //* 主要功能:结构数组 主要功能:结构数组 * *

//* //* 冒泡排序 冒泡排序 **

//**********************************//**********************************

Page 88: 5 数据组织、筛法与排序问题 的解题思路

88

#include <iostream>#include <iostream>using namespace std;using namespace std;structstruct student // student //名为名为 studentstudent的结构类型的结构类型{{ char name[20]; //char name[20]; // 姓名姓名 char sex; //char sex; // 性别性别 unsigned long birthday; //unsigned long birthday; // 生日生日 float height; //float height; // 身高身高 float weight; //float weight; // 体重体重 };};

Page 89: 5 数据组织、筛法与排序问题 的解题思路

89

student student Room [ 4 ]Room [ 4 ] = = {{

{“Li li”, ‘M’, 19840318, 1.82, 65.0 },{“Li li”, ‘M’, 19840318, 1.82, 65.0 },

{“Mi mi”, ‘M’, 19830918, 1.75, 58.0 },{“Mi mi”, ‘M’, 19830918, 1.75, 58.0 },

{“He lei”, ‘M’, 19841209, 1.83, 67.1 },{“He lei”, ‘M’, 19841209, 1.83, 67.1 },

{“Ge li”, ‘M’, 19840101, 1.70, 59.0 }{“Ge li”, ‘M’, 19840101, 1.70, 59.0 }

}};;

Page 90: 5 数据组织、筛法与排序问题 的解题思路

90

int main()int main(){ { studentstudent q; q; int i = 0 ; int j =0;int i = 0 ; int j =0; for ( j = 0; j < 3; j = j+1 )for ( j = 0; j < 3; j = j+1 ) for ( i = 0; i < 3 – j ; i = i +1 )for ( i = 0; i < 3 – j ; i = i +1 ) if (Room[ i ].birthday >if (Room[ i ].birthday > TT Room[i+1].birthday) Room[i+1].birthday) F F

{ q= Room[ i ];{ q= Room[ i ]; Room[ i ]=Room[ i+1];Room[ i ]=Room[ i+1]; Room[ i+1]= q; }Room[ i+1]= q; }

Page 91: 5 数据组织、筛法与排序问题 的解题思路

91

int main()int main()

{ {

student student q; //q; // 定义 定义 q q 为 为 student student 结构 结构

int i = 0 ; int j =0;int i = 0 ; int j =0;

for ( j = 0; j < 3; j = j+1 ) //for ( j = 0; j < 3; j = j+1 ) // 冒泡排序冒泡排序 for ( i = 0; i < 3 – j ; i = i +1 )for ( i = 0; i < 3 – j ; i = i +1 )

if ( Room[ i ].birthday >if ( Room[ i ].birthday >

Room[i+1].birthday ) Room[i+1].birthday )

{ q= Room[ i ]; //{ q= Room[ i ]; //整体交换整体交换 Room[ i ]=Room[ i+1];Room[ i ]=Room[ i+1];

Room[ i+1]= q; }Room[ i+1]= q; }

Page 92: 5 数据组织、筛法与排序问题 的解题思路

92

for( i = 0; i < 4; i = i + 1 ) //for( i = 0; i < 4; i = i + 1 ) // 输出输出 {{ cout<< Room[ i ].name << “\n”cout<< Room[ i ].name << “\n” << Room[ i ]. sex << “\n”<< Room[ i ]. sex << “\n” << Room[ i ]. birthday << “\n”<< Room[ i ]. birthday << “\n” << Room[ i ]. height << “\n”<< Room[ i ]. height << “\n” << Room[ i ]. weight << “\n”;<< Room[ i ]. weight << “\n”; }} return 0;return 0; }}

Page 93: 5 数据组织、筛法与排序问题 的解题思路

93

5.55.5 二维数组二维数组

Page 94: 5 数据组织、筛法与排序问题 的解题思路

94

内 容 要 点内 容 要 点二维数组二维数组::

1.1. 二维数组的定义二维数组的定义2.2. 二维数组的初始化二维数组的初始化3.3. 二维数组应用实例二维数组应用实例

任务 任务 5.35.3

Page 95: 5 数据组织、筛法与排序问题 的解题思路

95

测量湖泊水深测量湖泊水深 0 1 2 3 4 5 6 7 8 x 0 1 2 3 4 5 6 7 8 x

0 0 0 0 0 0 1 2 2 31 2 2 3 0 0 0 0 0 0

1 0 1 0 2 3 5 5 3 22 3 5 5 3 2 0 0 0 0

2 0 2 0 1 4 3 4 2 2 11 4 3 4 2 2 1 0 0

3 0 0 3 0 0 1 11 1 0 0 0 0 1 11 1 0 0

4 0 0 0 0 0 0 0 0 04 0 0 0 0 0 0 0 0 0

yy

Page 96: 5 数据组织、筛法与排序问题 的解题思路

96

Lake0 0 0 Lake0 0 0 1 2 2 31 2 2 3 0 0 0 0 0 0

0 1 2 3 4 5 6 7 80 1 2 3 4 5 6 7 8

第 第 0 0 行的数据构成一维数组行的数据构成一维数组 Lake0Lake0

共有 共有 5 5 行数据构成 行数据构成 5 5 个一维数组个一维数组 Lake0, Lake1, Lake2, Lake3, Lake4Lake0, Lake1, Lake2, Lake3, Lake4

Page 97: 5 数据组织、筛法与排序问题 的解题思路

97

Lake0Lake0 Lake0Lake0[0] [0] Lake0Lake0[1] . . . [1] . . . Lake0Lake0[8][8]

Lake1Lake1 Lake1Lake1[0] [0] Lake1Lake1[1] . . . [1] . . . Lake1Lake1[8][8]

Lake2Lake2 Lake2Lake2[0] [0] Lake2Lake2[1] . . . [1] . . . Lake2Lake2[8][8]

Lake3Lake3 Lake3Lake3[0] [0] Lake3Lake3[1] . . . [1] . . . Lake3Lake3[8][8]

Lake4Lake4 Lake4Lake4[0] [0] Lake4Lake4[1] . . . [1] . . . Lake4Lake4[8][8]

下标 下标 0 1 80 1 8

Page 98: 5 数据组织、筛法与排序问题 的解题思路

98

把 把 5 5 个一维数组作为个一维数组作为 5 5 个元素放到个元素放到 一个名为 一个名为 Lake Lake 的二维数组的二维数组中中

Page 99: 5 数据组织、筛法与排序问题 的解题思路

99

Lake0 Lake0[0] Lake0[1] . . . Lake0[8]Lake0 Lake0[0] Lake0[1] . . . Lake0[8]

Lake1 Lake1[0] Lake1[1] . . . Lake1[8]Lake1 Lake1[0] Lake1[1] . . . Lake1[8]

Lake2 Lake2[0] Lake2[1] . . . Lake2[8]Lake2 Lake2[0] Lake2[1] . . . Lake2[8]

Lake3 Lake3[0] Lake3[1] . . . Lake3[8]Lake3 Lake3[0] Lake3[1] . . . Lake3[8]

Lake4 Lake4[0] Lake4[1] . . . Lake4[8]Lake4 Lake4[0] Lake4[1] . . . Lake4[8]

0 1 80 1 8

下标下标

Page 100: 5 数据组织、筛法与排序问题 的解题思路

100

Lake Lake Lake Lake

下标 下标 0 Lake0 0 Lake[0]0 Lake0 0 Lake[0]

下标 下标 1 Lake1 1 Lake[1]1 Lake1 1 Lake[1]

下标下标 2 Lake2 2 Lake[2]2 Lake2 2 Lake[2]

下标下标 3 Lake3 3 Lake[3]3 Lake3 3 Lake[3]

下标下标 4 Lake4 4 Lake[4]4 Lake4 4 Lake[4]

Page 101: 5 数据组织、筛法与排序问题 的解题思路

101

Lake[Lake[00] Lake[] Lake[00][0] Lake[][0] Lake[00][1] . . . Lake[][1] . . . Lake[00][8]][8]

Lake[Lake[11] Lake[] Lake[11][0] Lake[][0] Lake[11][1] . . . Lake[][1] . . . Lake[11][8]][8]

Lake[Lake[22] Lake[] Lake[22][0] Lake[][0] Lake[22][1] . . . Lake[][1] . . . Lake[22][8]][8]

Lake[Lake[33] Lake[] Lake[33][0] Lake[][0] Lake[33][1] . . . Lake[][1] . . . Lake[33][8]][8]

Lake[Lake[44] Lake[] Lake[44][0] Lake[][0] Lake[44][1] . . . Lake[][1] . . . Lake[44][8]][8]

[ 0 ] [ 1 ] [ 8 ][ 0 ] [ 1 ] [ 8 ]

Page 102: 5 数据组织、筛法与排序问题 的解题思路

102

[0] [1] [2] [3] [4] [5] [6] [7] [8][0] [1] [2] [3] [4] [5] [6] [7] [8]

Lake[ 0 ] 0 0 Lake[ 0 ] 0 0 1 2 2 31 2 2 3 0 0 0 0 0 0

Lake[ 1 ] 0 Lake[ 1 ] 0 2 3 5 5 3 22 3 5 5 3 2 0 0 0 0

Lake[ 2 ] 0 Lake[ 2 ] 0 1 4 3 4 2 2 11 4 3 4 2 2 1 0 0

Lake[ 3 ] 0 0 Lake[ 3 ] 0 0 1 11 1 0 0 0 0 1 11 1 0 0

Lake[ 4 ] 0 0 0 0 0 0 0 0 0Lake[ 4 ] 0 0 0 0 0 0 0 0 0

Page 103: 5 数据组织、筛法与排序问题 的解题思路

103

[0] [1] [2] [3] [4] [5] [6] [7] [8][0] [1] [2] [3] [4] [5] [6] [7] [8]

Lake[ 0 ] 0 0 1 2 2 3 0 0 0Lake[ 0 ] 0 0 1 2 2 3 0 0 0

Lake[ 1 ] 0 2 3 5 5 3 2 0 0 Lake[ 1 ] 0 2 3 5 5 3 2 0 0

Lake[ 2 ] 0 1 4 3 4 2 2 1 0 Lake[ 2 ] 0 1 4 3 4 2 2 1 0

Lake[ 3 ] 0 0 1 1 0 0 1 1 0Lake[ 3 ] 0 0 1 1 0 0 1 1 0

Lake[ 4 ] 0 0 0 0 0 0 0 0 0Lake[ 4 ] 0 0 0 0 0 0 0 0 0

Page 104: 5 数据组织、筛法与排序问题 的解题思路

104

二维数组的存储顺序二维数组的存储顺序

Lake[0][0] Lake[0][1] Lake[0][2]. . . Lake[0][0] Lake[0][1] Lake[0][2]. . .

Lake[1][0] Lake[1][1] Lake[1][2]. . .Lake[1][0] Lake[1][1] Lake[1][2]. . .

Lake[2][0] Lake[2][1] Lake[2][2]. . .Lake[2][0] Lake[2][1] Lake[2][2]. . .

Page 105: 5 数据组织、筛法与排序问题 的解题思路

105

Lake[ 0 ] 0 0 1 2 2 3 0 0 0Lake[ 0 ] 0 0 1 2 2 3 0 0 0

Lake[ 1 ] 0 2 3 5 5 3 2 0 0Lake[ 1 ] 0 2 3 5 5 3 2 0 0

Lake[ 2 ] 0 1 4 3 4 2 2 1 0 Lake[ 2 ] 0 1 4 3 4 2 2 1 0

Lake[ 3 ] 0 0 1 1 0 0 1 1 0Lake[ 3 ] 0 0 1 1 0 0 1 1 0

Lake[ 4 ] 0 0 0 0 0 0 0 0 0Lake[ 4 ] 0 0 0 0 0 0 0 0 0

Page 106: 5 数据组织、筛法与排序问题 的解题思路

106

二维数组的定义和初始化二维数组的定义和初始化

类型标示符 数组名 类型标示符 数组名 [[ 一维数组个 一维数组个数数 ] [] [一维数组中的元素个数一维数组中的元素个数 ]]

例:例: int Lake[ 5 ][ 9 ]int Lake[ 5 ][ 9 ]

Page 107: 5 数据组织、筛法与排序问题 的解题思路

107

int Lake[5][9]= int Lake[5][9]= {{

{ 0, 0, 1, 2, 2, 3, 0, 0, 0 },{ 0, 0, 1, 2, 2, 3, 0, 0, 0 },

{ 0, 2, 3, 5, 5, 3, 2, 0, 0 },{ 0, 2, 3, 5, 5, 3, 2, 0, 0 },

{ 0 , 1, 4, 3, 4, 2, 2, 1, 0 },{ 0 , 1, 4, 3, 4, 2, 2, 1, 0 },

{ 0 , 0 , 1, 1, 0, 0, 1, 1, 0 },{ 0 , 0 , 1, 1, 0, 0, 1, 1, 0 },

{ 0 , 0 , 0, 0, 0, 0, 0, 0, 0 }{ 0 , 0 , 0, 0, 0, 0, 0, 0, 0 }}};;

Page 108: 5 数据组织、筛法与排序问题 的解题思路

108

小结小结结构体是一组类型可以不一样的数据的集合,结构体是一组类型可以不一样的数据的集合,

其中的元素由符号名区分,访问时使用其中的元素由符号名区分,访问时使用 .. 运算符。运算符。在数据处理的程序设计中,经常使用结构体(类在数据处理的程序设计中,经常使用结构体(类的对象),使用数组便于组织循环,因此结构数的对象),使用数组便于组织循环,因此结构数组十分方便。组十分方便。

二维数组是多维数组,复杂问题经常会使用二维数组是多维数组,复杂问题经常会使用到。到。

自学自学参考:参考:郑莉编著 《郑莉编著 《 C++C++ 语言程序设计语言程序设计(第三版)》(第三版)》 c++2.pptc++2.ppt

下载资料及上交作业网址:下载资料及上交作业网址: ftp://ait1.lynftp://ait1.lynu.edu.cnu.edu.cn

用户名:用户名: szpx szpx 密码:密码: 111111预习:预习: 6 6 函数函数

Page 109: 5 数据组织、筛法与排序问题 的解题思路

109

作 业 作 业

读懂程序读懂程序 5_7.cpp 5_7.cpp 和 和 5_8.cpp5_8.cpp

阅读 阅读 5.6 5.6 小结小结必作必作 7575页习题页习题 ( ( 准备交流思路准备交流思路 ))