💡 【习题集】 ▼01 绪论

This commit is contained in:
康建伟
2018-01-14 23:34:40 +08:00
parent 7ca9aa9473
commit dd74e62537
22 changed files with 611 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 520 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -0,0 +1,52 @@
#include <stdio.h>
/* 函数原型 */
void Algo_1_16(int i, int j, int k);
int main(int argc, char *argv[])
{
int i, j, k;
i = 3;
j = 7;
k = 1;
printf("作为示范,设定依次读入的三个整数为:%d %d %d...\n", i, j, k);
printf("这三个数从大到小的顺序为:");
Algo_1_16(i, j, k);
printf("\n");
return 0;
}
/*━━━━━━━━━━━━━━━━━━┓
┃题1.16将3个整数按从大到小顺序输出 ┃
┗━━━━━━━━━━━━━━━━━━*/
void Algo_1_16(int i, int j, int k)
{
int tmp;
if(i<j)
{
tmp = i;
i = j;
j = tmp;
}
if(j<k)
{
tmp = j;
j = k;
k = tmp;
}
if(i<j)
{
tmp = i;
i = j;
j = tmp;
}
printf("%d %d %d\n", i, j, k);
}

View File

@@ -0,0 +1,79 @@
#include <stdio.h>
#include <stdlib.h> //提供malloc、realloc、free、exit原型
#include "../../../▲课本算法实现/▲01 绪论/Status.h" //**▲01 绪论**//
/* 函数原型 */
int Algo_1_17_1(int k, int m);
int Algo_1_17_2(int k, int m);
int main(int argc, char *argv[])
{
int k, m;
k = 3;
m = 10;
printf("作为示范,求得 %d 阶斐波那契数列第 %d 项的值为:%d \n", k, m, Algo_1_17_1(k, m));
printf("作为示范,求得 %d 阶斐波那契数列第 %u 项的值为:%d \n", k, 2*m, Algo_1_17_2(k, 2*m));
printf("\n");
return 0;
}
/*━━━━━━━━━━━━━━━━━━┓
┃题1.17计算k阶斐波那契数列第m项的值┃
┗━━━━━━━━━━━━━━━━━━*/
/* 方法1递归算法 */
int Algo_1_17_1(int k, int m) //当m变大时计算速度会递减
{
int i, value;
if(k<2 || m<0)
exit(OVERFLOW);
if(m<k-1)
return 0;
else if(m==k-1)
return 1;
else
{
for(i=1,value=0; i<=k; i++)
value += Algo_1_17_1(k, m-i);
return value;
}
}
/*━━━━━━━━━━━━━━━━━━┓
┃题1.17计算k阶斐波那契数列第m项的值┃
┗━━━━━━━━━━━━━━━━━━*/
/* 方法2递推迭代算法 */
int Algo_1_17_2(int k, int m)
{
int i, j;
int fib[m+1];
if(k<1 || m<0)
exit(OVERFLOW);
i = 0;
while(i<k-1)
{
fib[i] = 0;
i++;
}
fib[i] = 1; //i = k-1
i++;
while(i<=m) //i = k
{
for(j=i-1,fib[i]=0; j>=i-k; j--)
fib[i] += fib[j];
i++;
}
return fib[m];
}

View File

@@ -0,0 +1,51 @@
#include <stdio.h>
#include <limits.h> //提供宏INT_MAX
#include "../../../▲课本算法实现/▲01 绪论/Status.h" //**▲01 绪论**//
/* 宏定义 */
#define arrsize 20 //数组长度
#define maxint INT_MAX //最大的整数
/* 函数原型 */
Status Algo_1_19(int i, int a[]);
int main(int argc, char *argv[])
{
int i, a[arrsize];
i = 5;
printf("计算i!*2^i...\n");
if(Algo_1_19(i, a)==OK)
printf("作为示例计算当i = %d 时a[i-1] = %d\n", i, a[i-1]);
printf("\n");
return 0;
}
/*━━━━━━━━━━━━━━━━━━━┓
┃题1.19计算i!*2^i存入a[i-1]i起点为1┃
┗━━━━━━━━━━━━━━━━━━━*/
Status Algo_1_19(int i, int a[])
{
int j;
if(i<1 || i>arrsize)
return ERROR;
for(j=1; j<=i; j++)
{
if(j==1)
a[j-1] = 2;
else
{
if(maxint/(2*j)<a[j-2])
return OVERFLOW;
a[j-1] = 2 * j * a[j-2];
}
}
return OK;
}

