程序填空题:有序表的插入
回顾我们在PTA上刷过的题,很多题目输入都是先在第一行给出数据个数n,然后第二行输入n个数据。想一想我们怎么存储这些数据的。因为不知道数据到底是多少个,所以需要确认n的最大值MAX,然后定义一个数组,元素个数是MAX,例如:
```
#define MAX 100
int a[MAX];
```
但是这MAX个数组空间内并不是全部存放了我们输入的数据,实际元素个数为n。所以我们在访问数组时,既要知道数组首地址,还要知道数组实际元素个数。比如函数调用时,不仅要传送数组名,还要传送数组元素的个数。
```
void printArr(int *a,int n);//打印数组元素
```
能不能把数组和数组元素个数封装在一起,只传递一个参数呢?咱们刚刚接触的结构体就可以完成。
那我们用这种思路改一改下面这道一维数组题目的做法吧。
![1.png](~/550a212d-2fef-4f45-b1b1-77ff5a776568.png)
### 输入格式:
输入在第一行先给出非负整数N(<10);第二行给出N个从小到大排好顺序的整数;第三行给出一个整数X。
### 输出格式:
在一行内输出将X插入后仍然从小到大有序的整数序列,每个数字后面有一个空格。
### 输入样例:
```
5
1 2 4 5 7
3
```
### 输出样例
```
1 2 3 4 5 7
```
由于输入的第一行是非负整数,而且是小于10的,所以定义一个长度为10的数组。但数组前N个数才使用,所以,我们另一个元素length表示数组元素实际个数。结构体定义如下:
```
struct list
{
int a[10];//定义数组a
int length;//length表示数组里有效元素的个数
};
typedef struct list list;
```
也可以
```
typedef struct list
{
int a[10];
int length;
}list;
```
该题的思路是:
```
1.输入n
2.输入n个数放在数组里
3.输入x
4.插入x
5.输出数组元素
```
输入的n该放在哪里呢?
奥,应该放在结构体length成员里。所以在具体做之前,应该定义一个结构体变量L,则需要将输入的值放在L.length成员里。
第四步插入x我们使用函数做。需要传送结构体变量L,我们知道,一般情况下,不建议使用结构体变量作为参数,所以传送L的地址吧。
那这个插入函数怎么完成呢?同学们在做这道题的时候,用的都是不同的方法,其实,最简单的方法是
```
1.从后往前对数组元素(下标为i)与x比较
如果小于等于x循环结束
如果大于x,该数组元素下移
(那循环结束条件是不是有两种情况?一种情况是数组元素小于等于x,另一种情况是下标i<0;那循环条件就应该有两个)
2.将x插入到下标为i+1的位置
3.length成员的值加1
```
```c++
#include
typedef struct list
{
int a[10];
int length;
}list;
void insert(list* L,int x);
void print(list *L);
int main()
{
list L;int x;
scanf("%d",&L.length);//输入n值送到L.length里
//输入有序的数组元素
for(int i=0;i
scanf("%d",@@[&L.a[i]](1));
}
scanf("%d",&x);
insert(@@[&L](1),x);//调用插入函数
print(&L); //调用输出函数
return 0;
}
void print(list *L)
{
//输出数组元素
for(int i=0;i<@@[L->length](1);i++)
{
printf("%d ",L->a[i]);
}
}
void insert(list* L,int x)
{
int i;
for(i=L->length-1;@@[i>=0&&L->a[i]>x](1);i--)
{
@@[L->a[i+1]](1)=L->a[i];//数组元素下移
}
@@[ L->a[i+1]](1)=x;//插入
L->length++;//实际长度加1
}
```
答案:
第1空:&L.a[i]
第2空:&L
第3空:L->length
第4空:i>=0&&L->a[i]>x
第5空:L->a[i+1]
第6空: L->a[i+1]