引言
- 文章结构:每一题主要是由题目、解析与注意事项和代码三部分组成。在文章的结尾,记录了我的一些做题心得。
- 建议第一次写这些题目的同学可以自己先敲一下代码,然后再参考文章中的代码。
第一题
题目
题目描述:
顺序表是数据结构中一种最基本的数据结构,它是用连续存储空间结构实现的线性表。主要包括顺序表操作,阅读顺序表数据结构定义、阅读顺序表的初始化、阅读顺序表的输出、完成插入操作、完成删除操作。
输入:
构造一个顺序表,输入数据只有 3 行,第 1 行是一个整数 n,表示顺序表元素个数;第 2
行是 n 个整数,用这 n 个整数构造顺序表;第 3 行表示删除的数据元素的位置。
输出:
依次输出顺序表中数据元素,每个元素以换行结束;然后输出被删除的数据元素数值;然
后输出被删除后的顺序表的所有元素;最后输出被删除后顺序表的长度。
输入样例:
3
10 20 30
2
输出样例
10
20
30
20
10
30
2
解析与注意事项
- 注意 ListInsert_Sq() 中 for 循环的判断条件是 「k > i - 1」不是小于。(循环中的条件是:满足了,执行循环体;不满足,则跳出循环。而不是满足该条件跳出循环。)
代码
补充函数 ListInsert_Sq() 和 ListDelete_Sq()
#include<stdio.h> //若用printf,scanf,getchar,putchar,gets,puts函数需包含该头文件
#include<malloc.h> //用malloc,free,realloc函数需包含该头文件
#define MAXSIZE 100 //设线性表初始分配空间大小
typedef int ElemType; //先设定数据元素的类型为整型
//0:定义顺序表的结构类型
typedef struct {
ElemType* elem;
int length;
int listsize;
}SqList;
//1:初始化顺序表
int InitList_Sq(SqList& L)
{
L.elem = (ElemType*)malloc(sizeof(ElemType) * MAXSIZE);
if (!L.elem) return 0;
L.length = 0;
L.listsize = MAXSIZE;
return 1;
}
//2:打印顺序表中所有元素
void PrintList(SqList& L)
{
int i;
for (i = 0; i < L.length; i++)
printf("%d\n", L.elem[i]);
}
//*****3:在顺序表中第i个位置(i=1~n)插入元素*****
int ListInsert_Sq(SqList& L, int i, ElemType e) {
if (i<1 || i>L.length + 1)
return 0;
//--------补充代码--Start------
if (L.length >= L.listsize)
return 0;
if (i <= L.length + 1)
{
for (int k = L.length - 1; k > i - 1; k--)//注意判断条件
L.elem[k + 1] = L.elem[k];
}
L.elem[i - 1] = e;
L.length++;
//--------补充代码--End-------
return 1;
}
//*****4:删除顺序表中第i(i=1~n)个元素,用e返回删除的元素*****
int ListDelete_Sq(SqList& L, int i, ElemType& e)
{
//--------补充代码--Start------
int k;
if (i<1 || i>L.length + 1 || L.length == 0)
return 0;
e = L.elem[i - 1];
if (i <= L.length)
{
for (k = i; k < L.length; k++)
L.elem[k - 1] = L.elem[k];
}
L.length--;
//--------补充代码--End-------
return 1;
}
//主函数
int main()
{
//以下代码请认真阅读,切勿做任何修改
SqList La;
int i, n, e;
//初始化顺序表
InitList_Sq(La);
//输入元素个数
scanf("%d", &n);
//依次读取n个数据插入顺序表
for (i = 1; i <= n; i++)
{
//输入数据元素
scanf("%d", &e);
//插入顺序表
ListInsert_Sq(La, i, e);
}
//按顺序输出顺序表中元素
PrintList(La);
//----------------------------
//输入要删除元素的位置
scanf("%d", &i);
//执行删除
ListDelete_Sq(La, i, e);
//输出删除后的元素
printf("%d\n", e);
//输出删除后的顺序表的内容
PrintList(La);
printf("%d\n", La.length);
return 0;
}
第二题
题目
题目描述:
顺序表是数据结构中一种最基本的数据结构,它是用连续存储空间结构实现的线性表。主要包括顺序表操作,阅读顺序表数据结构定义、阅读顺序表的初始化、阅读顺序表的输出、完成查找操作、完成翻转操作。
输入:构造一个顺序表,输入数据只有 4 行,第 1 行是一个整数 n,表示顺序表元素个数;第 2行是 n 个整数,用这 n 个整数构造顺序表;第 3 行和第 4 行输入两个待查找的数据元素的值。
输出:依次输出顺序表中数据元素,每个元素以换行结束。然后输出 2 个被查找元素的位置(未找到返回 0)。最后输出被翻转后的顺序表的所有元素。
输入样例:
4
11 22 33 44
22
55
输出样例
11
22
33
44
2
0
44
33
22
11
解析与注意事项
- 注意不要将是否相等的判断符号写成了赋值符号。如不要误将「 if (L.length == 0) 」写成「 if (L.length = 0) 」。
代码
补充函数 Location_Sq() 和 ReverseList()
#include<stdio.h> //若用printf,scanf,getchar,putchar,gets,puts函数需包含该头文件
#include<malloc.h> //用malloc,free,realloc函数需包含该头文件
#define MAXSIZE 100 //设线性表初始分配空间大小
typedef int ElemType; //先设定数据元素的类型为整型
//0:定义顺序表的结构类型
typedef struct {
ElemType* elem;
int length;
int listsize;
}SqList;
//1:初始化顺序表
int InitList_Sq(SqList& L)
{
L.elem = (ElemType*)malloc(sizeof(ElemType) * MAXSIZE);
if (!L.elem) return 0;
L.length = 0;
L.listsize = MAXSIZE;
return 1;
}
//2:打印顺序表中所有元素
void PrintList(SqList& L)
{
int i;
for (i = 0; i < L.length; i++)
printf("%d\n", L.elem[i]);
}
//3:在顺序表中查找值为e的元素,返回其位置,没有返回0
int Location_Sq(SqList L, ElemType e)
{
//--------补充代码--Start------
int i;
if (L.length == 0)
return 0;
for (i = 0; i < L.length - 1; i++)
{
if (L.elem[i] == e)
return i+1;
}
//--------补充代码--End-------
return 0;
}
//4:翻转顺序表
void ReverseList(SqList& L)
{
//--------补充代码--Start------
int i,a;
for (i = 0; i < L.length / 2; i++)
{
a = L.elem[i];
L.elem[i] = L.elem[L.length - 1 - i];
L.elem[L.length - 1 - i] = a;
}
//--------补充代码--End-------
}
//主函数
int main()
{
//以下代码请认真阅读,切勿做任何修改
SqList La;
int i, n, e;
//初始化顺序表
InitList_Sq(La);
//输入元素个数
scanf("%d", &n);
//依次读取n个数据插入顺序表
for (i = 0; i < n; i++)
{
//输入数据元素
scanf("%d", &e);
//插入顺序表
La.elem[i] = e;
}
//数据元素个数赋值
La.length = n;
//-----------------------------------
//按顺序输出顺序表中元素
PrintList(La);
//-----------------------------------
//执行2次查找操作
//输入第1次要查找的数据元素值
scanf("%d", &e);
//执行查找,输出第1次被查找的数据元素的位置
printf("%d\n", Location_Sq(La, e));
//输入第2次要查找的数据元素值,执行查找
scanf("%d", &e);
//执行查找,输出第2次被查找的数据元素的位置
printf("%d\n", Location_Sq(La, e));
//-----------------------------------
//执行翻转操作
ReverseList(La);
//输出翻转后的顺序表的内容
PrintList(La);
return 0;
}
第三题
题目
题目描述:
顺序表是数据结构中一种最基本的数据结构,它是用连续存储空间结构实现的线性表。主要包括顺序表操作,阅读顺序表数据结构定义、阅读顺序表的初始化、阅读顺序表的输出、完成合并操作。
输入:
构造一个顺序表,输入数据只有 4 行,第 1 行是一个整数 n,表示顺序表元素个数;
第 2行是 n 个非递减整数,用这 n 个整数构造顺序表 la;第 3 行是一个整数 m,表示顺序表元素个数;
第 4 行是 m 个非递减整数,用这 m 个整数构造顺序表 lb。
输出:依次输出 la 和 lb 合并后的顺序表 lc 中所有元素。
输入样例:
3
5 7 7
2
3 8
输出样例
3
5
7
7
8
解析与注意事项
- 将Lb放入Lc中时,「Lb.elem[j]」下标要从0开始,故不能为i。
代码
补充函数 MergeList()。
#include<stdio.h> //若用printf,scanf,getchar,putchar,gets,puts函数需包含该头文件
#include<malloc.h> //用malloc,free,realloc函数需包含该头文件
#define MAXSIZE 100 //设线性表初始分配空间大小
typedef int ElemType; //先设定数据元素的类型为整型
//0:定义顺序表的结构类型
typedef struct {
ElemType* elem;
int length;
int listsize;
}SqList;
//1:初始化顺序表
int InitList_Sq(SqList& L)
{
L.elem = (ElemType*)malloc(sizeof(ElemType) * MAXSIZE);
if (!L.elem) return 0;
L.length = 0;
L.listsize = MAXSIZE;
return 1;
}
//2:打印顺序表中所有元素
void PrintList(SqList& L)
{
int i;
for (i = 0; i < L.length; i++)
printf("%d\n", L.elem[i]);
}
//3:合并两个有序的顺序表,La,Lb有序,合并到Lc
void MergeList(SqList La, SqList Lb, SqList& Lc)
{
//--------补充代码--Start------
int i,j;
ElemType e;
//先将La和Lb的元素放入Lc中
for (i = 0; i < La.length; i++)
{
Lc.elem[i] = La.elem[i];
}
for (j=0; j<Lb.length; j++)
{
Lc.elem[i] = Lb.elem[j];//Lb.elem[j]下标要从0开始,故不能为i
i++;
}
Lc.length = i;
//用直接插入排序法给Lc中的元素排序
for (i = 1; i < Lc.length; i++)
{
if (Lc.elem[i] < Lc.elem[i - 1])
{
e = Lc.elem[i];
for (j = i - 1; Lc.elem[j] > e; j--)
Lc.elem[j + 1] = Lc.elem[j];
Lc.elem[j+1] = e;
}
}
//--------补充代码--End-------
}
//主函数
int main()
{
//以下代码请认真阅读,切勿做任何修改
//将list[0]和list[1]合并到list[2]
SqList list[3];
int i, k, n, e;
//构造2个数据表
for (k = 0; k < 2; k++)
{
//初始化顺序表list 1,2
InitList_Sq(list[k]);
//有序输入第k个顺序表数据元素个数
scanf("%d", &n);
//依次读取n个数据插入顺序表
for (i = 0; i < n; i++)
{
//输入数据元素
scanf("%d", &e);
//插入顺序表
list[k].elem[i] = e;
}
//数据元素个数赋值
list[k].length = n;
}
//初始化顺序表list 3
InitList_Sq(list[2]);
//-----------------------------------
//执行合并操作
MergeList(list[0], list[1], list[2]);
//按顺序输出顺序表list[3]中元素
PrintList(list[2]);
return 0;
}
做题心得
- 本实验用到的代码在OJ上提交时,要用C++不能用C,否则会报「编译错误」。
- 多测试代码。每完成一部分就测试一下,不要等全部写完在一起测试。这样更便于找到代码中的Bug,尤其是一些粗心产生的Bug。
- 注意不要将是否相等的判断符号写成了赋值符号。
- 循环中的条件是:满足了,执行循环体;不满足,则跳出循环。而不是满足该条件跳出循环。
- 大多数情况下,用顺序表表长做循环条件时,表长减一了,就不要再用小于等于;用了小于等于,表长就不要再减一了。
- 代码运行出问题了,不要总是自己硬想,写的时候没看出来的问题,查的时候也很难看出来。不会的问题要多与老师、同学们交流,多请教别人。