数据结构实验.docx

上传人:b****5 文档编号:29173260 上传时间:2023-07-21 格式:DOCX 页数:22 大小:111.30KB
下载 相关 举报
数据结构实验.docx_第1页
第1页 / 共22页
数据结构实验.docx_第2页
第2页 / 共22页
数据结构实验.docx_第3页
第3页 / 共22页
数据结构实验.docx_第4页
第4页 / 共22页
数据结构实验.docx_第5页
第5页 / 共22页
点击查看更多>>
下载资源
资源描述

数据结构实验.docx

《数据结构实验.docx》由会员分享,可在线阅读,更多相关《数据结构实验.docx(22页珍藏版)》请在冰豆网上搜索。

数据结构实验.docx

数据结构实验

武汉工程大学

计算机科学与工程学院

《算法与数据结构》实验报告

专业班级

10智能01班

实验地点

201

学生学号

1005030134

指导教师

吕品

学生姓名

谢红涛

实验时间

实验项目

实验2非线性结构综合应用

实验类别

操作性()验证性()设计性()综合性(√)其它()

实验目的及要求

1.加深理解树和图的非线性结构特点;

2.灵活运用树和图的存储结构、二叉树的遍历技术、图的拓扑排序等来解决有关应用问题;

3.加深递归程序设计的训练;

4.注重提高关于模型选择、算法设计和分析方面的能力。

成绩评定表

类别

评分标准

分值

得分

合计

上机表现

积极出勤、遵守纪律

主动完成实验设计任务

30分

程序代码

比较规范、基本正确

功能达到实验要求

30分

实验报告

及时递交、填写规范

内容完整、体现收获

40分

说明:

评阅教师:

日期:

2012年月日

实验内容

1.二叉树的前序,中序与后序遍历的非递归算法。

(必做)

算法的描述:

结点要入两次栈,出两次栈;为了区别同一个结点的两次出栈,设置标志flag,当结点进、出栈时,其标志flag也同时进、出栈。

 

1.栈s初始化;

2.循环直到root为空且栈s为空

2.1当root非空时循环

2.1.1将root连同标志flag=1入栈;

2.1.2继续遍历root的左子树;

2.2当栈s非空且栈顶元素的标志为2时,出栈并输出栈顶结点;

2.3若栈非空,将栈顶元素的标志改为2,准备遍历栈顶结点的右子树;

核心程序代码:

#include//后序遍历非递归算法

#include

#include

usingnamespacestd;

structtree

{

chardata;

structtree*lchild;

structtree*rchild;

};

typedefstructtree*treptr;

treptrbuild(treptrt)//先序建树

{

charc;

c=getchar();

if(c=='#')

{

t=NULL;

}

else

{

t=(treptr)malloc(sizeof(structtree));

t->data=c;

t->lchild=build(t->lchild);

t->rchild=build(t->rchild);

}

returnt;

}

structstack

{

treptr*top,*base;

};

typedefstructstack*stackptr;

voidinit(stackptrs)//初始化栈

{

s->base=(treptr*)malloc(sizeof(treptr)*100);

s->top=s->base;

}

voidpush(stackptrs,treptrt)//入栈

{

*(s->top++)=t;

}

treptrpop(stackptrs)//弹出栈顶元素

{

treptrt;

t=*(--(s->top));

returnt;

}

treptrgettop(stackptrs)//取栈顶元素

{

treptr*l=s->top-1;

return*(l);

}

voidpostorder(treptrt)//这是非递归后序实现

{

stackptrs=(stackptr)malloc(sizeof(structstack));

treptrtemp=t;

treptrp;

treptrlastvist=NULL;

init(s);

p=t;

while(p||s->top!

=s->base)

{

while(p)

{

push(s,p);

p=p->lchild;

}

temp=gettop(s);

if(temp->rchild==NULL||temp->rchild==lastvist)

{

putchar(temp->data);

lastvist=pop(s);

}

else

p=temp->rchild;

}

}

intmain()

