数据结构报告.docx
《数据结构报告.docx》由会员分享,可在线阅读,更多相关《数据结构报告.docx(41页珍藏版)》请在冰豆网上搜索。
![数据结构报告.docx](https://file1.bdocx.com/fileroot1/2023-1/24/7e2c8a17-69bb-48b9-9207-d7948a3ca65e/7e2c8a17-69bb-48b9-9207-d7948a3ca65e1.gif)
数据结构报告
数据结构
课
程
设
计
报
告
学院:
计算机科学与技术学院
专业:
计算机应用技术
班级:
2班
姓名:
文雨婷
学号:
120171021334
指导教师:
秦明
完成日期:
6月30日
实验一顺序表与单链表的基本运算
实验一分录
1.1实验名称
顺序表的基本运算
1.2实验内容
(1)已知长度为n的线性表A采用顺序存储结构,请写一时间复杂度为0(n)、空间复杂度为0
(1)的算法,该算法删除线性表中所有值为item的数据元素。
要求:
线性表元素个数n很大,而值为item的数据元素个数很少,要求移动元素个数尽量少;删除后的数组元素与原数组元素不必保持顺序一致。
(2)编写一个函数将一个顺序表A(有n个元素,且任何元素均不为0)分拆成两个顺序表,使A中大于0的元素存放在B中,小于0的元素存放在C中。
(3)假设一个算术表达式中包含圆括号,方括号和花号三种类型的括号,编写一个判别表达式中括号是否正确配对的函数correct(exp,tag);其中:
exp为字符串类型量,表示被判别的表达式,tag为布尔型的变量。
(4)编写向顺序分配的循环队列QU[0,m-1]中插入一个结点的函数enqueue和从该队列中取出一个节点的dequeue函数。
(5)编写一个主函数,调试上述算法。
1.3实验代码
#include
#include
#defineMAXSIZE100
typedefintElemType;
typedefstructlist
{
ElemTypeelem[MAXSIZE];
intlength;
}Sqlist;
typedefstructNode
{
ElemTypedate;
structNode*next;
}DNode;
typedefstructDulNode
{
ElemTypedate;
structDulNode*prev,*next;
intfreq;
}DLinkList;//定义双向链表
voidCreatlist(Sqlist&L)
{
inti;
printf("请输入顺序表的长度:
");
scanf("%d",&L.length);
for(i=0;iscanf("%d",&L.elem[i]);
}
voidCreateSame(Sqlist&L1,Sqlist&L2)
{
intcounter=0;
SqlistL3;
Creatlist(L1);
Creatlist(L2);
for(inti=0;ifor(intj=0;j{
if(L1.elem[i]==L2.elem[j])
{
L3.elem[counter]=L1.elem[i];
counter++;
}
}
printf("删除相同元素后的链表元素:
");
for(i=0;iprintf("%d",L3.elem[i]);
printf("\n");
}
voidChooseking(DNode*head)
{
intm,num;
printf("请输入猴子的总数:
");
scanf("%d",&num);
printf("出局的猴子所报的号码是:
");
scanf("%d",&m);
DNode*s,*q,*t;
inti,counter=0;
if(m==1)
printf("最后一只猴子是%d号。
\n",num);
else
{
for(i=0;i{
s=(DNode*)malloc(sizeof(DNode));
s->date=i+1;
s->next=NULL;
if(i==0)
{
head=s;
q=head;
}
else
{
q->next=s;
q=q->next;
}
}
q->next=head;
q=head;
while(q->next!
=q)
{
counter++;
if(counter==m-1)
{
t=q->next;
q->next=t->next;
counter=0;
free(t);
}
q=q->next;
}
printf("最后一只猴子是%d号。
\n",q->date);
}
}
DLinkList*Created()
{
intnum=0;
DLinkList*head;
DLinkList*p1,*p2;
p1=p2=(DLinkList*)malloc(sizeof(DLinkList));
scanf("%d",&p1->date);
head=NULL;
while(p1->date!
=0)
{
num++;
if(num==1)
head=p1;
else
{
p2->next=p1;
p1->prev=p2;
}
p2=p1;
p1=(DLinkList*)malloc(sizeof(DLinkList));
scanf("%d",&p1->date);
}
p2->next=NULL;
return(head);
}
voidprinted(DLinkList*head)
{
DLinkList*p=head;
while(p!
=NULL)
{
printf("%d",p->date);
p=p->next;
}
printf("\n");
}
DLinkList*Locate(DLinkList*L,intx)
{
DLinkList*p=L->next;
DLinkList*q;
while(p&&(p->date!
=x))
p=p->next;
if(!
p)returnNULL;
else
{
p->freq++;
q=p->prev;
while((q!
=L)&&(q->freq)<(p->freq))
q=q->prev;
if(q!
=p->prev)
{
p->prev->next=p->next;
if(p->next)
p->next->prev=p->prev;
p->prev=q;
p->next=q->next;
q->next=p;
p->next->prev=p;
}
returnp;
}
}
voidLocateLine()
{
DLinkList*p,*head;
inti;
head=(DLinkList*)malloc(sizeof(DLinkList));
head->date=0;
printf("输入链表各个结点的值(数字0代表结束):
\n");
p=Created();
head->next=p;
p->prev=head;
printed(head);
intnum;
printf("输入要访问的元素(数字0代表访问结束):
\n");
for(;i!
=0;)
{
scanf("%d",&num);
i=num;
p=Locate(head,num);
}
printf("根据访问频度重新排序后的链表变为:
\n");
printed(head->next);
}
voidmain()
{
intn;
Sqlisthead1,head2;
DNode*head3;
printf("************************************************************\n");
printf("0.退出程序。
\n");
printf("1.删除两个链表中的不同元素。
\n");
printf("2.猴子选大王的问题.\n");
printf("3.带有表头结点的非循环双向链表问题。
\n");
printf("************************************************************\n");
while(n!
=0)
{
printf("请选择:
");
scanf("%d",&n);
switch(n)
{
case0:
printf("退出系统!
\n");
exit(0);break;
case1:
CreateSame(head1,head2);break;
case2:
Chooseking(head3);break;
case3:
LocateLine();break;
}
}
}
1.4运行结果
程序执行后出现下图样式的菜单:
新建顺序表:
删除顺序表中所要求的元素:
拆分顺序表:
判别括号是否配对:
正确的匹配:
建立一个循环队列:
向循环队列中插入元素:
从循环队列中删除元素:
退出操作:
实验一分录
2.1实验名称
单链表的基本运算
2.2实验内容
(1)假设有两个按元素值递增次序排列的线性表A和B,均以单链表形式存储,里面的大部分元素对应相等,请删除一些元素(A中有而B中没有,或B中有而A中没有),使得两个有序表中保留下来的元素对应相等。
比如,A中元素为(1,3,5,8,10,13,18),B中元素为(1,3,6,8,9,10,13,15),则删除元素后A、B里的元素为(1,3,8,10,13)。
(2)猴子选大王。
n只猴子围成一圈,从1到m报数,报m的猴子出局。
余下的猴子从第m+1只开始继续从1到m报数,报m的猴子出局。
第n只猴子报数后,第1只猴子接着报数(因为围成了圈)。
待整个圈只剩下一只猴子时,该猴子即为大王。
n和m由用户输入,请输出当选大王的猴子的编号。
(3)设有一头指针为L的带有表头结点的非循环双向链表,其每个结点中除有prev(前驱指针),data(数据)和next(后继指针)域外,还有一个访问频度域freq。
在链表被起用前,其值均初始化为零。
每当在链表中进行一次Locate(L,x)运算时,令元素值为x的结点中freq域的值增1,并使此链表中结点保持按访问频度非增(递减)的顺序排列,同时最近访问的结点排在频度相同的结点的最后,以便使频繁访问的结点总是靠近表头。
试编写符合上述要求的Locate(L,x)运算的算法,该运算为函数过程,返回找到结点的地址,类型为指针型。
(4)在主函数中设计一个简单的菜单,分别调试上述算法。
2.3实验代码
#include
#include
#defineMAXSIZE100
typedefintElemType;
typedefstructlist
{
ElemTypeelem[MAXSIZE];
intlength;
}Sqlist;
typedefstructNode
{
ElemTypedate;
structNode*next;
}DNode;
typedefstructDulNode
{
ElemTypedate;
structDulNode*prev,*next;
intfreq;
}DLinkList;//定义双向链表
voidCreatlist(Sqlist&L)
{
inti;
printf("请输入顺序表的长度:
");
scanf("%d",&L.length);
for(i=0;iscanf("%d",&L.elem[i]);
}
voidCreateSame(Sqlist&L1,Sqlist&L2)
{
intcounter=0;
SqlistL3;
Creatlist(L1);
Creatlist(L2);
for(inti=0;ifor(intj=0;j{
if(L1.elem[i]==L2.elem[j])
{
L3.elem[counter]=L1.elem[i];
counter++;
}
}
printf("删除相同元素后的链表元素:
");
for(i=0;iprintf("%d",L3.elem[i]);
printf("\n");
}
voidChooseking(DNode*head)
{
intm,num;
printf("请输入猴子的总数:
");
scanf("%d",&num);
printf("出局的猴子所报的号码是:
");
scanf("%d",&m);
DNode*s,*q,*t;
inti,counter=0;
if(m==1)
printf("最后一只猴子是%d号。
\n",num);
else
{
for(i=0;i{
s=(DNode*)malloc(sizeof(DNode));
s->date=i+1;
s->next=NULL;
if(i==0)
{
head=s;
q=head;
}
else
{
q->next=s;
q=q->next;
}
}
q->next=head;
q=head;
while(q->next!
=q)
{
counter++;
if(counter==m-1)
{
t=q->next;
q->next=t->next;
counter=0;
free(t);
}
q=q->next;
}
printf("最后一只猴子是%d号。
\n",q->date);
}
}
DLinkList*Created()
{
intnum=0;
DLinkList*head;
DLinkList*p1,*p2;
p1=p2=(DLinkList*)malloc(sizeof(DLinkList));
scanf("%d",&p1->date);
head=NULL;
while(p1->date!
=0)
{
num++;
if(num==1)
head=p1;
else
{
p2->next=p1;
p1->prev=p2;
}
p2=p1;
p1=(DLinkList*)malloc(sizeof(DLinkList));
scanf("%d",&p1->date);
}
p2->next=NULL;
return(head);
}
voidprinted(DLinkList*head)
{
DLinkList*p=head;
while(p!
=NULL)
{
printf("%d",p->date);
p=p->next;
}
printf("\n");
}
DLinkList*Locate(DLinkList*L,intx)
{
DLinkList*p=L->next;
DLinkList*q;
while(p&&(p->date!
=x))
p=p->next;
if(!
p)returnNULL;
else
{
p->freq++;
q=p->prev;
while((q!
=L)&&(q->freq)<(p->freq))
q=q->prev;
if(q!
=p->prev)
{
p->prev->next=p->next;
if(p->next)
p->next->prev=p->prev;
p->prev=q;
p->next=q->next;
q->next=p;
p->next->prev=p;
}
returnp;
}
}
voidLocateLine()
{
DLinkList*p,*head;
inti;
head=(DLinkList*)malloc(sizeof(DLinkList));
head->date=0;
printf("输入链表各个结点的值(数字0代表结束):
\n");
p=Created();
head->next=p;
p->prev=head;
printed(head);
intnum;
printf("输入要访问的元素(数字0代表访问结束):
\n");
for(;i!
=0;)
{
scanf("%d",&num);
i=num;
p=Locate(head,num);
}
printf("根据访问频度重新排序后的链表变为:
\n");
printed(head->next);
}
voidmain()
{
intn;
Sqlisthead1,head2;
DNode*head3;
printf
("************************************************************\n");
printf("0.退出程序。
\n");
printf("1.删除两个链表中的不同元素。
\n");
printf("2.猴子选大王的问题.\n");
printf("3.带有表头结点的非循环双向链表问题。
\n");
printf
("************************************************************\n");
while(n!
=0)
{
printf("请选择:
");
scanf("%d",&n);
switch(n)
{
case0:
printf("退出系统!
\n");
exit(0);break;
case1:
CreateSame(head1,head2);break;
case2:
Chooseking(head3);break;
case3:
LocateLine();break;
}
}
}
2.4运行结果
程序执行后出现下图样式的菜单:
删除两个链表中的不同元素:
猴子选大王问题:
当所报号码为1时:
非循环双向链表的访问频度排序:
退出操作:
实验二栈与队列的基本运算
一、实验内容:
(1)任意输入一个字符串,按反序输出。
要求字符串从键盘随机输入,字符长度不做具体限制。
实现时,以链栈为手段。
(1)设计一个算法,判定一个字符串是否是对称字符串。
若是,则返回1,否则返回0。
(2)括号配对检查。
试设计一个程序对任意输入的语句或数学表达式,判断其符号是否匹配。
若匹配,则返回1;否则返回0。
(3)编写递归和非递归程序,计算下列表达式的值
1n=0
2xn=1
n>1
(5)舞伴问题。
假设在周末舞会上,男士和女士各自组成一排,跳舞开始的时候,依次从男队和女队上各出一人配成舞伴。
若两队初始人数不相同,则较长的那一队中未匹配对者等待下一轮舞曲。
现要求写一篇算法模拟上述舞伴配对的问题。
二、程序代码:
1
#include
#include
typedefcharElemType;
typedefstructsnode{
ElemTypedata;
structsnode*next;
}LinkSTACK;
voidInitStack(LinkSTACK**top)
{*top=(LinkSTACK*)malloc(sizeof(LinkSTACK));
(*top)->next=NULL;
}
intpush(LinkSTACK**top,ElemTypex)
{LinkSTACK*s;
s=(LinkSTACK*)malloc(sizeof(LinkSTACK));
s->data=x;
s->next=(*top)->next;
(*top)->next=s;
return1;
}
intEmpty(LinkSTACK**top)
{
return((*top)->next==NULL?
1:
0);}
intPop(LinkSTACK**top,ElemType*x)
{
LinkSTACK*s;
if(Empty(top)){
printf("Stackisfree!
\n");
return0;
}
s=(*top)->next;
*x=s->data;
(*top)->next=s->next;
return1;
}
voidmain()
{charch;
LinkSTACK*top;
InitStack(&top);
printf("请输入一字串");
while((ch=getchar())!
='\n')push(&top,ch);
printf("\n");
while(!
Empty(&top)){
Pop(&top,&ch);
printf("%c",ch);
}
}
2
#include
#include
#defineMAXSIZE40
typedefcharElemType;
typedefstruct{
ElemTypedata[MAXSIZE];
inttop;
}STACK;
voidInitStack(STACK*S)
{S->top=-1;}
intPush(STACK*S,ElemTypex)
{if(S->top==MAXSIZE-1){
printf("St