河北工业大学数据结构实验报告.docx
《河北工业大学数据结构实验报告.docx》由会员分享,可在线阅读,更多相关《河北工业大学数据结构实验报告.docx(64页珍藏版)》请在冰豆网上搜索。
河北工业大学数据结构实验报告
河北工业大学
《数据结构》
2014版
实验报告
实验一、约瑟夫环
【源代码】
#include
#include
structLnode
{intnumber;
intpassword;
structLnode*next;
}Lnode,*p,*q;
intmain()
{intn;
inti;
intm;
intj;
printf("pleaseenterthenumberofpeoplen:
");
scanf("%d",&n);
if(n<=0||n>30)
{printf("niserorr!
\n");
printf("pleaseenterthenumberofpeopleagain:
");
scanf("%d",&n);
}
for(i=1;i<=n;i++)
{
if(i==1)
{p=q=(structLnode*)malloc(sizeof(structLnode));}
else
{
q->next=(structLnode*)malloc(sizeof(structLnode));
q=q->next;
}
printf("pleaseenterthe%dpeople'spassword:
",i);
scanf("%d",&(q->password));
q->number=i;
}
q->next=p;
printf("pleaseenterthenumberm:
");
scanf("%d",&m);
printf("Thepasswordis:
\n");
for(j=1;j<=n;j++)
{
for(i=1;i<=m-1;i++)
{q=p;p=p->next;}
m=p->password;
printf("%d",p->number);
q->next=p->next;
free(p);
p=q->next;
}
printf("\n");
}
【实验感想】
这次编写约瑟夫环程序虽然用了很长时间,但是当程序正确运行的时候,真的感觉特别开心!
我一边画图,一边分析,一边调试,在许多次的调试过程中,我注意到了好多问题,有很多细节真的是有一点不对就会满盘皆输,而且每次感觉能成功编好的情况下,把代码敲进机器却总是得不到正确的答案,感觉很郁闷,也想放弃过,但是最后还是坚持下来了。
总共用了一天的时间。
可能是因为我课本知识掌握的不扎实,而且很久没有编写程序了,第一次上机感觉有困难。
编代码的时候走了好多弯路,其中有一个弯路就是我设立了一个头节点,然后还自以为很聪明的把头节点绕了过去,等等。
很多类似的错误,都是以前觉得自己没问题,一上机才知道原来还存在很多问题。
这是第一次数据结构上机课,以前跟老师上课的时候总是感觉对这种类C语言很陌生,不像和以前学C/C++语言那样,书上的程序一看就知道什么意思,而且这些算法是包含思想的,必须要自己想的特别明白。
简单总结一下思路:
我觉得程序大致分三块
一、是用结构体定义节点类型,每个节点有3个域,两个数据域,一个指针域
二、定义好节点之后,利用指针形成链表,但有一点要注意就是不需要头节点,并且最后一个节点的指针要指向第一个节点,从而构成循环链表
三、删除节点,但关键点是指针的位置一定要移动正确,我觉得这部分一定要想的非常明白才能正确的编出程序
通过这次编程,首先我把约瑟夫环问题的算法弄的非常明白,也通过实验夯实了课内学到的许多知识,在计算机上得到了印证,现在对于定义链表还有对节点进行删除、插入操作也弄的非常明白。
总之,上机能很好的巩固上课学到的知识,正确的编出程序也会觉得很有成就感,很开心,收获颇多!
实验二、停车场管理
【源代码】
#include
#definen2
//将停车场的容量设为2
#definecost10
//将单位时间的停车费设为10,车道里不收费
#defineOVERFLOW-2
#defineERROR0
//分配栈的存储空间失败;
usingnamespacestd;
typedefstructElem
{//定义元素数据结构类型
intcarnum;
inttime;
}Elem;
typedefstructQNode
{//队列
structQNode*next;
ElemQelem;
}QNode,*QueuePtr;
typedefstruct
{
QueuePtrfront;//队头指针
QueuePtrrear;//队尾指针
}LinkQueue;
voidinitqueue(LinkQueue&Q)
{//构造一个空队列
Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode));
if(!
Q.front)exit(OVERFLOW);
Q.front->next=Q.rear->next=NULL;
}
voidenqueue(LinkQueue&Q,intcarnum,inttime)
{//入队操作
QueuePtrp=(QueuePtr)malloc(sizeof(QNode));
p->Qelem.carnum=carnum;
p->Qelem.time=time;
p->next=NULL;
Q.rear->next=p;
Q.rear=p;
}
intlengthqueue(LinkQueueQ)
{
inti=0;
QueuePtrp;
p=Q.front->next;
while(p!
=Q.rear)
{
i++;
p=p->next;
}
i++;
returni;
}
voiddequeue(LinkQueue&Q,Elem&e)
{//从对头离队操作,并返回其值
QueuePtrp=(QueuePtr)malloc(sizeof(QNode));
if(Q.front==Q.rear)
cout<<"车道中没有车辆"<if(Q.front!
=Q.rear)
{
p=Q.front->next;
e=p->Qelem;
Q.front->next=p->next;
if(Q.rear==p)Q.rear=Q.front;
free(p);
}
}
typedefstruct
{
Elem*base;
Elem*top;
intstacksize;
}Sqstack;
voidinitStack(Sqstack&S)
{//创建一个空栈
S.base=(Elem*)malloc(n*sizeof(Elem));
if(!
S.base)exit(OVERFLOW);
S.top=S.base;
S.stacksize=n;
}
intpush(Sqstack&S,Elem&e)//插入新的元素
{
Elem*temp;
if(S.top-S.base==S.stacksize)
return1;
else
{
temp=S.top;
temp->carnum=e.carnum;
temp->time=e.time;
S.top++;
return0;
}
}
intlengthstack(SqstackS)
{//当前栈的长度
returnS.top-S.base;
}
intpop(Sqstack&S,Elem&e){
//删除栈顶元素,并返回其值
if(S.top==S.base)returnERROR;
e=*--S.top;
return1;
}
voidcarin(Sqstack&S,LinkQueue&Q,Elemcar)
{
intk=0;//输入数据正确
QueuePtrr;
Elem*temp;
temp=S.base;
while(temp!
=S.top)
//在栈中寻找是否有同一编号的车;
{
if(temp->carnum==car.carnum)
{
cout<<"该车号在停车场中已存在,请重新输入"<k=1;//找到了有同一编号的车
break;
}
temp++;
}
if(k==0&&Q.front!
=Q.rear)
{//在栈中未找到,从队列中查找
r=Q.front->next;//队头
while(r&&r->Qelem.carnum!
=car.carnum)
{r=r->next;}
if(r&&r->Qelem.carnum==car.carnum){cout<<"该车号在车道中已存在,请重新输入"<}
if(k==0)//说明经检查输入数据正确;
{
if(S.top-S.base!
=S.stacksize)//说明栈未满,
{
S.top->carnum=car.carnum;
S.top->time=car.time;
S.top++;
cout<<"请进入停车场"<}
else
{
enqueue(Q,car.carnum,car.time);
cout<<"请进入便道"<}
}
}
voidcarleave(Sqstack&S,LinkQueue&Q,Elemcar)
{
intture=0;//在栈中没有找到与要离开的车
Eleme,em,*temp;
QueuePtrp,r;
temp=S.base;
if(ture==0)
{
while(temp!
=S.top)//先在栈中寻找;
{
if(temp->carnum==car.carnum)
{
inttemp_cost;
temp_cost=(car.time-temp->time)*cost;
ture=1;//在栈中找到
cout<<"您的停车时间为"<time<<"请交纳费用"<break;
}
temp++;
}
if(ture==1)//备用栈
{
Sqstackspear;
initStack(spear);
while(S.top!
=temp+1)//先在栈中寻找;
{
pop(S,em);
push(spear,em);
}
pop(S,*temp);
if(spear.top!
=spear.base)
{
while(spear.top!
=spear.base)
{
pop(spear,em);
push(S,em);
}
}
}
if(ture==1&&Q.front!
=Q.rear)//栈中有车离开,将队列中的车进入栈中
{
dequeue(Q,e);//离队,并返回数据e
S.top->carnum=e.carnum;
S.top->time=car.time;
S.top++;
cout<}
}
if(ture==0&&Q.front!
=Q.rear)//栈中没找到要离开的车
{
p=Q.front;
r=Q.front->next;//队头
while(r&&r->Qelem.carnum!
=car.carnum)
{
p=r;
r=r->next;
}
if(r&&r->Qelem.carnum==car.carnum)
ture=2;//在队列中找到要离开的车
if(r&&r->Qelem.carnum==car.carnum)
{
ture=2;
cout<<"便道"<Qelem.carnum<<"号车离开,不收取费用"<p->next=r->next;
free(r);
}
}//直接从队列离开
if(ture==0)
cout<<"没有该辆车"<}
intmain()
{
charc;
intj=0,temp_time,i=1;//i==0,判断临时记录时间的temp_time应该去该次的值,还是上次的值。
j==0,表示第一次输入数据,不需要检测数据是否正确
LinkQueueQ;
SqstackS;
Elemcar;
initqueue(Q);
initStack(S);
cout<<"请输入车辆信息(到达离开或退出标志ADE,车牌号,当前时间)"<while(cin>>c>>car.carnum>>car.time)
{
if(j==1)
{
if(S.top==S.base)
cout<<"停车场中没有车"<else
{
temp_time=car.time;
i=1;
}
if(i==1)//正确的数据
{
if(c=='A')//到达
carin(S,Q,car);
elseif(c=='D')
{
if(S.top==S.base);
else
carleave(S,Q,car);
}
}
j=1;
}
if(j==0)//第一次输入数据不需要检测
{
if(c=='A')//到达
carin(S,Q,car);
elseif(c=='D')
{
if(S.top==S.base)
cout<<"停车场中没有车"<else
carleave(S,Q,car);
}
j=1;
temp_time=car.time;
}
if(c=='E')
{
cout<<"输入结束"<break;
}
}
return0;
}
【实验心得】
本次实验较复杂,应先梳理好思路,把整个大程序分成三个小模块,最后拼接起来,再进行整体调试与分析。
模块一:
Carin函数:
如果车来,判断停车场(栈1)是否满。
不满则压入停车场;满则进队列
模块二:
Carleave函数:
如果车离开,首先判断车的位置。
先在停车场进行遍历,如果找到此车,则弹出此车上方的车辆,压入另一个栈(栈2),计算此车的时间以及金钱,并删除此车辆,再把栈2的车辆弹出,压入栈1,再让队头元素出队列,压入栈中;
若停车场中没有遍历到该车辆,则继续在队列中遍历,找到此车辆之后,删除此车辆即可
模块三:
main函数:
判断A、D、E
A:
调用carin函数
B:
调用carleave函数
E:
输入结束End
还有几个实验中需要用到的函数:
Initstack函数//生成一个栈
Stacklength函数//计算栈的长度
Pop函数//元素出栈
Push函数//元素进栈
Initqueue函数//生成一个队列
Queuelength函数//计算队列长度
Enqueue函数//进队列
Dequeue函数//出队列
实验三、哈夫曼编/译码器
【源程序】
#include
#include
#include
#include
#include
constintUINT_MAX=1000;
charstr[50];
typedefstruct
{
intweight,K;
intparent,lchild,rchild;
}HTNode,*HuffmanTree;
typedefchar**HuffmanCode;
HuffmanTreeHT;
HuffmanCodeHC;
intw[50],i,j,n;
charz[50];
intflag=0;
intnumb=0;
//求哈夫曼编码
structcou{
chardata;
intcount;
}cou[50];
intmin(HuffmanTreet,inti)
{
intj,flag;
intk=UINT_MAX;
for(j=1;j<=i;j++)
if(t[j].weightk=t[j].weight,flag=j;
t[flag].parent=1;
returnflag;
}
voidselect(HuffmanTreet,inti,int&s1,int&s2)
{intj;
s1=min(t,i);
s2=min(t,i);
if(s1>s2)
{
j=s1;
s1=s2;
s2=j;
}
}
voidHuffmanCoding(HuffmanTree&HT,HuffmanCode&HC,int*w,intn)
{
intm,i,s1,s2,start;
intc,f;
HuffmanTreep;
char*cd;
if(n<=1)
return;
m=2*n-1;
HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode));
for(p=HT+1,i=1;i<=n;++i,++p,++w)
{
p->weight=*w;
p->parent=0;
p->lchild=0;
p->rchild=0;
}
for(;i<=m;++i,++p)
p->parent=0;
for(i=n+1;i<=m;++i)//建哈夫曼树
{select(HT,i-1,s1,s2);
HT[s1].parent=HT[s2].parent=i;
HT[i].lchild=s1;
HT[i].rchild=s2;
HT[i].weight=HT[s1].weight+HT[s2].weight;
}
HC=(HuffmanCode)malloc((n+1)*sizeof(char*));
cd=(char*)malloc(n*sizeof(char));
cd[n-1]='\0';
for(i=1;i<=n;i++)
{
start=n-1;
for(c=i,f=HT[i].parent;f!
=0;c=f,f=HT[f].parent)
//从叶子到根逆向求编码
if(HT[f].lchild==c)
cd[--start]='0';
else
cd[--start]='1';
HC[i]=(char*)malloc((n-start)*sizeof(char));
//为第i个字符编码分配空间
strcpy(HC[i],&cd[start]);
}
free(cd);
}
//---------------------获取报文并写入文件---------------------------------
intInputCode()
{
FILE*tobetran;
if((tobetran=fopen("tobetran.txt","w"))==NULL)
{
cout<<"不能打开文件"<return0;
}
cout<<"请输入你想要编码的字符"<gets(str);
fputs(str,tobetran);
cout<<"获取报文成功"<fclose(tobetran);
returnstrlen(str);
}
//--------------初始化哈夫曼链表---------------------------------
voidInitialization()
{inta,k,flag,len;
a=0;
len=InputCode();
for(i=0;i{k=0;flag=1;cou[i-a].data=str[i];cou[i-a].count=1;
while(i>k){if(str[i]==str[k]){a++;flag=0;}
k++;
if(flag==0)
break;
}
if(flag)
{
for(j=i+1;j{if(str[i]==str[j])++cou[i-a].count;}
}
}
n=len-a;
for(i=0;i{cout<cout<}
for(i=0;i<=n;i++)
{*(z+i)=cou[i].data;
*(w+i)=cou[i].count;
}
HuffmanCoding(HT,HC,w,n);
//------------------------打印编码-------------------------------------------
cout<<"字符对应的编码为:
"<for(i=1;i<=n;i++)
{
puts(HC[i]);
}
//--------------------------将哈夫曼编码写入文件------------------------
FILE*htmTree;
charr[]={'','\0'};
if((htmTree=fopen("htmTree.txt","w"))==NULL)
{
co