View File

@@ -0,0 +1,32 @@
#include <stdio.h>
#include <math.h> //提供pow原型
/* 函数原型 */
int Algo_1_20(int a[], int x, int n);
int main(int argc, char *argv[])
{
int a[5] = {-2, 3, 6,-8, 7};
int n = 5;
int Xo = 3;
printf("作为示范设定项数n = 5变量Xo = 3计算Pn(Xo)...\n");
printf("P%d(%d) = %d\n", n, Xo, Algo_1_20(a, Xo, n));
printf("\n");
return 0;
}
/*━━━━━━━━━━━━━━┓
┃题1.20计算多项式Pn(Xo)的值┃
┗━━━━━━━━━━━━━━*/
int Algo_1_20(int a[], int x, int n)
{
int i;
int tmp;
for(i=1,tmp=0; i<=n; i++)
tmp += a[i-1]*pow(x, i-1);
return tmp;
}

View File

@@ -0,0 +1,397 @@
# 第1章 绪论
## 一、基础知识题
### 1.1 简述下列术语:数据、数据元素、数据对象、数据结构、存储结构、数据类型和抽象数据类型。
> **数据**(data)是对客观事物的符号表示。在计算机科学中是指所有能输入到计算机中并被计算机程序处理的符号的总称。
> **数据元素**(data element)是数据的基本单位,在计算机程序中通常作为一个整体进行考虑和处理。
> **数据对象**(data object)是性质相同的数据元素的集合,是数据的一个子集。
> **数据结构**(data structure)是相互之间存在一种或多种特定关系的数据元素的集合。
> **存储结构****物理结构**)是数据结构在计算机中的表示(又称映像)。
> **数据类型**(data type)是一个值的集合和定义在这个值集上的一组操作的总称。
> **抽象数据类型**(Abstract Data Type)是指一个数学模型以及定义在该模型上的一组操作。
### 1.2 试描述数据结构和抽象数据类型的概念与程序设计语言中数据类型概念的区别。
> 简单地说,数据结构定义了一组按某些关系结合在一起的数组元素。数据类型不仅定义了一组带结构的数据元素,而且还在其上定义了一组操作。
### 1.3 设有数据结构DR其中D={d1,d2,d3,d4}R={r}r={(d1,d2),(d2,d3),(d3,d4)}。试按图论中图的画法惯例画出其逻辑结构图。
![1.3](_v_images/20181124235659821_31062.png)
### 1.4 试仿照三元组的抽象数据类型分别写出抽象数据类型复数和有理数的定义(有理数是其分子、分母均为自然数且分母不为零的分数)。
```c
ADT Complex //复数定义 a±bi
{
D = {a, b | a,b为实数}
R = {<a, b>}
InitComplex(&C, re, im)
Cre和im
DestroyCmoplex(&C)
C
Get(C, k, &e)
C已存在
e返回复数C的第k元的值
Put(&C, k, e)
C已存在
C的第k元的值为e
IsAscending(C)
C已存在
C的两个元素按升序排列10
IsDescending(C)
C已存在
C的两个元素按降序排列10
Max(C, &e)
C已存在
e返回复数C的两个元素中值较大的一个
Min(C, &e)
C已存在
e返回复数C的两个元素中值较小的一个
}ADT Complex
```
```c
ADT RationalNumber //有理数定义
{
D={s, m | s,m为自然数m不为0}
R={<s, m>}
InitRationalNumber(&R, s, m)
Rs和m
DestroyRationalNumber(&R)
R
Get(R, k, &e)
R已存在
e返回有理数R的第k元的值
Put(&R, k, e)
R已存在
R的第k元的值为e
IsAscending(R)
R已存在
R的两个元素按升序排列10
IsDescending(R)
R已存在
R的两个元素按降序排列10
Max(R, &e)
R已存在
e返回有理数R的两个元素中值较大的一个
Min(R, &e)
R已存在
e返回有理数R的两个元素中值较小的一个
}ADT RationalNumber
```
### 1.5 试画出与下列程序段等价的框图。
**(1)**
```c
product = 1;
i = 1;
while(i<=n)
{
product *= i;
i++;
}
```
![1.5.1](_v_images/20181124235559962_1540.png)
**(2)**
```c
i=0;
do
{
i++;
}while((i!=n) && (a[i]!=x));
```
![1.5.2](_v_images/20181124235736015_5587.png)
**(3)**
```c
switch
{
case x<y:
z=y-x;
break;
case x==y:
z=abs(x*y);
break;
default:
z=(x-y)/abs(x)*abs(y);
}
```
![1.5.3](_v_images/20181124235749817_29555.png)
### 1.6 在程序设计中,常用下列三种不同的出错处理方式:
#### 1用exit语句终止执行并报告错误
#### 2以函数的返回值区别正确返回或错误返回
#### 3设置一个整型变量的函数参数以区别正确返回或某种错误返回。
### 试讨论这三种方法各自的优缺点。
> 1exit常用于严重错误处理它可以强行中断程序的执行返回操作系统。优点是可以在程序的任何地方关闭程序缺点是隐藏了故障信息。
> 2以函数的返回值判断正确与否常用于子程序的测试便于实现程序的局部控制。
> 3用整型变量进行错误处理的优点是可以给出错误类型便于迅速定位错误。
### 1.7 在程序设计中,可采用下列三种方法实现输出和输入:
#### 1通过scanf和printf语句
#### 2通过函数的参数显式传递
#### 3通过全局变量隐式传递。
### 试讨论这三种方法的优缺点。
> 1用scanf和printf直接进行输入输出的好处是形象、直观但缺点是需要对其进行格式控制较为烦琐如果出现错误则会引起整个系统的崩溃。
> 2通过函数的参数传递进行输入输出便于实现信息的隐蔽减少出错的可能。
> 3通过全局变量的隐式传递进行输入输出最为方便只需修改变量的值即可但过多的全局变量使程序的维护较为困难。
### 1.8 设n为正整数。试确定下列各程序段中前置以记号@的语句的频度:
**1**
```c
i = 1; k = 0;
while(i <= n-1)
{
@ k += 10 * i;
i++;
}
```
> n-1
**2**
```c
i = 1; k = 0;
do
{
@ k += 10 * i;
i++;
}while(i <= n-1);
```
> n-1
**3**
```c
i = 1; k = 0;
while(i <= n-1)
{
i++;
@ k += 10 * i;
}
```
> n-1
**4**
```c
k = 0;
for(i=1; i<=n; i++)
{
for(j=i; j<=n; j++)
@ k++;
}
```
> ![1.8.4](_v_images/20181125001012797_15869.png)
**5**
```c
for(i=1; i<=n; i++)
for(j=1; j<=i; j++)
for(k=1; k<=j; k++)
@ x += 1;
```
> ![1.8.5](_v_images/20181125001057524_32274.png)
**6**
```c
i = 1; j = 0;
while(i+j <= n)
{
@ if(i>j)
j++;
else
i++;
}
```
> n
**7**
```c
x = n; y = 0; //n是不小于1的常数
while(x >= (y+1)*(y+1))
@ y++;
```
> ![1.8.7](_v_images/20181125001138318_16618.png)
**8**
```c
x = 91; y = 100;
while(y>0)
{
@ if(x>100)
{
x -= 10;
y--;
}
else
x++ ;
}
```
> 1100
### 1.9 假设n为2的乘幂并且n>2,试求下列算法的时间复杂度及变量count的值以n的函数形式表示
```c
int Time (int n)
{
count = 0;
x = 2;
while(x<n/2)
{
x *= 2;
count++;
}
return (count)
}//Time
```
> 时间复杂度O(log2n)
> count = log2n - 2
### 1.10 按增长率由小至大的顺序排列下列各函数:
#### 2<sup>100</sup>(3/2)<sup>n</sup>(2/3)<sup>n</sup>(4/3)<sup>n</sup>n<sup>n</sup>n<sup>3/2</sup>n<sup>2/3</sup>√nnnlog<sub>2</sub>nn/log<sub>2</sub>nlog<sup>2</sup><sub>2</sub>nlog<sub>2</sub>(log<sub>2</sub>n)nlog<sub>2</sub>nn<sup>log<sub>2</sub>n</sup>
> 各函数的排列次序如下:
![1.10.1](_v_images/20181125002335576_8701.png)
![1.10.2](_v_images/20181125002344865_51.png)
### 1.11 已知有实现同一功能的两个算法其时间复杂度分别为O(2<sup>n</sup>)和O(n<sup>10</sup>)假设现实计算机可连续运算的时间为10<sup>7</sup>秒100多天又每秒可执行基本操作根据这些操作来估算算法时间复杂度10<sup>5</sup>次。试问在此条件下这两个算法可解问题的规模即n值的范围各为多少哪个算法更适宜请说明理由。
> 2<sup>n</sup>=10<sup>12</sup>求得n=40
> n<sup>10</sup>=10<sup>12</sup>求得n=16
> 故第一种算法较适宜。因为在同样的算力下第一种算法可解的n值较大。
> 由此可见虽然一般情况下多项式阶的算法优于指数阶的算法但高次多项式的算法在n的很大范围内不如某些指数阶的算法。
### 1.12 设有以下三个函数:
#### f(n)=21n<sup>4</sup>+n<sup>2</sup>+1000g(n)=15n<sup>4</sup>+500n<sup>2</sup>h(n)=5000n<sup>3.5</sup>+nlogn
### 请判断以下断言正确与否:
#### 1f(n)是O(g(n))
#### 2h(n)是O(f(n))
#### 3g(n)是O(h(n))
#### 4h(n)是O(n<sup>3.5</sup>)
#### 5h(n)是O(nlogn)
> (1) 对 (2) 错 (3) 错 (4) 对 (5) 错
### 1.13 试设定若干n值比较两函数n<sup>2</sup>和50nlog<sub>2</sub>n的增长趋势并确定n在什么范围内时n<sup>2</sup>的值大于50nlog<sub>2</sub>n。
> 大约在n>450时 函数n<sup>2</sup>的值才大于函数50nlog<sub>2</sub>n的值。
![1.13](_v_images/20181125003217769_19055.png)
### 1.14 判断下列各对函数f(n)和g(n)当n→∞时哪个函数增长更快
![1.14](_v_images/20181125003411487_11601.png)
> (1) g(n)快 (2) g(n)快 (3) f(n)快 (4) f(n)快
### 1.15 试用数学归纳法证明:
![1.15](_v_images/20181125003506946_12124.png)
![1.15.1](_v_images/20181125003527776_6872.png)
![1.15.2](_v_images/20181125003543569_28283.png)
![1.15.3](_v_images/20181125003604248_12415.png)
![1.15.4](_v_images/20181125003616918_30233.png)
## 二、算法设计题
### 1.16 试写一算法自大到小依次输出顺序读入的三个整数XY和Z的值。
> [Question-1.16-main.c](▼习题测试文档-01/Question-1.16-main.c)
### 1.17 已知k阶斐波那契序列的定义为
#### f0=0, f1=0, …, fk-2=0, fk-1=1;
#### fn=fn-1+fn-2+…+fn-k, n=k,k+1,…
### 试编写求k阶斐波那契序列的第m项值的函数算法k和m均以值调用的形式在函数参数表中出现。
> [Question-1.17-main.c](▼习题测试文档-01/Question-1.17-main.c)
### 1.18 假设有A、B、C、D、E五个高等院校进行田径对抗赛各院校的单项成绩均已存入计算机并构成一张表表中每一行的形式为
|项目名称|性别|校名|成绩|得分|
|---------|-----|----|-----|----|
| | | | | |
### 编写算法,处理上述表格,以统计各院校的男、女总分和团体总分,并输出。
```c
typedef enum {A, B, C, D, E} SchoolName;
typedef enum {FEMALE, MALE} SexType;
typedef enum {X, Y, Z} Event;
typedef struct
{
Event e; //项目名称
SexType sex; //性别
SchoolName school; //校名
int score; //得分
}Component;
typedef struct
{
int malesum; //男团总分
int femalesum; //女团总分
int totalsum; //团体总分
}Sum;
Component report[n]; //n条记录
Sum result[5];
//算法过程体中主要结构
for(i=0; i<n; i++)
{
//对result[report[i].school]进行处理
}
for(s=A; s<=E; s++)
{
//printf(...);
}
```
### 1.19 试编写算法计算i!*2<sup>i</sup>的值并存入数组a[0..arrsize-1]的第i-1个分量中(i=1,2,…,n)。假设计算机中允许的整数最大值为maxint则当n>arrsize或对某个k(1≤k≤n)使k!*2<sup>k</sup>>maxint时应按出错处理。注意选择你认为较好的出错处理方法。
> [Question-1.19-main.c](▼习题测试文档-01/Question-1.19-main.c)
### 1.20 试编写算法求一元多项式:
![1.20](_v_images/20181125004220502_31495.png)
### 的值Pn(x)并确定算法中每一语句的执行次数和整个算法的时间复杂度。注意选择你认为较好的输入和输出方法。本题的输入为ai(i=0,1,…,n)x0和n输出为Pn(x0)。
> [Question-1.20-main.c](▼习题测试文档-01/Question-1.20-main.c)