实验一 顺序表基本操作的实现
一、实验目的
1.掌握线性表的顺序存贮结构及基本操作,深入了解顺序表的基本特性,以便在实际问题背景下灵活运用它们。
2.深入理解和灵活掌握顺序表的插入、删除等操作。
二、实验环境
1.硬件:每个学生需配备计算机一台。
2.软件:Windows操作系统+Visual C++。
三、实验要求
1.将建表、遍历、插入、删除分别定义为4个子函数,通过主函数实现对上述子函数的调用。
2.输入数据:数据类型设定为整型
四、实验内容
实现顺序表各种基本运算的基础上,设计主程序,完成如下功能:
(1)初始化顺序表L。
(2)依次插入2,5,7,9,10共5个元素。
(3)输出顺序表L。
(4)输出顺序表L的长度。
(5)判断顺序表L是否为空。
(6)输出顺序表L第4个元素。
(7)输出元素5的位置。
(8)在第4个元素的位置上插入元素100。
(9)输出顺序表L。
(10)删除顺序表L的第3个元素。
(11)输出顺序表L。
(12)释放顺序表L。
实现程序:
#include<stdio.h>
#include<malloc.h>
#define MaxSize 50
typedef int ElemType;
//定义顺序表
typedef struct{
ElemType data[MaxSize]; //存放顺序表元素
int length; //存放顺序表的长度
}SqList; //声明顺序表的类型
//创建顺序表
void CreateList(SqList *&L,ElemType a[],int n)
{
int i=0,k=0;
L=(SqList *)malloc(sizeof(SqList));
while(i<n)
{
L->data[k]=a[i];
k++;
i++;
}
L->length=k;
}
//初始化线性表
void InitList(SqList *&L){
L=(SqList *)malloc(sizeof(SqList));
L->length=0;
}
//销毁线性表
void DestroyList(SqList *&L){
free(L);
}
//判断线性表是否为空表
bool ListEmpty(SqList *L){
return(L->length==0);
}
//求线性表的长度
int ListLength(SqList *L){
return(L->length);
}
//输出顺序表
void DispList(SqList *L)
{
for(int i=0;i<L->length;i++)
{
printf("%d",L->data[i]);
}
}
//求线性表的第i个元素
bool GetElem(SqList *L,int i,ElemType &e)
{
if(i<1 || i>L->length)
return false;
e=L->data[i-1];
return true;
}
//查找第一个值为e的元素值
int LocateElem(SqList *L,ElemType e)
{
int i=0;
while(i<L->length && L->data[i]!=e)
i++;
if(i>=L->length)
return 0;
else
return i+1;
}
//插入第i个元素
bool ListInsert(SqList *&L,int i,ElemType e)
{
int j;
if(i<1 || i>L->length+1 || L->length==MaxSize)
return false;
i--;
for(j=L->length;j>i;j--)
L->data[j]=L->data[j-i];
L->data[i]=e;
L->length++;
return true;
}
//删除第i个元素
bool ListDelete(SqList *&L,int i,ElemType &e)
{
int j;
if(i<1 || i>L->length)
return false;
i--;
e=L->data[i];
for(j=i;j<L->length-1;j++)
L->data[j]=L->data[j+1];
L->length--;
return true;
}
void main()
{
SqList *L;
ElemType e;
printf("顺序表的基本运算如下:\n");
printf("(1)初始化顺序表L\n");InitList(L);
printf("(2)依次插入2,5,7,9,10\n");
int i,y;
char s;
//循环输入,遇到回车停止输入
for(i=1;i<51&&s!='\n';i++){
scanf("%d",&y);
s=getchar();
ListInsert(L,i,y);
}
printf("(3)输出顺序表L");DispList(L);
printf("\n(4)输出顺序表L长度:%d\n",ListLength(L));
printf("(5)顺序表L为%s\n",(ListEmpty(L)?"空":"非空"));
GetElem(L,3,e);
printf("(6)顺序表L的第3个元素:%d\n",e);
printf("(7)元素5的位置:%d\n",LocateElem(L,5));
printf("(8)在第4个元素位置上插入100");ListInsert(L,4,100);
printf("\n(9)输出顺序列表L:");
DispList(L);
printf("\n(10)删除L的第3个元素\n");
ListDelete(L,3,e);
printf("(11)输出顺序表L:");
DispList(L);
printf("\n(12)释放顺序表L\n");
DestroyList(L);
}
运行结果:
测试结果:
通过!
2.顺序表的应用
(1)设计算法,删除顺序表中所有值等于x的元素。
实现程序:
#include<stdio.h>
#include<malloc.h>
#define MaxSize 50
typedef int ElemType;
//定义顺序表
typedef struct{
ElemType data[MaxSize]; //存放顺序表元素
int length; //存放顺序表的长度
}SqList; //声明顺序表的类型
//创建顺序表
void CreateList(SqList *&L,ElemType a[],int n)
{
int i=0,k=0;
L=(SqList *)malloc(sizeof(SqList));
while(i<n)
{
L->data[k]=a[i];
k++;
i++;
}
L->length=k;
}
//初始化线性表
void InitList(SqList *&L){
L=(SqList *)malloc(sizeof(SqList));
L->length=0;
}
//销毁线性表
void DestroyList(SqList *&L){
free(L);
}
//输出顺序表
void DispList(SqList *L)
{
for(int i=0;i<L->length;i++)
{
printf("%d",L->data[i]);
}
}
//插入第i个元素
bool ListInsert(SqList *&L,int i,ElemType e)
{
int j;
if(i<1 || i>L->length+1 || L->length==MaxSize)
return false;
i--;
for(j=L->length;j>i;j--)
L->data[j]=L->data[j-i];
L->data[i]=e;
L->length++;
return true;
}
//顺序表的删除
bool Delete(SqList *&L,int a)
{
int k=0;
for(int i=0;i<L->length ;i++)
{
if(L->data[i]==a)//当前元素为a时k增1
{
k++;
}
else
{
L->data [i-k]=L->data [i];//当前元素不a时将其前移k个位置
}
}
L->length -= k;//顺序表L的长度减K
return true;
}
void main()
{
SqList *L;
InitList(L);
printf("请输入顺序表用空格分开按回车结束\n");
int i,y;
char s;
for(i=1;i<51&&s!='\n';i++){
scanf("%d",&y);
s=getchar();
ListInsert(L,i,y);
}
printf("输出顺序表L");DispList(L);
printf("\n请输入删除元素:\n");
int a;
scanf("%d",&a);
Delete(L,a);
printf("输出顺序表L\n");
DispList(L);
}
运行结果:
测试结果:
通过!
(2)设计算法,将顺序表L中所有奇数移动到偶数的前面。
实现程序:
#include<stdio.h>
#include<malloc.h>
#define MaxSize 50
typedef int ElemType;
//定义顺序表
typedef struct{
ElemType data[MaxSize]; //存放顺序表元素
int length; //存放顺序表的长度
}SqList; //声明顺序表的类型
//创建顺序表
void CreateList(SqList *&L,ElemType a[],int n)
{
int i=0,k=0;
L=(SqList *)malloc(sizeof(SqList));
while(i<n)
{
L->data[k]=a[i];
k++;
i++;
}
L->length=k;
}
//初始化线性表
void InitList(SqList *&L){
L=(SqList *)malloc(sizeof(SqList));
L->length=0;
}
//销毁线性表
void DestroyList(SqList *&L){
free(L);
}
//插入第i个元素
bool ListInsert(SqList *&L,int i,ElemType e)
{
int j;
if(i<1 || i>L->length+1 || L->length==MaxSize)
return false;
i--;
for(j=L->length;j>i;j--)
L->data[j]=L->data[j-i];
L->data[i]=e;
L->length++;
return true;
}
//输出顺序表
void DispList(SqList *L)
{
int i,b;
int a=0;
int j=L->length-1;
while(a<j){
while((j>=0)&&(L->data[j]%2==0))
j--;
while((a<j)&&(L->data[a]%2==1))
a++;
if(a<j){
b=L->data[j];
L->data[j]=L->data[a];
L->data[a]=b;
}
}
for(i=0;i<L->length;i++){
printf("%d",L->data[i]);
}
}
void main()
{
SqList *L;
InitList(L);
printf("请输入顺序表用空格分开按回车结束\n");
int i,y;
char s;
for(i=1;i<51&&s!='\n';i++){
scanf("%d",&y);
s=getchar();
ListInsert(L,i,y);
}
printf("输出顺序表L");
DispList(L);
printf("\n");
DestroyList(L);
}
运行结果:
测试结果:
通过!
五、思考题
1.删除顺序表中自第i个元素起连续k个元素。
程序实现:
#include<stdio.h>
#include<malloc.h>
#define MaxSize 50
typedef int ElemType;
//定义顺序表
typedef struct{
ElemType data[MaxSize]; //存放顺序表元素
int length; //存放顺序表的长度
}SqList; //声明顺序表的类型
//创建顺序表
void CreateList(SqList *&L,ElemType a[],int n)
{
int i=0,k=0;
L=(SqList *)malloc(sizeof(SqList));
while(i<n)
{
L->data[k]=a[i];
k++;
i++;
}
L->length=k;
}
//初始化线性表
void InitList(SqList *&L){
L=(SqList *)malloc(sizeof(SqList));
L->length=0;
}
//销毁线性表
void DestroyList(SqList *&L){
free(L);
}
//判断线性表是否为空表
bool ListEmpty(SqList *L){
return(L->length==0);
}
//求线性表的长度
int ListLength(SqList *L){
return(L->length);
}
//输出顺序表
void DispList(SqList *L)
{
for(int i=0;i<L->length;i++)
{
printf("%d",L->data[i]);
}
}
//插入第i个元素
bool ListInsert(SqList *&L,int i,ElemType e)
{
int j;
if(i<1 || i>L->length+1 || L->length==MaxSize)
return false;
i--;
for(j=L->length;j>i;j--)
L->data[j]=L->data[j-i];
L->data[i]=e;
L->length++;
return true;
}
//顺序表的删除
bool Delete(SqList *&L,int a)
{
if(L->length==0) //线性表为空
return 0;
if(a<L->length)
{
for(int i=a;i<L->length;i++)
{
L->data[i-1]=L->data[i];
}
L->length--;
}
return 1;
}
void main()
{
SqList *L;
InitList(L);
printf("请输入顺序表用空格分开按回车结束\n");
int i,y;
char s;
for(i=1;i<51&&s!='\n';i++){
scanf("%d",&y);
s=getchar();
ListInsert(L,i,y);
}
printf("输出顺序表L");DispList(L);
printf("\n请输入删除的位置和删除的元素个数:\n");
int a,b;
scanf("%d%d",&a,&b);
if(b>=L->length)
{
printf("输入有误\n");
}
else
{
while(b--)
{
Delete(L,a);
}
}
printf("输出顺序表L\n");
DispList(L);
DestroyList(L);
}
运行结果:
测试结果:
通过!
2.已知顺序表递减有序,将元素x插入,保持其有序性
程序实现:
#include<stdio.h>
#include<malloc.h>
#define MaxSize 50
typedef int ElemType;
//定义顺序表
typedef struct{
ElemType data[MaxSize]; //存放顺序表元素
int length; //存放顺序表的长度
}SqList; //声明顺序表的类型
//创建顺序表
void CreateList(SqList *&L,ElemType a[],int n)
{
int i=0,k=0;
L=(SqList *)malloc(sizeof(SqList));
while(i<n)
{
L->data[k]=a[i];
k++;
i++;
}
L->length=k;
}
//初始化线性表
void InitList(SqList *&L){
L=(SqList *)malloc(sizeof(SqList));
L->length=0;
}
//销毁线性表
void DestroyList(SqList *&L){
free(L);
}
//输出顺序表
void DispList(SqList *L)
{
int n;
int l;
n=L->length;
//冒泡排序法从小到大排序
for(int i=0;i<n-1;i++)
{
for(int j=0;j<n-1-i;j++){
if(L->data[j]<L->data[j+1]){
l=L->data[j];
L->data[j]=L->data[j+1];
L->data[j+1]=l;
}
}
}
for(i=0;i<L->length;i++){
printf("%d",L->data[i]);
}
}
//插入元素
bool ListInserts(SqList *&L,int i,ElemType e)
{
int j;
if(i<1 || i>L->length+1 || L->length==MaxSize)
return false;
i--;
for(j=L->length;j>i;j--)
L->data[j]=L->data[j-i];
L->data[i]=e;
L->length++;
return true;
}
//插入新增元素到最后
bool ListInsert(SqList *&L,ElemType e)
{
int i;
i=L->length+1;
ListInserts(L,i,e);
return true;
}
void main()
{
SqList *L;
InitList(L);
printf("请输入顺序表用空格分开按回车结束\n");
int i,y;
char s;
for(i=1;i<51&&s!='\n';i++){
scanf("%d",&y);
s=getchar();
ListInserts(L,i,y);
}
printf("输出顺序表L");DispList(L);
printf("\n输入要插入的元素");
int f;
scanf("%d",&f);
ListInsert(L,f);
printf("再次输出顺序表");
DispList(L);
printf("\n");
DestroyList(L);
}
运行结果:
测试结果:
通过!
六、实验总结
通过本次增加了对C语言的掌握,对顺序表的建表、初始化、输出等操作有了进一步的认识,同时对C语言主函数和子函数的调用进一步的认识。领会顺序表存储结构和掌握顺序表中各种基本运算算法的设计。对C语言循环结构、冒泡排序法等方法进行了复习。在实验过程中会出现很多问题,出现程序报错的情况。在测试阶段发现出现的错误基本为小错误,如参数错误,调用错误,返回值错误等。一个程序最可怕的是无报错错误,在程序不报错的情况下运行结果和实验结果不同,经过调试后最终和实验结果相同。