顺序表的基本操作
一、实验目的:
1、复习C语言程序设计中的知识。
2、掌握线性表的顺序存储结构的表示和实现方法。
3、掌握顺序表基本操作的算法实现。
二、实验内容:
1.建立顺序表。
2.在顺序表上实现插入、删除和查找等操作。
三、实验要求:
1、编写实现顺序表的基本算法(初始化、查找、插入、删除等)的函数,并在此基础上设计一个主程序完成如下功能:
⑴初始化一个顺序表L,数据元素类型可任选;
⑵建立顺序表L,要求数据元素至少10个;
⑶输出顺序表L的长度;
⑷按位置查找:输出顺序表L的第i个元素,如第3个元素;
⑸按内容查找:输出给定元素的位置;
⑹在第i个元素前插入给定元素;
⑺删除顺序表L的第i个元素;
⑻遍历顺序表,将表中的元素按序输出。
⑼编写菜单,以便用户可以选择相应的操作。
2. 利用顺序表的基本操作,求两个集合A和B的交集、交集以及差集。
四、实验步骤(给出每个函数的算法描述):
顺序表的存储结构
typedef struct
{
ElemType elem[maxsize]; /* 线性表占用的数组空间*/
int last; /*记录线性表中最后一个元素在数组elem[ ]中的位置(下标值),空表置为-1*/
} SeqList;
实现顺序表所需的函数共涉及10个函数:
main() : 主函数
menu() : 菜单函数
Init_SeqList() : 初始化函数
SeqList_Length () :求顺序表长度函数
Indata_SeqList() :建立顺序表函数
GetData_SeqList() :顺序表的位置查找函数
Locate_SeqList() :顺序表的内容查找函数
Insert_SeqList() :顺序表的的插入函数
Delete_SeqList() :顺序表的的删除函数
Print_SeqList() : 顺序表的的遍历函数
顺序表函数的算法描述
(1)函数名:main()
输入:输入你选择的菜单编码,最后输入两个getchar()用于清除缓存区
输出:主函数调用菜单函数后输入菜单编码,调用相应的功能函数,每调完一个后按任意键就又返回主菜单,继续调用其他函数,当输出编码错误是输出“输入1~8之间的数字”,当所有功能完成后输出“程序结束”
算法描述:在while循环语句中,首先调用menu()函数,再用switch ()语句通过menu()函数中相应编码执行后面功能函数的调用,每执行一个功能函数后就跳出switch ()语句,继续输入其他的编码执行其他相应函数,一直到实现完所有的功能函数,最后如果输入编码错误是输出“输入1~8之间的数字”,另外,在switch ()语句中还要执行将1赋值给quit,如果当quit=1是就结束while循环语句,最后每调完一个功能函数后就输出“按任意键返回主菜单!”以及当所有功能完成后输出“程序结束”
(2)函数名:menu()
输入:无
输出:首先输出每个编码所代表的功能函数的作用,再输出“输入需要访问的编号”
算法描述:把编码与功能函数一一对应
(3)函数名:Init_SeqList()
输入:无
输出:成功初始化就输出“初始化成功”
算法描述:首先定义一个顺序表,之后在堆区分配一块指定大小的内存空间来存放顺序表L,如果申请分配内存空间成功,就让顺序表为空表,并且输出“初始化成功”,最后返回顺序表的首地址
(4)函数名:SeqList_Length ()
输入:无
输出:输出顺序表的长度
算法描述:首先定义一个顺序表,最后输出该顺序表的长度,该顺序表的长度就是顺序表的指针变量指向顺序表中最后一个元素的位置再加1
(5)函数名:Indata_SeqList()
输入:输入你所建立顺序表的元素
输出:首先输出输入的提示语句,建表完成后输出“顺序表建立成功”
算法描述:首先定义一个指针变量L的顺序表和顺序表元素的类型,再输入顺序表的元素,之后用while循环语句,在循环体中,先让顺序表位置从0开始,然后让指针变量从0依次访问顺序表的数组,再将输入的元素依次赋值给数组,当输入“#”时跳出while循环语句,建表完成后输出“顺序表建立成功”,最后返回顺序表
(6)函数名:GetData_SeqList()
输入:输入取出元素的位置
输出:首先输出输入取出元素的位置的提示语句,如果输入的数字不在顺序表范围之内就输出“插入位置错误”,最后输出取出的元素
算法描述:首先定义一个顺序表和一个整型变量,输入取出元素的位置,如果输入的数字不在顺序表范围之内就输出“插入位置错误”,如果输入的数字在顺序表范围之内就输出取出的元素,取出的元素就是指针变量指向数组中取出元素的位置量-1
时的元素
(7)函数名:Locate_SeqList()
输入:输入查找的元素
输出:首先输出输入查找元素的提示语句,最后输出元素在顺序表中的位置
算法描述:首先定义一个顺序表和元素的类型,再输入查找元素,之后用for循环将顺序表中所以的元素都扫描一遍,如果发现顺序表中有和输入元素相同的元素,就输出该元素在顺序表中的位置,如果没有在顺序表中发现有和输入元素相同的元素,就输出“查找失败”
(8)函数名:Insert_SeqList()
输入:输入插入位置和元素
输出:首先输出输入插入位置和元素的提示语句,当顺序表已满时输出“表已满无法插入”,当插入的数字不在顺序表范围之内就输出“插入位置i值不合法”,当成功插入就输出“插入成功”
算法描述:首先定义一个顺序表,一个整型变量以及元素的类型,再输入插入位置和元素,当顺序表已满时输出“表已满无法插入”并返回0,当插入的数字不在在顺序表范围之内就输出“插入位置i值不合法”并返回-1,再用for循环语句,循环的范围从顺序表的最后到插入位置-1,循环体中让顺序表中最后一个元素在数组的位置往后移一位,再把插入的元素放在插入的位置上,最后将顺序表的长度加1,最后当成功插入就输出“插入成功”并返回1
(9)函数名:Delete_SeqList()
输入:输入删除元素的位置
输出:首先输出输入删除元素的位置的提示语句,如果顺序表中最后一个元素在数组的位置指向0就输出“这是一个空表!”,当输入删除元素的位置的数字不在顺序表范围之内就输出“删除位置不合法!”,最后当成功删除就输出“删除成功”
算法描述:首先定义一个顺序表和一个整型变量,输入删除元素的位置,如果顺序表中最后一个元素在数组的位置指向0就输出“这是一个空表!”,当输入删除元素的位置的数字不在顺序表范围之内就输出“删除位置不合法!”再用for循环语句,循环的范围从顺序表删除元素位置后一个位置到最后位置,循环体中让删除后面的元素依次往前移一位,最后将顺序表的长度减1,最后当成功删除就输出“删除成功”
(10)函数名:Print_SeqList()
输入:无
输出:输出顺序表
算法描述:首先定义一个顺序表,再通过for循环依次输出顺序表中元素位置以及元素本身,每输出五个换行
实现两个集合的并交差集所需的函数共涉及11个函数
main() : 主函数
Init_SeqList() : 初始化函数
SeqList_Length () :求顺序表长度函数
Indata_SeqList() :建立顺序表函数
GetData_SeqList() :顺序表的位置查找函数
Locate_SeqList() :顺序表的内容查找函数
Insert_SeqList() :顺序表的的插入函数
Print_SeqList() : 顺序表的的遍历函数
Union_SeqList() :求两个集合的并集函数
Inter_SeqList() :求两个集合的交集函数
Differ_SeqList() :求两个集合的差集函数
两个集合的并交差集的算法描述
(1)函数名:main()
输入:输入集合A和集合B的元素
输出:输出输入集合A和集合B的元素以及输出A,B的并,交,差集的提示语句
算法描述:首先定义三个顺序表以及元素的类型,调用初始化函数初始化顺序表A、B、C,之后调用建立顺序表函数建立顺序表A、B,再调用求两个集合的并集函数、求两个集合的交集函数、求两个集合的差集函数,最后调用顺序表的的遍历函数输出两个集合的并交差集
(2)函数名:Union_SeqList()
输入:无
输出:无
算法描述:首先定义三个顺序表,令顺序表C为空表,运用for循环将A中的所有元素扫描一遍,在循环体中调用插入函数,将顺序表A中的所有元素插入到顺序表C中,现在顺序表C的长度就是顺序表A的长度,再运用for循环将B中的所有元素扫描一遍,在循环体中调用按内容查找函数,如果顺序表B中的某些元素在顺序表A中没有找到,就再调用插入函数,将这次元素也插入到顺序表C中
(3)函数名:Inter_SeqList()
输入:无
输出:无
算法描述:首先定义三个顺序表,令顺序表C为空表,运用for循环将A中的所有元素扫描一遍,在循环体中调用按内容查找函数,如果顺序表A中的某些元素在顺序表B中也能找到,就调用插入函数,将这次元素也插入到顺序表C中
(4)函数名:Differ_SeqList()
输入:无
输出:无
算法描述:首先定义三个顺序表,令顺序表C为空表,运用for循环将A中的所有元素扫描一遍,在循环体中调用按内容查找函数,如果顺序表A中的某些元素在顺序表B中没有找到,就调用插入函数,将这次元素也插入到顺序表C中
五、实验总结:
- 在编写代码的时候,每一个语句完都需要写一个分号,但我每次写的时候经常忘记,在运行就有错误提示,修改后才能正常运行。
- 在调用函数的时候没有注意返回的类型,比如有时返回类型是char,在主函数里我有时把它错误定义成其他的类型导致运行失败,在看到提示后改正正确,运行成功。
- 在写switch语句时,将select的类型写错,导致输入数字它却无法执行后面的语句,系统也没有提示,导致我无法知道自己的错误,最后在同学的帮助下,才找到问题的所在,最终改正过来运行成功。
- 在写集合的并,交,差集的时候,开始调用调用函数的时候,经常运行错误,
调试也没能调试出来,于是我就借鉴网上的相关代码,改成自己所需要的代码,最终才运行成功。
六、源代码:
1、顺序表的源代码
#include<stdio.h>
#include<malloc.h>
#include <cstdlib>
#define maxsize 100
typedef char ElemType;
//顺序表的定义
typedef struct
{
ElemType elem[maxsize];
int last;
} SeqList;
void menu()
{
system("cls");
printf("***---1顺序表的初始化---***\n");
printf("***---2顺序表的建立---***\n");
printf("***---3顺序表的长度---***\n");
printf("***---4顺序表按位置查找---***\n");
printf("***---5顺序表按内容查找---***\n");
printf("***---6在顺序表的第i个元素前插入指定元素---***\n");
printf("***---7删除顺序表中的第i个元素---***\n");
printf("***---8顺序表的遍历---***\n");
printf("***---9退出程序---***\n");
printf("***---请输入需要访问的编号是(1~8)---***\n");
}
//顺序表的初始化
SeqList * Init_SeqList( )
{ SeqList *L;
L = (SeqList *) malloc ( sizeof( SeqList ) );
if(L!=NULL)
{L->last = -1;
printf("初始化成功\n") ;
}
return L;
}
//求顺序表的长度
int SeqList_Length (SeqList *L)
{
printf("输出顺序表的长度:%d\n", L->last+1);
return 0;
}
//顺序表的建立
SeqList * Indata_SeqList(SeqList *L)
{ ElemType x;
printf("请输入顺序表:");
scanf("%c", &x);
while(x != '#')
{ L->last += 1;
L->elem[L->last] = x;
scanf("%c", &x);
}
printf("顺序表建立成功\n");
return L;
}
//顺序表按位置查找
ElemType GetData_SeqList(SeqList *L)
{ int i;
printf("请输入取出元素的位置:");
scanf("%d",&i);
if ( i<1 || i>L->last+1 )
printf("插入位置错误\n");
else
printf("输出取出元素:%c\n",L->elem[i-1]);
return 0;
}
//顺序表按内容查找
int Locate_SeqList(SeqList *L)
{ int i;ElemType key;
printf("请输入查找的元素:");
scanf(" %c",&key);
for(i=0;i<=L->last;i++)
if(L->elem[i]==key)
{
printf("输出元素在顺序表中的位置:%d\n",i-1);
return 0;
}
printf("查找失败\n");
}
//在顺序表L中第i个数据元素之前插入一个元素e
int Insert_SeqList(SeqList *L, int i, ElemType e)
{ int j;
printf("请输入插入位置和元素:");
scanf("%d %c",&i,&e);
if(L->last>=maxsize-1)
{ printf("表已满无法插入\n");
return 0;
}
if((i<1) || (i>L->last+2))
{ printf("插入位置i值不合法\n");
return -1;
}
for(j=L->last; j>=i-1; j--)
{L->elem[j+1]=L->elem[j];
L->elem[i-1]=e;
L->last++;
printf("插入成功\n");
return 1;
}
}
//在顺序表L中删除第i个数据元素
void Delete_SeqList(SeqList *L, int i)
{ int k;
printf("请输入删除元素的位置:");
scanf("%d",&i);
if(L->last==0)
printf("这是一个空表!\n");
else if((i<1)||(i>L->last+1))
printf("删除位置不合法!\n");
else
{ for(k=i+1;k<=L->last;k++)
L->elem[k-1]=L->elem[k];
L->last--;
printf("删除成功\n");
}
}
//顺序表的遍历
void Print_SeqList(SeqList *L)
{ int i;
for (i=0; i<=L->last;i++)
{printf("a[%d]=%4c\t",i,L->elem[i]);
if ((i+1)%5 ==0)
printf("\n");
}
}
int main()
{
SeqList *L;
int quit=0;
int i;ElemType e;
int select;
while(1)
{
menu();
scanf("%d",&select);
switch (select)
{
case 1:L=Init_SeqList();break;
case 2:Indata_SeqList(L);break;
case 3:SeqList_Length(L);break;
case 4:GetData_SeqList(L);break;
case 5:Locate_SeqList(L);break;
case 6:Insert_SeqList(L,i,e);break;
case 7:Delete_SeqList(L,5);break;
case 8:Print_SeqList(L);break;
case 9:quit=1;break;
default:printf("输入1~8之间的数字\n");break;
}
if(quit==1)
{
break;
}
printf("按任意键返回主菜单!\n");
getchar();
getchar();
printf("程序结束!\n");
}
return 0;
}
2、两个集合的并交差集的源代码
#include<stdio.h>
#include<malloc.h>
#define maxsize 100
typedef char ElemType;
//顺序表的定义
typedef struct
{
ElemType elem[maxsize];
int last;
} SeqList;
SeqList * Init_SeqList( )
{ SeqList *L;
L = (SeqList *) malloc ( sizeof( SeqList ) );
if(L!=NULL)
{L->last = -1;}
return L;
}
SeqList * Indata_SeqList(SeqList *L)
{ ElemType x;
while(x != '#')
{ L->last += 1;
L->elem[L->last] = x;
scanf("%c", &x);
}
return L;
}
int SequenList_Length (SeqList *L)
{
return( L->last + 1 );
}
int Insert_SeqList(SeqList *L, int i, ElemType e)
{ int j;
if(L->last>=maxsize-1)
{ printf("表已满无法插入");
return 0;
}
if((i<1) || (i>L->last+2))
{ printf("插入位置i值不合法");
return -1;
}
for(j=L->last; j>=i-1; j--)
L->elem[j+1]=L->elem[j];
L->elem[i-1]=e;
L->last++;
return 1;
}
int Locate_SeqList(SeqList *L, ElemType key)
{ int i;
for(i=0;i<=L->last;i++)
if(L->elem[i]==key)
return (i+1);
return 0;
}
void Print_SeqList(SeqList *L)
{ int i;
for (i=0; i<=L->last;i++)
printf("%c\n",L->elem[i]);
}
void Union_SeqList(SeqList *A, SeqList *B, SeqList *C)
{ int i,len_lc;C->last=0;
for (i = 0; i <= A->last; i ++)
{
Insert_SeqList(C,C->last+1,A->elem[i]);
len_lc=SequenList_Length(A);
}
for (i = 0; i <= B->last; i ++)
if(!(Locate_SeqList(A,B->elem[i])))
Insert_SeqList(C,len_lc,B->elem[i]);
}
void inter_SeqList(SeqList *A, SeqList *B,SeqList *C)
{ int i;C->last=0;
for (i = 0; i <= A->last; i ++)
if((Locate_SeqList(B,A->elem[i])))
Insert_SeqList(C,C->last+1,A->elem[i]);
}
void Differ_SeqList(SeqList *A, SeqList *B, SeqList *C)
{ int i;C->last=0;
for (i = 0; i <= A->last; i ++)
if(!(Locate_SeqList(B,A->elem[i])))
Insert_SeqList(C,C->last+1,A->elem[i]);
}
int main()
{ SeqList *A;SeqList *B; SeqList *C;int len;ElemType x;
printf("输入集合A的元素:");
scanf("%c\n",&x);
A=Init_SeqList();
A=Indata_SeqList(A);
printf("输入集合B的元素:");
scanf("%c\n",&x);
B=Init_SeqList();
B=Indata_SeqList(B);
Indata_SeqList(B);
C=Init_SeqList();
printf("输出A,B的并集:");
Union_SeqList(A,B,C);
Print_SeqList(C);
printf("输出A,B的交集:");
inter_SeqList(A,B,C);
Print_SeqList(C);
printf("输出A,B的差集:");
Differ_SeqList(A,B,C);
Print_SeqList(C);
return 0;
}