数据结构实验1.2: 顺序表的基本运算
文章目录
- 一,问题描述
- 二,基本要求
- 三,算法分析
- (1)插入算法
- (2)删除算法
- 四,参考程序
- 五,运行效果
一,问题描述
创建一个顺序表,编程实现顺序表的下列基本运算:
- 在顺序表的第i个位置上插入m个新元素;
- 删除顺序表中元素值在x到y之间的所有元素。
二,基本要求
- 采用动态分配方式设计顺序表的存储结构;
- 插入算法必须考虑存储空间的动态扩充;插入和删除两种算法均必须满足时间复杂度为O(n),空间复杂度为O(1);
- 根据插入和删除的算法分析,请在参考程序中的下划线处填上适当的子句,完善参考程序;
- 设计测试数据,上机调试、测试参考程序,保存和打印测试结果,对测试结果进行分析,重点分析两种算法的性能是否达到第2条的要求;
- 运行效果图。
三,算法分析
(1)插入算法
- 判断i、m的合法性;
- 判断L.length+m是否大于L.listsize,是则扩充空间;
- 将L中的第n到第i个元素逆序向后移动m个位置;
- 在位置i处插入m个新元素。(可以是已知数组,也可键盘输入);
- 调整L的参数,算法结束。
(2)删除算法
在线性表中设置两个初值为0的下标变量i和j,其中,i为比较元素的下标,j为赋值元素的下标。依次取线性表中下标为i的元素与x和y比较,假若是x到y之外的元素,则赋值给下标为j的元素。这种算法比删除一个元素后立即移动其后面的元素的效率高得多。
四,参考程序
#define MAXSIZE 10 //空间初始分配量
#define OK 1
#define ERROR 0
#define OVERFLOW -1
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
typedef int Status;
typedef int ElemType; //将元素类型定义为整型
typedef struct {
ElemType* elem; //存储空间基址
int length; //当前顺序表中实际元素的个数
int listsize; //当前分配的存储容量
} SqList;
Status CreatList(SqList* L) { // 建立有n个元素的顺序表
int i;
do { // 若表的长度输入不合法,则循环输入
printf("请输入元素个数:");
scanf("%d", &L->length);
} while (L->length <= 0 || L->length > MAXSIZE);
L->elem = (ElemType*)malloc(MAXSIZE * sizeof(ElemType));
if (!L->elem) return ERROR;
for (i = 0; i < L->length; i++) { // 依次输入n个元素
printf("请输入第%d个元素值=>", i + 1);
scanf("%d", &L->elem[i]);
}
return OK;
}
Status InsertList(SqList* L, int i, int m, ElemType* E) {
// 在顺序表L的第i个位置上插入m个新元素E[]
if (i < 1 || i > L->length + 1 || m <= 0 || L->length + m > MAXSIZE) // 进行i、m的合法性判断
return ERROR;
ElemType* p;
int j;
if (L->length + m > L->listsize) { //若顺序表空间不够,则需扩充空间
p = (ElemType*)realloc(L->elem, (L->length + m) * sizeof(ElemType));
if (!p) exit(OVERFLOW);
L->elem = p;
L->listsize = L->length + m;
}
for (j = L->length - 1; j >= i - 1; --j) // 移动元素
L->elem[j + m] = L->elem[j];
for (j = 0; j < m; j++) // 插入元素
L->elem[i + j - 1] = E[j];
L->length = L->length + m; // 修改表的长度
return OK;
}// InsertList
Status DeleteList(SqList* L, int x, int y) {
// 在顺序表L中删除其值介于x到y之间的所有元素
if (x > y) return ERROR;
int i, j; // 临时变量j用于当前元素i前移的位置
for (i = j = 0; i < L->length; i++)
if (L->elem[i] >= x && L->elem[i] <= y)
j++;
else
L->elem[i - j] = L->elem[i]; // 前移j个位置
L->length -= j;
return OK;
}
void PrintList(SqList L) { // 输出顺序表中所有元素值
int i;
printf("顺序表中有%d个元素:\n", L.length);
for (i = 0; i < L.length; i++)
printf("%4d", L.elem[i]);
printf("\n");
}
int main()
{
SqList L;
int i, m = 3; // 插入点及插入元素个数
ElemType E[] = { 23,24,25 }; // 待插入的新元素
ElemType x, y;
printf("(1) 建立有n个元素的顺序表 ……\n");
if (!CreatList(&L)) { printf("创建顺序表失败!\n"); return 0; }
printf("当前顺序表如下:\n");
PrintList(L);
printf("(2) 在顺序表第i个位置上插入m个新元素……\n");
printf("请输入插入位置i:");
scanf("%d", &i);
if (!InsertList(&L, i, m, E))
printf("插入失败!\n");
else {
printf("插入成功!插入后的顺序表如下:\n");
PrintList(L);
}
printf("(3) 在顺序表中删除其值介于x到y之间的所有元素……\n");
printf("请输入被删元素下限值x:");
scanf("%d", &x);
printf("请输入被删元素上限值y:");
scanf("%d", &y);
if (!DeleteList(&L, x, y))
printf("参数错误,删除失败!");
else {
printf("删除后的顺序表如下:\n");
PrintList(L);
}
return 0;
}