数据结构实验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;
}
 
五,运行效果

