实验一 顺序表的基本操作的实现(必做,设计性实验)
-
实验目的
熟悉将算法转换成程序代码的过程,了解顺序表的逻辑结构特性,熟练掌握顺序表存储结构的C语言描述方法。熟练掌握顺序表的基本操作:查找、插入、删除、合并等,掌握顺序表的随机存取特性。
-
实验内容(选其中之一书写实验报告)
(1)在非递减有序的顺序表中插入一个元素x,保持顺序表有序性。
(2)顺序表元素的逆置
(3)两个(有序或无序)顺序表的合并
要求用静态分配的一维数组和动态分配的一维数组来完成实验题目。分析静态分配的一维数组和动态分配的一维数组在顺序表基本操作实现上的共同点和区别。
对顺序表插入的算法,要求用两种方法实现:其一:自己编写实现函数;其二:调用顺序表基本操作ListInsert(SqList &L,int i,ElemType x),比较使用自己编写的插入函数和调用顺序表基本操作的函数两种实现方法之间的优缺点。对所编写的算法进行时间复杂度分析。
-
问题描述
题目:顺序表元素的逆序
要求:要求用静态分配的一维数组和动态分配的一维数组来完成实验题目。分析静态分配的一维数组和动态分配的一维数组在顺序表基本操作实现上的共同点和区别。
-
数据结构定义
(说明你算法中用到的数据结构、数据类型的定义)
数据结构:线性表的顺序存储结构
数据类型:*elem,length,listsize整型变量分别存储空间基地址,长度,当前分配存储容量
Typedef int ElemType;//元素类型
typedef struct node
{
ElemType data;
struct node *next;
}LNode,*LinkList;
-
算法思想及算法设计
(先文字说明算法的思想,然后给出类C语言算法)
表中元素的逆序,先确定元素个数length,也就是表的长度,先将第(length-1)后者元素赋值给中间变量temp,再将前者元素i赋值给后者元素,再将temp赋值给前者元素,完成前者后者元素的互换,通过for循环语句完成整个表中元素的逆序。
Void TransList(Sqlist *l){
for(int i=0;i<(l->length)/2;i++){
int temp = l->elem[l->length-1-i];
l->elem[l->length-1-i]=l->elem[i];
l->elem[i]=temp;
}
return OK;
}
-
实验代码
静态存储:
#include<stdio.h>
#include<stdlib.h>
#define OK 1
#define OVERFLOW 0
#define LIST_INIT_SIZE 10
#define LISTINCREMENT 5
typedef struct{
int *elem;
int length;
int listsize;
}Sqlist;
int InitList(Sqlist *l){
l->elem =new int[LIST_INIT_SIZE];
if(!l->elem){
printf("存储空间分配失败\n");
exit(OVERFLOW);
}
l->length=0;
l->listsize=LIST_INIT_SIZE;
return OK;
}
int TransList(Sqlist *l){
for(int i=0;i<(l->length)/2;i++){
int temp = l->elem[l->length-1-i];
l->elem[l->length-1-i]=l->elem[i];
l->elem[i]=temp;
}
return OK;
}
int CreatList(Sqlist *l,int length){
printf("请输入元素值:\n");
for(int i=0;i<length;i++){
scanf("%d",l->elem+i);
} l->length=length;
return OK;
}
void PrintList(Sqlist *l){
for(int i=0;i<l->length;i++){
printf("%d ",l->elem[i]);
}
}
int main(){
int length;
Sqlist l;
InitList(&l);
printf("元素的个数是:\n");
scanf("%d",&length);
CreatList(&l,length);
PrintList(&l);
printf("逆置后的结果为:\n");
TransList(&l);
PrintList(&l);
}
动态存储:
#include<stdio.h>
#include<stdlib.h>
#define OK 1
#define OVERFLOW 0
#define LIST_INIT_SIZE 10
#define LISTINCREMENT 5
typedef struct{
int *elem;
int length;
int listsize;
}Sqlist;
int InitList(Sqlist *l){
l->elem = (int *)malloc(LIST_INIT_SIZE*sizeof(int));
if(!l->elem){
printf("存储空间分配失败\n");
exit(OVERFLOW);
}
l->length=0;
l->listsize=LIST_INIT_SIZE;
return OK;
}
int CreatList(Sqlist *l,int length){
printf("请输入元素值:\n");
for(int i=0;i<length;i++){
scanf("%d",l->elem+i);
} l->length=length;
return OK;
}
void PrintList(Sqlist *l){
for(int i=0;i<l->length;i++){
printf("%d ",l->elem[i]);
}
}
int IncreaseList(Sqlist *l ,int length){
if(length>l->listsize){
int *newbase;
newbase=(int*)realloc(l->elem,(l->listsize+LISTINCREMENT)*sizeof(int));
if(!newbase){
printf("存储空间分配失败\n");
exit(OVERFLOW);
}
l->elem=newbase;
l->listsize+= LISTINCREMENT;
}
return OK;
}
int TransList(Sqlist *l){
for(int i=0;i<(l->length)/2;i++){
int temp = l->elem[i];
l->elem[i]=l->elem[l->length-1-i];
l->elem[l->length-1-i]=temp;
}
return OK;
}
int main(){
int length;
Sqlist l;
InitList(&l);
printf("元素的个数是:\n");
scanf("%d",&length);
//IncreaseList(&l,length);
CreatList(&l,length);
PrintList(&l);
printf("逆置后的结果为:\n");
TransList(&l);
PrintList(&l);
}
- 算法测试结果
(说明测试数据,粘贴实验结果图)
分别输入奇数个和偶数个数据,{1 2 3 4 5 }和{1 2 3 4 5 6 7 8}
- 分析与总结
(1)算法复杂度分析及优、缺点分析
(说明你编写算法的复杂度,算法的优点和缺点有哪些)
时间复杂度O(n)
静态顺序表创建空间时为静态开辟,不用malloc函数,代码相对简单(一点点),不存在内存泄露问题
动态顺序表,动态开辟空间,使用相对灵活,相比于静态开辟空间也可以少空间浪费
(2)实验总结
(说明你怎么解决实验中遇到的问题,有什么收获)
通过对顺序表元素的逆序操作,更加了解了线性表的存储结构和数据类型,明白了静态和动态分布的区别和优缺点,懂得了如何定义顺序表,对表内元素进行操作。