实验报告123C.docx
《实验报告123C.docx》由会员分享,可在线阅读,更多相关《实验报告123C.docx(16页珍藏版)》请在冰豆网上搜索。
实验报告123C
多项式求和
1.试验内容
有两个x的多项式,实现将这两个多项式相加,得到一个新的多项式.
2.试验目的
1,熟练掌握链表的应用;
2,掌握基于链表的基本操作的实现方法
3.试验要求
1,设计实现链表;
2,设计算法完成多项式问题的求解
4.试验解决思路
将两个多项式抽象为链表的形式,通过SLNode
的定义,只要EXP(指数)相同的COEF),相加,不同,则按照降幂的方式新建立一个链表,用于储存相加后的多项式.
5.源程序代码
#include
typedefintelemtype;
typedefstructSLNode
{
elemtypeCOEF;
elemtypeEXP;
structSLNode*Next;
}slnodetype;
intMergeSL(slnodetype*la,slnodetype*lb,slnodetype**lc);
intCreateSL(slnodetype*la,intn);
voidDisplaySL(slnodetype*la,char*comment);
main()
{slnodetype*la,*lb,*lc,*p;
intn,m;
if((la=(slnodetype*)malloc(sizeof(slnodetype)))==NULL)
{
printf("\n内存分配失败!
");
exit(0);
}
la->Next=NULL;
if((lb=(slnodetype*)malloc(sizeof(slnodetype)))==NULL)
{
printf("\n内存分配失败!
");
exit(0);
}
lb->Next=NULL;
printf("\ninputlanumber:
");
scanf("%d",&n);
printf("\ninputlbnumber:
");
scanf("%d",&m);
printf("\ninputla\n");
CreateSL(la,n);
DisplaySL(la,"thela'scomment");
printf("\ninputlb\n");
CreateSL(lb,m);
DisplaySL(lb,"thelb'scomment");
MergeSL(la,lb,&lc);
DisplaySL(lc,"result");
}
intMergeSL(slnodetype*la,slnodetype*lb,slnodetype**lc)
{
slnodetype*pa,*pb,*pc;
if((*lc=(slnodetype*)malloc(sizeof(slnodetype)))==NULL)
{
printf("\n内存分配失败!
");
return0;
}
pa=la->Next;
pb=lb->Next;
pc=*lc;
while(pa&&pb)
{
if((pc->Next=(slnodetype*)malloc(sizeof(slnodetype)))==NULL)
{
printf("\n内存分配失败!
");
return0;
}
pc=pc->Next;
if(pa->EXP==pb->EXP)
{
pc->COEF=pa->COEF+pb->COEF;
pc->EXP=pa->EXP;
pa=pa->Next;
pb=pb->Next;
}
else
if(pa->EXP>pb->EXP)
{
pc->COEF=pa->COEF;
pc->EXP=pa->EXP;
pa=pa->Next;
}
else
{
pc->COEF=pb->COEF;
pc->EXP=pb->EXP;
pb=pb->Next;
}
}
while(pa)
{
if((pc->Next=(slnodetype*)malloc(sizeof(slnodetype)))==NULL)
{
printf("\n内存分配失败!
");
return0;
}
pc=pc->Next;
pc->COEF=pa->COEF;
pc->EXP=pa->EXP;
pa=pa->Next;
}
while(pb)
{
if((pc->Next=(slnodetype*)malloc(sizeof(slnodetype)))==NULL)
{
printf("\n内存分配失败!
!
");
return0;
}
pc=pc->Next;
pc->COEF=pb->COEF;
pc->EXP=pb->EXP;
pa=pb->Next;
}
pc->Next=NULL;
return1;
}
intCreateSL(slnodetype*la,intn)
{
inti;
slnodetype*p,*q;
q=la;
for(i=1;i<=n;i++)
{
if((p=(slnodetype*)malloc(sizeof(slnodetype)))==NULL)
{
printf("\n内存分配失败!
");
return0;
}
scanf("%d,%d",&p->COEF,&p->EXP);
q->Next=p;
q=p;
}
q->Next=NULL;
return1;
}
voidDisplaySL(slnodetype*la,char*comment)
{
slnodetype*p;
p=la->Next;
if(p)printf("\n%s\n",comment);
while(p)
{
printf("\n%d,%d",p->COEF,p->EXP);
p=p->Next;
}
printf("\n");
}
6.试验总结
通过对多项式求和的算法
我了解了怎样构造实现一个链表,同样,在算法中应用到了很多的指针操作.
纯文本附件[扫描并保存到电脑]
迷宫问题
一实验目的
1熟练掌握链栈
2掌握基于顺序栈的基本操作的实现方法
二实验内容
心理学家把老鼠放入迷宫入口,再出口放置奶酪。
迷宫中有很多隔壁,对前进方向形成了很多出障碍,吸引老鼠在迷宫中寻找出路以到达出口,获得奶酪。
三实验要求
1设计数据存储结构;
2设计算法完成迷宫问题的求解
四设计思想
用栈保存搜索路径实现“穷举搜索求解”:
从入口出发,将入口位置置为当前位置,若当前位置“可通”,则将其纳入当前路径(入栈);并顺某一方向继续朝下一位置探索,
切换下一位置为当前位置。
若当前位置“不可通”,则应顺着“来向”退回到“前一通道块”,换“来向”之外的下一方向继续探索;若该通道块的相邻四周4个方向(东、南、西、北)均“不可通”,则应从“当前路径上删除该通道块(出栈!
)。
直至所有可能的通路都探索为止。
用栈记录“当前路径”,栈顶元素就是“当前路径上最后一个通道块”。
实即一种“深度优先搜索”思想。
当前位置“可通”:
指未曾走过的通道块,即既不在当前路径上,也未曾纳入过路径,五源代码
#include
#include
constintN=10;
constM=N*N;
constintStackSize=100;
//10只是示例性的数据,可以根据实际问题具体定义
template//定义模板类SeqStack
classSeqStack
{
public:
SeqStack();//构造函数,栈的初始化
voidPush(Tx);//将元素x入栈
TPop();//将栈顶元素弹出
voidPrint(SeqStack);//取栈顶元素(并不删除)
boolEmpty();//判断栈是否为空
private:
Tdata[StackSize];//存放栈元素的数组
inttop;//栈顶指针,指示栈顶元素在数组中的下标
};
template
SeqStack:
:
SeqStack()
{
top=-1;
}
template
voidSeqStack:
:
Push(Tx)
{
if(top==StackSize-1)exit
(1);
else{
top++;
data[top].d=x.d;
data[top].x=x.x;
data[top].y=x.y;}
}
template
TSeqStack:
:
Pop()
{
Tx;
if(top==-1)throw"下溢";
x=data[top--];
returnx;
}
template
voidSeqStack:
:
Print(SeqStack)
{
while(top!
=-1)
{
cout<<
data[top].x<<'\t'<}
}
template
boolSeqStack:
:
Empty()
{
if(top==-1)return1;
elsereturn0;
}
typedefstruct{intx,y,d;}DataType;
structDirectInc{intdx,dy;};
constDirectIncmove[4]={{0,1},{1,0},{0,-1},{-1,0}};
voidmazepath(intmaze[10][10])
{
DataTypetemp;
intg,h,v,i,j,d;
SeqStackS;//栈(*S)已建立
temp.x=1;temp.y=1;temp.d=-1;//入口位置及方向
S.Push(temp);
while(!
S.Empty())
{
temp=S.Pop();
g=temp.x;h=temp.y;d=temp.d+1;v=0;
while(v<4)
{
i=g+move[v].dx;
j=h+move[v].dy;
if(maze[i][j]==0)
{
temp.x=i;temp.y=j;temp.d=v;
S.Push(temp);
maze[g][h]=-1;g=i;h=j;
if(g5=N-2&&h==N-2)//是N-2
{
S.Ppint(S);
}
else{v=0;}
}
else{v++;}
}
}
}
voidmain()
{
intmaze[N][N]={{1,1,1,1,1,1,!
1,1,1},
{1,0,0,1,0,0,0,1,0,1},
{1,0,0,1,0,0,0,1,0,1},
{1,0,0,0,0,1,1,0,0,1},
{1,0,1,1,1,0,0,0,0,1},
{1,0,0,0,1,0,0,0,0,1},
{1,0,1,0,0,0,1,0,0,1},
{1,0,1,1,1,0,1,1,0,1},
{1,1,0,0,0,0,0,0,0,1},
{1,1,1,1,1,1,1,1,1,1}};
cout<<"从出口到入口的路径为\n(x
y代表坐标代表方向(东0,南1,西2,北3))\nx\ty\td"<mazepath(maze);
}
纯文本附件[扫描并保存到电脑]
约瑟夫环
1.试验内容
编号为1,2,....,N的N个人按顺时针方向围坐一圈,每人持有一个密码(正整数),一开始任选一个正整数作为报数上限值M,从第一个人开始按顺时针方向自1开始顺序报数,报到M时停止报数。
报M的人出列,将他的密码作为新的M值,从他在顺时针方向上的下一个人开始重新从1报数,如此下去,直至所有人全部出列为止。
试设计一个程序求出出列顺序。
2.试验目的
1,熟练掌握单循环堆栈的应用;
2,掌握基于单循环栈的基本操作的实现方法
3.试验要求
1设计数据存储结构;
2设计算法完成迷宫问题的求解
4.试验解决思路:
显示建立起一条单循环链表,把一个这条单循环链表看成一圈围坐的人,分别带有id
和
cipher,然后按照初始化密码第一个人开始报数,删除相应的节点并取得该节点的cipher作为下一个M值。
依此类推直到最后一个节点被删除。
5.源程序代码
#include
#include
#defineMAX_NODE_NUM100
typedefstructNodeType
{
intid;
intcipher;
structNodeType*next;
}NodeType;
staticintCreateRandom();/*产生随机数作为密码*/
staticvoidCreateList(NodeType**,constint);/*创建单向循环链表*/
staticvoidStartJoseph(NodeType**,int);/*运行"约瑟夫环"问题*/
staticvoidPrintList(constNodeType*);/*打印循环链表*/
staticNodeType*GetNode(constint,constint);/*得到一个结点*/
staticunsignedEmptyList(constNodeType*);/*测试链表是否为空,
空为TRUE,非空为FALSE*/
intmain(void)
{
intn,m;
NodeType*pHead=NULL;
while
(1)
{
printf("请输入人数n(最多%d个):
",MAX_NODE_NUM);
scanf("%d",&n);
printf("和初始密码m:
");
scanf("%d",&m);
if(n>MAX_NODE_NUM)
{
printf("人数太多,请重新输入!
\n");
continue;
}
else
break;
}
CreateList(&pHead,n);
printf("\n-----------循环链表初始话打印-------------\n");
PrntList(pHead);
printf("\n-----------删除出队情况打印-------------\n");
StartJoseph(&pHead,m);
}
staticintCreateRandom();
{
intnum;
srand((int)time(0));
num=1+(int)rand()%MAX_NODE_NUM;
returnnum;
}
staticvoidCreateList(NodeType**ppHead,constintn)
{
inti,iCipher;
NodeType*pNew,*pCur;
for(i=1;i<=n;i++)
{
iCipher=CreateRandom();/*产生随机正整数*/
pNew=GetNode(i,iCipher);
if(*ppHead==NULL)
{
*ppHead=pCur=pNew;
pCur->next=*ppHead;
}
else
{
pNew->next=pCur->next;
pCur->next=pNew;
pCur=pNew;
}
}
printf("完成单向循环链表的创建!
\n");
}
staticvoidStartJoseph(NodeType**ppHead,intiCipher)
{
intiCounter,iFlag=1;
NodeType*pPrv,*pCur,*pDel;
pPrv=pCur=*ppHead;
/*将pPrv初始为指向尾结点,为删除作好准备*/
while(pPrv->next!
=*ppHead)
pPrv=pPrv->next;
while(iFlag)
{
for(iCounter=1;iCounter{
pPrv=pCur;
pCur=pCur->next;
}
if(pPrv==pCur)
iFlag=0;
pDel=pCur;/*删除pCur指向的结点,即有人出列*/
pPrv->next=pCur->next;
pCur=pCur->next;
iCipher=pDel->cipher;
printf("第%d个人出列,密码:
%d\n",pDel->id,
pDel->cipher);
free(pDel);
}
*ppHead=NULL;
}
staticvoidPrintList(constNodeType*pHead)
{
constNodeType*pCur=pHead;
if(EmptyList(pHead))
return;
do
{
printf("第%d个人,密码:
%d\n",pCur->id,
pCur->cipher);
pCur=pCur->next;
}while(pCur!
=pHead);
}
staticNodeType*GetNode(constintiId,constintiCipher)
{
NodeType*pNew;
pNew=(NodeType*)malloc(sizeof(NodeType));
if(!
pNew)
{
printf("Error,thememoryisnotenough!
\n");
exit(-1);
}
pNew->id=iId;
pNew->cipher=iCipher;
pNew->next=NULL;
returnpNew;
}
staticunsignedEmptyList(constNodeType*pHead)
{
if(!
pHead)
{
returnTRUE;
}
returnFALSE;
}
6.实验总结
通过学习约瑟夫环算法我理解了循环链表如何
建立节点——》连接链表——》删除节点等链表操作,并且在算法里用到了很多指针操作,虽然程序存在错误,但这里让我对指针以及单循环堆栈操作有了更深的认识。