一、题目
有序顺序表的设计
实验要求:
- 有序顺序表的操作,包括初始化,求数据元素个数,插入,删除和取数据元素。放在头文件中(建议尝试用动态数组实现有序顺序表);注意有序顺序表的操作与课本上的操作有所不同,需要重写一些操作,如ListInsert(L,x),不需要参数i);
- 设计合并函数ListMerge(L1,L2,L3),其功能是把有序表L1和L2中的数据合并到L3中,要求L3中的数据依然保持有序。(要求时间复杂度O(n), n= n1+n2,n1、n2分别为两个顺序表的长度);
- 设计一个测试主函数实际验证所设计有序表的各项操作以及合并函数的正确性。
测试数据:
字符型或者整形:可选z,h,o,u, k,u,n,x,i,a,o(同学们自己名字的拼音)
二、算法思想
- 定义顺序表结构体:包括数组首元素的地址、顺序表当前长度。
- 顺序表初始化函数:在内存中开辟一段连续的内存空间用于后续储存顺序表的数据元素,将循序表当前长度赋值为0。
- 输入顺序表元素值的函数:连续输入n个数据元素并将其储存在数组中,并将顺序表表长赋值为n。
- 打印顺序表中的各数据元素的函数:利用循环打印数组元素。
- 求顺序表中数据元素个数的函数:直接返回顺序表的表长。
- 在第i个位置插入值为e的元素的函数:先判断初始条件是否成立:线性表不为空且插入位置合理,若不成立,则直接结束跳出函数。否则执行操作:从最后一个元素开始,依次用前驱元素覆盖后继元素,直到第i个元素为止,再用e给第i个元素赋值,顺序表长度自增一次。
- 删除第i个位置的元素的函数:先判断初始条件是否成立:线性表不为空且删除位置合理,若不成立,则直接结束跳出函数。否则执行操作:从第i个位置开始,依次用后继元素覆盖前驱元素,表长自减一次。
- 查找第i个元素并用e返回其值的函数:先判断初始条件是否成立:线性表不为空且查找位置合理,若不成立,则直接结束跳出函数。否则执行操作:将第i个元素的值赋值给e。
- 有序表合并的函数:建立新的顺序表储存合并后的顺序表,若两个顺序表均未插入完成,则将值小的元素插入新顺序表的表尾,再将较长的顺序表中未插入的元素插入新顺序表的表尾。
- 主函数:依次调用上述函数实现程序功能。
三、完整源代码
注:作者用的是多文件代码。
一、list.cpp
#include"list.h"void InitList(List* L)//顺序表的初始化函数
{L->a = (ElemType*)malloc(sizeof(ElemType) * MAX_SIZE);L->length = 0;
}void InputList(List* L,int n)//输入顺序表的元素值,n为待输入的元素个数
{printf("请输入%d个元素:", n);for (int i = 0; i < n; i++)scanf("%d", &L->a[i]);L->length = n;
}void PrintList(List* L)//打印顺序表的各个元素
{for (int i = 0; i < L->length; i++)printf("%d ", L->a[i]);
}int LengthList(List* L)//求数据元素个数的函数
{return L->length;//返回表长
}Status InsertElem (List* L,int i,int e)//在第i个位置前插入值为e的元素
{if (L->length == 0 || i<1 || i>L->length)//初始条件:线性表不为空且插入位置合理return ERROR;int n = L->length;for (n; n >= i; n--)//从最后一个元素开始,依次用前驱元素覆盖后继元素L->a[n] = L->a[n - 1];L->a[n] = e;//用e给第i个元素赋值L->length++;//表长加1return OK;
}Status DeleteElem(List* L,int i)//删除第i个位置的元素
{if (L->length == 0 || i<1 || i>L->length)//初始条件:线性表不为空且插入位置合理return ERROR;for (i; i < L->length; i++)//从第i个位置开始,依次用后继元素覆盖前驱元素L->a[i - 1] = L->a[i];L->length--;//表长减1return OK;
}int SeekElem(List* L, int i,int* pe)//查找第i个位置的元素并用e返回其值
{if (L->length == 0 || i<1 || i>L->length)//初始条件:线性表不为空且查找位置合理return ERROR;*pe = L->a[i - 1];return OK;
}List* ListMerge(List* L1, List* L2)//有序表合并函数
{List* L3 = (List*)malloc(sizeof(List));//建立新顺序表储存合并后的顺序表L3->a=(ElemType*)malloc(sizeof(ElemType) * MAX_SIZE * 2);L3->length = L1->length + L2->length;int i = 0,j = 0,k = 0;while (i < L1->length && j < L2->length)//两个顺序表均未插入完成{if (L1->a[i] >= L2->a[j])//将值小的元素插入新的顺序表末尾{L3->a[k] = L2->a[j];k++;j++;}else{L3->a[k] = L1->a[i];k++;i++;}}if(i==L1->length)//L1已插入完成,而L2还未完成for (j; j < L2->length; j++)//将L2中剩余元素插入新顺序表末尾{L3->a[k] = L2->a[j];k++;j++;}else//L2已插入完成,而L1还未完成for (i; i < L1->length; i++)//将L1中剩余元素插入新顺序表末尾{L3->a[k] = L1->a[i];k++;i++;}return L3;//返回新顺序表
}
二、list.h
#pragma once#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>typedef int ElemType;
typedef int Status;
#define MAX_SIZE 10//允许存储的最大元素数量
#define ERROR 0
#define OK 1typedef struct List {ElemType* a;int length;//顺序表表长
};void InitList(List* L);//顺序表的初始化函数
void InputList(List* L, int n);//输入顺序表的元素值,n为待输入的元素个数
void PrintList(List* L);//打印顺序表的各个元素
int LengthList(List* L);//求数据元素个数的函数
Status InsertElem(List* L, int i, int e);//在第i个位置插入值为e的元素
Status DeleteElem(List* L, int i);//删除第i个位置的元素
int SeekElem(List* L, int i, int* e);//查找第i个位置的元素并用e返回其值
List* ListMerge(List* L1, List* L2);//有序表合并函数
三、main.cpp
#include"list.h"int main()
{List* L1 = (List*)malloc(sizeof(List));List* L2 = (List*)malloc(sizeof(List));InitList(L1);InitList(L2);int n1;printf("请输入第一个顺序表的元素个数:");scanf("%d", &n1);InputList(L1, n1);int n2;printf("请输入第二个顺序表的元素个数:");scanf("%d", &n2);InputList(L2, n2);printf("顺序表L1中的元素个数为:%d\n", LengthList(L1));printf("顺序表L1中的元素个数为:%d\n", LengthList(L2));int i1, e1;printf("请输入待插入元素的位置和待插入元素的值:");scanf("%d %d", &i1, &e1);if(!InsertElem(L1, i1, e1))printf("插入元素失败!");printf("插入元素后的顺序表L1为:");PrintList(L1);printf("\n");int i2;printf("请输入待删除元素的位置:");scanf("%d", &i2);if (!DeleteElem(L2, i2))printf("删除元素失败!");printf("删除元素后的顺序表L2为:");PrintList(L2);printf("\n");int i;printf("请输入L1中待查找的元素位置:");scanf("%d", &i);int e;int* pe = &e;if (!SeekElem(L1, i, pe))printf("查找元素失败!");elseprintf("L1中第%d个元素的值为:%d", i, e);printf("\n");printf("L1和L2合并后的有序表为:");PrintList(ListMerge(L1, L2));return 0;
}
四、运行结果