数据结构实验线性表基本操作.docx
《数据结构实验线性表基本操作.docx》由会员分享,可在线阅读,更多相关《数据结构实验线性表基本操作.docx(33页珍藏版)》请在冰豆网上搜索。
数据结构实验线性表基本操作
学
《数据结构》课程
实验报告
实验名称:
线性表基本操作的实现
实验室(中心):
学生信息:
专业班级:
指导教师:
实验完成时间:
2016
实验一线性表基本操作的实现
一、实验目的
1.熟悉C语言的上机环境,进一步掌握C语言的结构特点。
2.掌握线性表的顺序存储结构的定义及C语言实现。
3.掌握线性表的链式存储结构——单链表的定义及C语言实现。
4.掌握线性表在顺序存储结构即顺序表中的各种基本操作。
5.掌握线性表在链式存储结构——单链表中的各种基本操作。
二、实验内容及要求
1.顺序线性表的建立、插入、删除及合并。
2.链式线性表的建立、插入、删除及连接。
三、实验设备及软件
计算机、MicrosoftVisualC++6.0软件
四、设计方案(算法设计)
㈠采用的数据结构
本程序顺序表的数据逻辑结构为线性结构,存储结构为顺序存储;链表的数据逻辑结构依然为线性结构,存储结构为链式结构。
㈡设计的主要思路
1.建立含n个数据元素的顺序表并输出该表中各元素的值及顺序表的长度,顺序表的长度和元素由用户输入;
2.利用前面建立的顺序表,对顺序表进行插入、删除及合并操作;
3.建立一个带头结点的单链表,结点的值域为整型数据,链表的元素由用户输入;
4.对前面建立的链表进行插入、删除及连个链表的连接操作;
㈢算法描述
1、顺序表
voidInit(sqlist&);//初始化顺序表
BOOLInse(sqlist&,int,char);//在线性表中插入元素
BOOLdel(sqlist&,int,char&);//在线性表中删除元素
intLoc(sqlist,char);//在线性表中定位元素
voidprint(sqlist);//输出顺序表
voidcombine(sqlist&,sqlist&,sqlist&);//两个线性表的合并
2、链表
voidCreaL(LinkList&,int);//生成一个单链表
BOOLLInsert(LinkList&,int,char);//在单链表中插入一个元素
BOOLLDele(LinkList&,int,char&);//在单链表中删除一个元素
BOOLLFind_key(LinkList,char,int&);//按关键字查找一个元素
BOOLLFind_order(LinkList,char&,int);//按序号查找一个元素
voidLPrint(LinkList);//显示单链表所有元素
voidLUnion(LinkList&,LinkList&,LinkList&,int);//两个链表的连接
五、程序代码
1、顺序表
#include
#include
#defineMax116
enumBOOL{False,True};
typedefstruct
{
charelem[Max];//线性表
intlast;//last指示当前线性表的长度
}sqlist;
voidInit(sqlist&);
BOOLInse(sqlist&,int,char);//在线性表中插入元素
BOOLdel(sqlist&,int,char&);//在线性表中删除元素
intLoc(sqlist,char);//在线性表中定位元素
voidprint(sqlist);
voidcombine(sqlist&,sqlist&,sqlist&);
voidmain()
{
sqlistL1;
sqlistL2;
sqlistL3;
intloc,S=1;
charj,ch;
BOOLtemp;
printf("本程序用来实现顺序结构的线性表。
\n");
printf("可以实现查找、插入、删除、两个线性表的合并等操作。
\n");
Init(L1);
while(S)
{
printf("\n请选择:
\n");
printf("1.显示所有元素\n");
printf("2.插入一个元素\n");
printf("3.删除一个元素\n");
printf("4.查找一个元素\n");
printf("5.线性表的合并\n");
printf("6.退出程序\n\n");
scanf("%c",&j);
switch(j)
{
case'1':
print(L1);break;
case'2':
{printf("请输入要插入的元素(一个字符)和插入位置:
\n");
printf("格式:
字符,位置;例如:
a,2\n");
scanf("%c,%d",&ch,&loc);
temp=Inse(L1,loc,ch);
if(temp==False)printf("插入失败!
\n");
else{printf("插入成功!
\n");
print(L1);
}
break;
}
case'3':
{printf("请输入要删除元素的位置:
");
scanf("%d",&loc);
temp=del(L1,loc,ch);
if(temp==True)printf("删除了一个元素:
%c\n",ch);
elseprintf("该元素不存在!
\n");
printf("删除该元素后的线性表为:
");
print(L1);
break;
}
case'4':
{printf("请输入要查找的元素:
");
scanf("%c",&ch);
loc=Loc(L1,ch);
if(loc!
=-1)printf("该元素所在位置:
%d\n",loc+1);
elseprintf("%c不存在!
\n",ch);
break;
}
case'5':
{printf("请输入要进行合并的第二个线性表:
");
Init(L2);
combine(L1,L2,L3);
printf("合并前的两个线性表如下:
\n");
print(L1);
print(L2);
printf("输出合并后的线性表如下:
\n");
print(L3);
break;
}
default:
S=0;printf("程序结束,按任意键退出!
\n");
}
}
getch();
}
voidInit(sqlist&v)//初始化线性表
{
inti;
printf("请输入初始线性表长度:
n=");
scanf("%d",&v.last);
printf("请输入从1到%d的各元素(字符),例如:
abcdefg\n",v.last);
getchar();
for(i=0;iscanf("%c",&v.elem[i]);
}
BOOLInse(sqlist&v,intloc,charch)//插入一个元素,成功返回True,失败返回False
{
inti;
if((loc<1)||(loc>v.last+1))
{
printf("插入位置不合理!
\n");
returnFalse;
}
elseif(v.last>=Max)
{printf("线性表已满!
\n");
returnFalse;
}
else{
for(i=v.last-1;i>=loc-1;i--)
v.elem[i+1]=v.elem[i];
v.elem[loc-1]=ch;
v.last++;
returnTrue;
}
}
BOOLdel(sqlist&v,intloc,char&ch)//删除一个元素,成功返回True,并用ch返回该元素值,失败返回False
{
intj;
if(loc<1||loc>v.last)
returnFalse;
else{
ch=v.elem[loc-1];
for(j=loc-1;jv.elem[j]=v.elem[j+1];
v.last--;
returnTrue;
}
}
intLoc(sqlistv,charch)//在线性表中查找ch的位置,成功返回其位置,失败返回-1
{
inti=0;
while(i=ch)i++;
if(v.elem[i]==ch)
returni;
elsereturn(-1);
}
voidprint(sqlistv)//显示当前线性表所有元素
{
inti;
for(i=0;iprintf("%c",v.elem[i]);
printf("\n");
}
voidcombine(sqlist&s1,sqlist&s2,sqlist&s3)//顺序表的连接
{
inti=0;
intj=0;
intk=0;
while(i{
if(s1.elem[i]<=s2.elem[j])
{
s3.elem[k]=s1.elem[i];
i++;
}
else
{
s3.elem[k]=s2.elem[j];
j++;
}
k++;
}
if(i==s1.last)
{
while(j{
s3.elem[k]=s2.elem[j];
k++;
j++;
}
}
if(j==s2.last)
{
while(i{
s3.elem[k]=s1.elem[i];
k++;
}
}
s3.last=k;
}
2、链表的操作
#include
#include
#include
#defineLENsizeof(LNode)
enumBOOL{False,True};
typedefstructnode
{
chardata;
structnode*next;
}LNode,*LinkList;
voidCreaL(LinkList&,int);//生成一个单链表
BOOLLInsert(LinkList&,int,char);//在单链表中插入一个元素
BOOLLDele(LinkList&,int,char&);//在单链表中删除一个元素
BOOLLFind_key(LinkList,char,int&);//按关键字查找一个元素
BOOLLFind_order(LinkList,char&,int);//按序号查找一个元素
voidLPrint(LinkList);//显示单链表所有元素
voidLUnion(LinkList&,LinkList&,LinkList&,int);//两个链表的连接
voidmain()
{
LinkListL;
LinkListT;
LinkListH;
BOOLtemp;
intnum,num1,loc,flag=1;
charj,ch;
printf("本程序实现链式结构的线性表的操作。
\n");
printf("可以进行插入,删除,定位,查找等操作。
\n");
printf("请输入初始时链表长度:
");
scanf("%d",&num);
CreaL(L,num);
LPrint(L);
while(flag)
{
printf("请选择:
\n");
printf("1.显示所有元素\n");
printf("2.插入一个元素\n");
printf("3.删除一个元素\n");
printf("4.按关键字查找元素\n");
printf("5.按序号查找元素\n");
printf("6.链表的连接\n");
printf("7.退出程序\n");
scanf("%c",&j);
switch(j)
{
case'1':
LPrint(L);break;
case'2':
{printf("请输入元素(一个字符)和要插入的位置:
\n");
printf("格式:
字符,位置;例如:
a,3\n");
scanf("%c,%d",&ch,&loc);
temp=LInsert(L,loc,ch);
if(temp==False)printf("插入失败!
\n");
elseprintf("插入成功!
\n");
LPrint(L);
break;
}
case'3':
printf("请输入要删除的元素所在位置:
");
scanf("%d",&loc);
temp=LDele(L,loc,ch);
if(temp==False)printf("删除失败!
\n");
elseprintf("成功删除了一个元素:
%c\n",ch);
LPrint(L);
break;
case'4':
if(L->next==NULL)
printf("链表为空!
\n");
else
{
printf("请输入要查找的元素(一个字符):
");
scanf("%c",&ch);
temp=LFind_key(L,ch,loc);
if(temp==False)printf("没有找到该元素!
\n");
elseprintf("该元素在链表的第%d个位置。
\n",loc);
}
break;
case'5':
if(L->next==NULL)
printf("链表为空!
\n");
else
{
printf("请输入要查找的位置:
");
scanf("%d",&loc);
temp=LFind_order(L,ch,loc);
if(temp==False)printf("该位置不存在!
\n");
elseprintf("第%d个元素是:
%c\n",loc,ch);
}
break;
case'6':
if(L->next==NULL)
printf("链表为空!
\n");
else
{
printf("请输入第二个链表的长度:
");
scanf("%d",&num1);
CreaL(T,num1);
}
if(T->next==NULL)
printf("第二个链表为空!
\n");
LUnion(L,T,H,num+num1);
printf("输出连接后链表中的所有元素:
");
printf("\n");
LPrint(H);
break;
default:
flag=0;printf("程序结束,按任意键退出!
\n");
}
}
getch();
}
voidCreaL(LinkList&v,intn)//生成一个带头结点的有n个元素的单链表
{
inti;
LinkListp;
v=(LinkList)malloc(LEN);
v->next=NULL;
printf("请输入%d个字符:
例如:
abcdefg\n",n);
getchar();
for(i=n;i>0;--i)
{p=(LinkList)malloc(LEN);
scanf("%c",&p->data);
p->next=v->next;
v->next=p;
}
}
BOOLLInsert(LinkList&v,inti,chare)//在单链表的第i各位置插入元素e,成功返回True,失败返回False
{
LinkListp,s;
intj=0;
p=v;
while(p&&jnext;++j;}
if(!
p||j>i-1)returnFalse;
s=(LinkList)malloc(LEN);
s->data=e;
s->next=p->next;
p->next=s;
returnTrue;
}
BOOLLDele(LinkList&v,inti,char&e)//在单链表中删除第i个元素,成功删除返回True,并用e返回该元素值,失败返回False
{
LinkListp,q;
intj=0;
p=v;
while(p->next&&j{p=p->next;++j;}
if(!
(p->next)||j>i-1)returnFalse;
q=p->next;p->next=q->next;
e=q->data;
free(q);
returnTrue;
}
BOOLLFind_key(LinkListv,chare,int&i)//在单链表中查找关键字为e的元素,成功返回True,并用i返回该元素位置,失败返回False
{
i=1;
LinkListp;
p=v->next;
while((p->data!
=e)&&(p->next!
=NULL))
{p=p->next;i++;}
if(p->data!
=e)
returnFalse;
elsereturnTrue;
}
BOOLLFind_order(LinkListv,char&e,inti)//在单链表中查找第i个元素,成功返回True,并用e返回该元素值,失败返回False
{
LinkListp;
intj=0;
p=v;
while(p->next&&j
{p=p->next;++j;}
if(j!
=i)returnFalse;
else{
e=p->data;
returnTrue;
}
}
voidLPrint(LinkListv)//显示链表所有元素
{
LinkListq;
q=v->next;
printf("链表所有元素:
");
while(q!
=NULL)
{printf("%c",q->data);q=q->next;}
printf("\n");
}
voidLUnion(LinkList&u,LinkList&v,LinkList&w,intn)
{
inti;
LinkListp;
w=(LinkList)malloc(LEN);//生成头结点
w->next=NULL;
for(i=n;i>0;--i)
{p=(LinkList)malloc(LEN);//生成新结点
if(u!
=NULL)
{
p->data=u->data;
u=u->next;
}
else
{
p->data=v->data;
v=v->next;
}
p->next=w->next;
w->next=p;
}
}
六、测试结果及说明
顺序表和链表基本操作的实现程序编译结果没错误和提醒,运行测试结果正确,没有出现错误;
1、顺序表
2、链表
七、实验体会
1.由于C语言的数组类型也有随机存取的特点,一维数组的机内表示就是顺序结构。
因此,可用C语言的一维数组实现线性表的顺序存储。
2.注意如何取到第i个元素,在插入过程中注意溢出情况以及数组的下标与位序(顺序表中元素的次序)的区别。
3.单链表的结点结构除数据域外,还含有一个指针域。
线性表提升实验
(一)、实现顺序表元素的就地逆置
一、设计方案
㈠采用的数据结构
本程序采用的数据逻辑结构为线性结构,存储结构为顺序结构,算法的总体功能是实现顺序表中元素的逆置。
㈡设计的主要思路
由用户确定初始顺序表的长度并输入初始顺序表的元素,然后通过交换元素的方法将初始表中的元素进行逆置处理、输出元素。
㈢算法描述
statusInitlist_Sq(Sqlist*L)//对顺序表A进行初始化
voidinput(Sqlist*A)//对一个线性表输入数据,是先输入长度,然后再输入数据
voidprint(Sqlist*A)//对一个线性表进行输出
voidinvert(Sqlist*A)//实现一个顺序表的逆置
二、主要代码
#include
#include
#include
#defineSIZE100
#defineListInc10
#defineOK1
typedefstruct
{
int*elem;
intlength;
intlistsize;
}Sqlist;
typedefintstatus;
statusInitlist_Sq(Sqlist*L)
{
L->elem=(int*)malloc(SIZE*sizeof(status));
if(!
L->elem)printf("voerflow");
elseL->length=0;
L->listsize=SIZE;
returnOK;
}
//对一个线性表输入数据,是先输入长度,然后再输入数据
voidinput(Sqlist*A)
{
inti=0;
printf("本程序用于实现顺序表的逆置。
\n");
printf("\n请输入长度:
\n");
scanf("%d",&A->length);
printf("请输入数:
\n");
for(i=0;ilength;i++)
{
scanf("%d",&A->elem[i]);
}
}
//对一个线性表进行输出
voidprint(Sqlist*A)
{
inti;
for(i=0;ilength;i++)
printf("%d\t",A->elem[i]);
printf("\n\n");
}
voidinvert(Sqlist*A)
{
intn=A->length