{

cout<<"请输入这颗二叉树(以##表示该节点无子树,并最终以#表示输入完毕):

"<

treptrt=NULL;

t=build(t);

printf("非递归后序遍历\n");

postorder(t);

printf("\n");

return0;

}

给出随意构造的二叉树,以其为实验目标

初始界面,提示输入一个二叉树,根据图示,以及输入规则,这里输入回车后,即出现后序遍历的序列:

DEBFCA

如下图所示:

遇到的问题及解决办法:

 

2.任意给定一个有向图,设计一个算法,对它进行拓扑排序。

(必做)

 

算法的描述:

1.栈S初始化;累加器count初始化;

2.扫描顶点表,将没有前驱(即入度为0)的顶点压栈;

3.当栈S非空时循环

3.1vj=退出栈顶元素;输出vj;累加器加1;

3.2将顶点vj的各个邻接点的入度减1;

3.3将新的入度为0的顶点入栈;

4.if(count

 

核心程序代码:

#include

usingnamespacestd;

#definemaxsize50

structnode

{

intadjvex;

node*next;

};

structgraph

{

intvexter;

intin;

node*firstedge;

};

typedefstruct

{

int*base;

int*top;

intstacksize;

}sqstack;

voidinitstack(sqstack&S)

{

S.base=(int*)malloc(sizeof(int));

S.top=S.base;

S.stacksize=maxsize+1;

}

voidcreateadlist(graphinDegree[],intn,inte)//创建邻接链表

{

inti,k,j;

node*q;

for(i=1;i<=n;i++)

{

inDegree[i].vexter=i;

inDegree[i].in=0;

inDegree[i].firstedge=NULL;

}

for(k=1;k<=e;k++)

{

cout<<"请输入第"<

\n";

cout<<"从";

cin>>i;

cout<<"邻接到";

cin>>j;

cout<<'\n';

inDegree[j].in++;

q=(node*)malloc(sizeof(structnode));

q->adjvex=j;

q->next=inDegree[i].firstedge;

inDegree[i].firstedge=q;

}

}

voidTopoSort(graphinDegree[],intn)

{

inti,v,count=0;

sqstackS;

node*p;

initstack(S);

for(i=1;i<=n;i++)

if(inDegree[i].in==0)

*S.top++=i;

while(S.top!

=S.base)

{

v=*--S.top;

cout<

count++;

p=inDegree[v].firstedge;

while(p!

=NULL)

{

inDegree[p->adjvex].in--;

if(inDegree[p->adjvex].in==0)

*S.top++=p->adjvex;

p=p->next;

}

}cout<

if(count

elsecout<<"无回路"<

}

voidmain()

{

graphinDegree[maxsize];

intv,e;

cout<<"该AOV网的顶点数:

";

cin>>v;

cout<<"该AOV网的边条数:

";

cin>>e;

createadlist(inDegree,v,e);

cout<<"拓扑排序序列为:

"<

TopoSort(inDegree,v);

}

实验结果:

首先给出此次实验结果所用的AOV网图示:

(1)初始界面,提示输入AOV网的定点数及边数,根据以上图示,这里输入5和6,显示如下:

(2)再提示输入各个边,从第一条边到第六条边的邻接序列,即从X邻接到Y,根据图示,这里分别是从1邻接到2、从1邻接到3、从2邻接到3、从3邻接到5、从3邻接到4、从5邻接到4这六条边,将其分别输入,得以下图示:

系统计算出AOV网的拓扑排序序列,输出了12354,即图示拓扑网络的拓扑排序序列,并提示无回路。

若某个网,有回路,则不会输出拓扑序列,并输出“有回路”。

遇到的问题及解决办法:

 

3.任意给定一个AOE网,设计一个算法求其关键路径。

(选做)

算法的描述:

核心程序代码:

遇到的问题及解决办法:

 

4火车车厢重排

算法的描述:

1.分别对k个队列初始化;

2.初始化下一个要输出的车厢编号nowOut=1;

3.依次取入轨中的每一个车厢的编号;

3.1如果入轨中的车厢编号等于nowOut,则

3.1.1输出该车厢;

3.1.2nowOut++;

3.2否则,考察每一个缓冲轨队列

for(j=1;j<=k;j++)

3.2.1取队列j的队头元素c;

3.2.2如果c=nowOut,则

3.2.2.1将队列j的队头元素出队并输出;

3.2.2.2nowOut++;

3.3如果入轨和缓冲轨的队头元素没有编号为nowOut的车厢,则

3.3.1求小于入轨中第一个车厢编号的最大队尾元素所在队列编号j;

3.3.2如果j存在,则把入轨中的第一个车厢移至缓冲轨j;

3.3.2如果j不存在,但有多于一个空缓冲轨,则把入轨中的第一个车厢移至一个空缓冲轨;否则车厢无法重排,算法结束;

 

核心程序代码:

#include

#include

usingnamespacestd;

constintQueueSize=1000;

template

structNode

{

 Tdata;

 Node*next;

};

template

classLinkQueue    //链队列模板类    

{

public:

 LinkQueue();   //构造函数

 ~LinkQueue();  //析构函数

 voidTrans();  //遍历缓冲轨

 voidEnQueue(Tx);//入队

 TDeQueue();     //出队

 TGetFront()     //查找队头元素

 {if(front!

=rear)returnfront->next->data;}

 TGetRear()      //查找队尾元素

 {if(front!

=rear)returnrear->data;}

 boolEmpty(){front==NULL?

return1:

return0;}   //判断队空

 friendvoidTrainPermute(intarr[],LinkQueuea[],intn,intk);

private:

 Node*front,*rear;

};

template

LinkQueue:

:

LinkQueue()

{

 Node*s=newNode;

 s->next=NULL;

 front=rear=s;

}

template

LinkQueue:

:

~LinkQueue()

{

 Node*p=front;

 while(p!

=NULL)

 {

  Node*q=p;

     p=p->next;

  deleteq;

 }

}

template

voidLinkQueue:

:

EnQueue(Tx)

{

 Node*s=newNode;

 s->data=x;

 s->next=NULL;

 rear->next=s;

 rear=s;

}

template

TLinkQueue:

:

DeQueue()

{

 if(rear==front)throw"下溢";

 Node*p=front->next;

 intx=p->data;

 front->next=p->next;

 if(p->next==NULL)

  rear=front;

 deletep;

 returnx;

}

template

voidLinkQueue:

:

Trans()

{Node*p=front->next;

while(p)

{

   

 cout<data<<'';

 p=p->next;

};

}

voidmain()

{

 try

 {

  intn,k,t;

  cout<<"请输入火车车厢数n(n请小于1000):

\nn=";

  cin>>n;

       cout<<"请输入缓冲轨数k:

\nk=";

  cin>>k;

  cout<<"系统将对"<

\n";

  if(n>1000)throw"输入错误!

车厢数必须小于1000!

";

  if(n<=0)throw"输入错误!

车厢数必须大于0!

";

  if(k<=0)throw"输入错误!

缓冲轨数必须大于0!

";

  

  srand((unsigned)time(NULL));

  intcount=0;

  int*array;

  array=newint[n];

  int*ifmark;

  ifmark=newint[n];

  while(count!

=n)

  {

   t=rand()%n;

   if(ifmark[t]!

=1)

   {

    array[t]=count+1;

    ifmark[t]=1;

    count++;

   }

 }

  cout<<"火车车厢入轨顺序为:

"<

  for(inti=0;i

   cout<

  cout<

  LinkQueue*buffer;

  buffer=newLinkQueue[k];

  

  TrainPermute(array,buffer,n,k);

  cout<

 }

 catch(char*s)

 {

  cout<

 } 

}

voidTrainPermute(intarr[],LinkQueuea[],intn,intk)

{

 inti=0;

 

 boolaa=1;

 

 while((i

 {

  aa=0;                //亮点:

与非门思想!

  for(intm=0;m

  {  

   if(a[m].GetRear()

   {

    a[m].EnQueue(arr[i]);

    i++;

    aa=1;

    break;

   }

   if(a[m].front->next==NULL)

   {

    a[m].EnQueue(arr[i]);

    aa=1;

    i++;

    break;

   }

  }

 }

 if(aa==0)   //当无法将入轨中队头车厢移至合适缓冲轨中时,程序结束

 {

  cout<<"车厢无法重排,算法结束"<

 } 

 else                //当入轨中已经没有车厢时

 {

  for(intm=0;m

  {

   cout<<"第"<<(m+1)<<"个缓冲轨的列车编号";

   a[m].Trans();

   cout<

  }

  cout<<"火车车厢出轨顺序为:

"<

  for(intnewOut=1;newOut<=n;newOut++)

  {

   for(intj=0;j

   {  

    if(a[j].GetFront()==newOut)

    {

     cout<

    }  } } }}

实验结果:

(1)初始界面,提示输入火车车厢数n(n请小于1000)

(2)这里取车厢数为9,缓冲轨道数为3,和实验指导书上的一致,按回车后,系统对9个数字随机排列并入轨,自动输出入轨顺序(这里随机生成为672814359),并分别显示1、2、3号缓冲轨上的列车编号,最后输出出轨顺序(9个车厢,所以这里是123456789),程序结束,提示Pressanykeytocontinue.

 

遇到的问题及解决办法:

 

5稀疏矩阵的转置

算法的描述:

1.设置转置后矩阵B的行数、列数和非零元素的个数;

2.计算A中每一列的非零元素个数;

3.计算A中每一列的第一个非零元素在B中的下标;

4.依次取A中的每一个非零元素对应的三元组;

2.1确定该元素在B中的下标pb;

2.2将该元素的行号列号交换后存入B中pb的位置;

2.3预置该元素所在列的下一个元素的存放位置;

 

核心程序代码:

#include

#include

usingnamespacestd;

constintQueueSize=1000;

template

structNode

{

 Tdata;

 Node*next;

};

template

classLinkQueue    //链队列模板类    

{

public:

 LinkQueue();   //构造函数

 ~LinkQueue();  //析构函数

 voidTrans();  //遍历缓冲轨

 voidEnQueue(Tx);//入队

 TDeQueue();     //出队

 TGetFront()     //查找队头元素

 {if(front!

=rear)returnfront->next->data;}

 TGetRear()      //查找队尾元素

 {if(front!

=rear)returnrear->data;}

 boolEmpty(){front==NULL?

return1:

return0;}   //判断队空

 friendvoidTrainPermute(intarr[],LinkQueuea[],intn,intk);

private:

 Node*front,*rear;

};

template

LinkQueue:

:

LinkQueue()

{

 Node*s=newNode;

 s->next=NULL;

 front=rear=s;

}

template

LinkQueue:

:

~LinkQueue()

{

 Node*p=front;

 while(p!

=NULL)

 {

  Node*q=p;

     p=p->next;

  deleteq;

 }

}

template

voidLinkQueue:

:

EnQueue(Tx)

{

 Node*s=newNode;

 s->data=x;

 s->next=NULL;

 rear->next=s;

 rear=s;

}

template

TLinkQueue:

:

DeQueue()

{

 if(rear==front)throw"下溢";

 Node*p=front->next;

 intx=p->data;

 front->next=p->next;

 if(p->next==NULL)

  rear=front;

 deletep;

 returnx;

}

template

voidLinkQueue:

:

Trans()

{Node*p=front->next;

while(p)

{

   

 cout<data<<'';

 p=p->next;

};

}

voidmain()

{

 try

 {

  intn,k,t;

  cout<<"请输入火车车厢数n(n请小于1000):

\nn=";

  cin>>n;

       cout<<"请输入缓冲轨数k:

\nk=";

  cin>>k;

  cout<<"系统将对"<

\n";

  if(n>1000)throw"输入错误!

车厢数必须小于1000!

";

  if(n<=0)throw"输入错误!

车厢数必须大于0!

";

  if(k<=0)throw"输入错误!

缓冲轨数必须大于0!

";

  

  srand((unsigned)time(NULL));

  intcoun

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 初中教育 > 英语

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1