《数据结构》实验指导书.docx
《《数据结构》实验指导书.docx》由会员分享,可在线阅读,更多相关《《数据结构》实验指导书.docx(37页珍藏版)》请在冰豆网上搜索。
《数据结构》实验指导书
《数据结构》
实验指导书
10学时
实验一链表的插入和删除
一、实验内容:
1.初始化链表L
2.销毁链表L
3.清空链表L
4.求链表L的长度
5.判链表L空否。
6.通过e返回链表L中第i个数据元素的内容
7.在链表L中检索值为e的数据元素
8.返回链表L中结点e的直接前驱结点
9.返回链表L中结点e的直接后继结点
10.在链表L中第i个数据元素之前插入数据元素e
11.将链表L中第i个数据元素删除,并将其内容保存在e中。
二、实验环境:
1.硬件环境
计算机一台
2.软件环境
MicrosoftVisualStudio2008集成开发环境
Windows操作系统(WindowsXP、Windows7、WindowsServer2008)
三、实验步骤:
#include
usingnamespacestd;
//实现线性表的链式存储结构的类型定义
typedefintElemtype;
#defineOK1;
#defineERROR-1;
structNODE//结点类型
{
Elemtypeelem;
NODE*next;
};
structLINK_LIST//链表类型
{
NODE*head;
};
//典型操作的算法实现
//初始化链表L
intInitList(LINK_LIST*L)
{
L->head=(NODE*)malloc(sizeof(NODE));//为头结点分配存储单元
if(L->head){L->head->next=NULL;returnOK;}
elsereturnERROR;
}
//销毁链表L
voidDestoryList(LINK_LIST*L)
{
NODE*p;
while(L->head)//依次删除链表中的所有结点
{
p=L->head;L->head=L->head->next;
free(p);
}
}
//清空链表L
voidClearList(LINK_LIST*L)
{
NODE*p;
while(L->head->next){//p指向链表中头结点后面的第一个结点
p=L->head->next;
L->head->next=p->next;//删除p结点
free(p);//释放p结点占据的存储空间
}
}
//求链表L的长度
intListLength(LINK_LISTL)
{
NODE*p;
intlen;
len=0;
for(p=L.head;p->next!
=NULL;p=p->next)
len++;
return(len);
}
//判链表L空否。
intIsEmpty(LINK_LISTL)
{
if(L.head->next==NULL)returntrue;
elsereturnfalse;
}
//()通过e返回链表L中第i个数据元素的内容
voidGetElem(LINK_LIST*L,inti,Elemtype*e)
{
NODE*p;
intj;
if(i<1||i>ListLength(*L))
exit(-1);//检测i值的合理性
for(p=L.head,j=0;j!
=i;p=p->next,j++);
p=L->head;
for(j=0;j
p=p->next;
*e=p->elem;//将第i个结点的内容赋给e指针所指向的存储单元中
}
//在链表L中检索值为e的数据元素
NODE*LocateELem(LINK_LISTL,Elemtypee)
{
NODE*p;
for(p=L.head->next;p&&p->elem!
=e;p=p->next);//寻找满足条件的结点
return(p);
}
//返回链表L中结点e的直接前驱结点
NODE*PriorElem(LINK_LISTL,NODE*e)
{
NODE*p;
if(L.head->next==e)returnNULL;//检测第一个结点
for(p=L.head;p->next&&p->next!
=e;p=p->next);
if(p->next==e)returnp;
elsereturnNULL;
}
//返回链表L中结点e的直接后继结点
NODE*NextElem(LINK_LISTL,NODE*e)
{
NODE*p;
for(p=L.head->next;p&&p!
=e;p=p->next);
if(p)p=p->next;
returnp;
}
//在链表L中第i个数据元素之前插入数据元素e
intListInsert(LINK_LIST*L,inti,Elemtypee)
{
NODE*p,*s;
if(i<1||i>ListLength(*L)+1)returnERROR;
p=L->head;
for(intj=0;jp=p->next;
s=(NODE*)malloc(sizeof(NODE));
if(s==NULL)returnERROR;
s->elem=e;
s->next=p->next;p->next=s;//将s结点插入
returnOK;
}
//将链表L中第i个数据元素删除,并将其内容保存在e中。
intListDelete(LINK_LIST*L,inti,Elemtype*e)
{
NODE*p,*s;
if(i<1||i>ListLength(*L))returnERROR;//检查i值的合理性
p=L->head;
for(intj=0;jp=p->next;
s=p->next;//用s指向将要删除的结点
p->next=s->next;//删除s指针所指向的结点
*e=s->elem;
free(s);
returnOK;
}
voidmain()
{
LINK_LISTNL;
InitList(&NL);
cout<inta,b;
a=11;
ListInsert(&NL,1,a);
a=21;
ListInsert(&NL,1,a);
a=31;
ListInsert(&NL,1,a);
cout<GetElem(&NL,1,&b);
cout<
GetElem(&NL,2,&b);
cout<
GetElem(&NL,3,&b);
cout<
ListDelete(&NL,1,&a);
GetElem(&NL,1,&b);
cout<
DestoryList(&NL);
getchar();
}
实验二多项式相加
一、实验内容:
1.建立多项式链表数据结构
2.生成结点并插入链表
3.释放结点
4.初始化多项式链表
5.创建链表
6.销毁链表
7.在头结点插入数据
8.在头结点删除数据
9.在尾结点添加数据
10.打印多项式
11.多项式加法函数
二、实验环境:
1.硬件环境
计算机一台
2.软件环境
MicrosoftVisualStudio2008集成开发环境
Windows操作系统(WindowsXP、Windows7、WindowsServer2008)
三、实验步骤:
#include
usingnamespacestd;
#defineTRUE1
#defineFALSE0
#defineOK1
#defineERROR0
typedefintStatus;
//项结点数据结构
typedefstruct
{
floatcoef;
intexpn;
}term,ElemType;
typedefstructLNode
{
ElemTypedata;
LNode*next;
}*Link,*Position;
//多项式链表数据结构
structLinkList
{
Linkhead;
Linktail;
intlen;
};
typedefLinkListpolynomial;
//生成结点并插入链表
voidMakeNode(Link&p,ElemTypee)
{
p=(Link)malloc(sizeof(LNode));
if(!
p)
{
exit(ERROR);
}
p->data=e;
}
//释放结点
voidFreeNode(Link&p)
{
free(p);
p=NULL;
}
//初始化多项式链表
voidInitList(LinkList&L)
{
Linkp;
p=(Link)malloc(sizeof(LNode));
if(p)
{
p->next=NULL;
L.head=L.tail=p;
L.len=0;
}
else
{
exit(ERROR);
}
}
//创建链表
voidClearList(LinkList&L)
{
Linkp,q;
if(L.head!
=L.tail)
{
p=q=L.head->next;
L.head->next=NULL;
while(p!
=L.tail)
{
p=q->next;
free(q);
q=p;
}
free(q);
L.tail=L.head;
L.len=0;
}
}
//销毁链表
voidDestroyList(LinkList&L)
{
ClearList(L);
FreeNode(L.head);
L.tail=NULL;
L.len=0;
}
//头结点插入数据
voidInsFirst(LinkList&L,Linkh,Links)
{
s->next=h->next;
h->next=s;
if(h==L.tail)
{
L.tail=h->next;
}
L.len++;
}
//头结点删除数据
StatusDelFirst(LinkList&L,Linkh,Link&q)
{
q=h->next;
if(q)
{
h->next=q->next;
if(!
h->next)
{
L.tail=h;
}
L.len--;
returnOK;
}
else
returnFALSE;
}
voidAppend(LinkList&L,Links)
{
inti=1;
L.tail->next=s;
while(s->next)
{
s=s->next;
i++;
}
L.tail=s;
L.len+=i;
}
ElemTypeGetCurElem(Linkp)
{
returnp->data;
}
StatusListEmpty(LinkListL)
{
if(L.len)
returnFALSE;
else
returnTRUE;
}
PositionGetHead(LinkListL)
{
returnL.head;
}
PositionNextPos(Linkp)
{
returnp->next;
}
StatusLocateElem(LinkListL,ElemTypee,Position&q,int(*compare)(ElemType,ElemType))
{
Linkp=L.head,pp;
do
{
pp=p;
p=p->next;
}
while(p&&(compare(p->data,e)<0));
if(!
p||compare(p->data,e)>0)
{
q=pp;
returnFALSE;
}
else
{
q=p;
returnTRUE;
}
}
intcmp(terma,termb)
{
if(a.expn==b.expn)
return0;
else
return(a.expn-b.expn)/abs(a.expn-b.expn);
}
voidCreatPolyn(polynomial&P,intm)
{
Positionq,s;
terme;
inti;
InitList(P);
printf("请依次输入%d个系数,指数\n",m);
for(i=1;i<=m;i++)
{
scanf("%f",&e.coef);
getchar();
scanf("%d",&e.expn);
getchar();
if(!
LocateElem(P,e,q,cmp))
{
MakeNode(s,e);
InsFirst(P,q,s);
}
}
}
//打印多项式
voidPrintPolyn(polynomialP)
{
Linkq;
q=P.head->next;
while(q)
{
cout<data.coef<<"x^"<data.expn;
q=q->next;
if(q)cout<<"+";
}
}
//加法函数
voidAddPolyn(polynomial&Pa,polynomial&Pb)
{
Positionha,hb,qa,qb;
terma,b;
ha=GetHead(Pa);
hb=GetHead(Pb);
qa=NextPos(ha);
qb=NextPos(hb);
while(!
ListEmpty(Pa)&&!
ListEmpty(Pb)&&qa)
{
a=GetCurElem(qa);
b=GetCurElem(qb);
switch(cmp(a,b))
{
case-1:
ha=qa;
qa=NextPos(ha);
break;
case0:
qa->data.coef+=qb->data.coef;
if(qa->data.coef==0)
{
DelFirst(Pa,ha,qa);
FreeNode(qa);
}
else
ha=qa;
DelFirst(Pb,hb,qb);
FreeNode(qb);
qb=NextPos(hb);
qa=NextPos(ha);
break;
case1:
DelFirst(Pb,hb,qb);
InsFirst(Pa,ha,qb);
ha=ha->next;
qb=NextPos(hb);
}
}
if(!
ListEmpty(Pb))
{
Pb.tail=hb;
Append(Pa,qb);
}
DestroyList(Pb);
}
voidmain()
{
polynomialp,q;
intm;
printf("请输入第一个一元多项式的非零项的个数:
");
scanf("%d",&m);
CreatPolyn(p,m);
printf("请输入第二个一元多项式的非零项的个数:
");
scanf("%d",&m);
CreatPolyn(q,m);
AddPolyn(p,q);
printf("两个一元多项式相加的结果\n");
PrintPolyn(p);
getchar();
}
实验三二叉树的遍历
一、实验内容:
1.构造空二叉树T
2.按层序次序输入二叉树中结点的值
3.返回二叉树是否为空
4.返回二叉树深度
5.若e是T的非根结点,则返回二叉树的双亲
6.返回二叉树的左孩子
7.返回二叉树的右兄弟
8.先序遍历T,对每个结点调用函数Visit一次且仅一次
9.中序遍历T,对每个结点调用函数Visit一次且仅一次
10.后序遍历T,对每个结点调用函数Visit一次且仅一次
11.逐层输出二叉树
二、实验环境:
1.硬件环境
计算机一台
2.软件环境
MicrosoftVisualStudio2008集成开发环境
Windows操作系统(WindowsXP、Windows7、WindowsServer2008)
三、实验步骤:
#include
#include
usingnamespacestd;
typedefcharTElemType;
//二叉树的顺序存储表示
#defineMAX_TREE_SIZE100//二叉树的最大结点数
typedefTElemTypeSqBiTree[MAX_TREE_SIZE];//0号单元存储根结点
typedefstruct
{
intlevel,//结点的层
order;//本层序号(按满二叉树计算)
}position;
typedefintQElemType;
//队列的顺序存储结构(可用于循环队列和非循环队列)
#defineMAXQSIZE5//最大队列长度(对于循环队列,最大队列长度要减)
typedefstruct
{
QElemType*base;//初始化的动态分配存储空间相当于一个数组
intfront;//头指针,若队列不空,指向队列头元素,相当于一个数组下标
intrear;//尾指针,若队列不空,指向队列尾元素的下一个位置
//相当于一个数组下标
}SqQueue;
#defineClearBiTreeInitBiTree//在顺序存储结构中,两函数完全一样
TElemTypeNil='';//设空为字符型的空格符
//构造空二叉树T。
因为T是固定数组,不会改变,故不需要&
intInitBiTree(SqBiTreeT)
{
inti;
for(i=0;iT[i]=Nil;//初值为空
return1;
}
voidDestroyBiTree()
{
//由于SqBiTree是定长类型,无法销毁
}
//按层序次序输入二叉树中结点的值(字符型或整型),构造顺序存储的二叉树T
intCreateBiTree(SqBiTreeT)
{
inti=0,l;
chars[MAX_TREE_SIZE];
printf("请按层序输入结点的值(字符),空格表示空结点,结点数≤%d:
\n",
MAX_TREE_SIZE);
printf("例如:
abcefgh\n");
gets(s);//输入字符串
l=strlen(s);//求字符串的长度
for(;i{
T[i]=s[i];
//此结点(不空)无双亲且不是根,T[(i+1)/2-1]==Nil表示T[i]无双亲
if(i!
=0&&T[(i+1)/2-1]==Nil&&T[i]!
=Nil)
{
printf("出现无双亲的非根结点%c\n",T[i]);
exit(0);
}
}
for(i=l;iT[i]=Nil;
return1;
}
//若T为空二叉树,则返回,否则
intBiTreeEmpty(SqBiTreeT)
{
if(T[0]==Nil)//根结点为空,则树空
return1;
else
return0;
}
//返回T的深度
intBiTreeDepth(SqBiTreeT)
{
inti,j=-1;
for(i=MAX_TREE_SIZE-1;i>=0;i--)//找到最后一个结点
if(T[i]!
=Nil)
break;
i++;//为了便于计算
do
j++;
while(i>=pow(2.0,j));//i>pow(2,depth-1)&&i<=pow(2,depth)
returnj;//j=depth;
}
//当T不空,用e返回T的根,返回;否则返回,e无定义
intRoot(SqBiTreeT,TElemType*e)
{
if(BiTreeEmpty(T))//T空
return0;
else
{
*e=T[0];
return1;
}
}
//返回处于位置e(层,本层序号)的结点的值
TElemTypeValue(SqBiTreeT,positione)
{
//将层、本层序号转为矩阵的序号
returnT[((int)pow(2.0,e.level-1)-1)+(e.order-1)];
//((int)pow(2,e.level-1)-1)为该e.level的结点个数,
//(e.order-1)为本层的位置
}
//给处于位置e(层,本层序号)的结点赋新值value
intAssign(SqBiTreeT,positione,TElemTypevalue)
{
//将层、本层序号转为矩阵的序号
inti=(int)pow(2.0,e.level-1)+e.order-2;
if(value!
=Nil&&T[(i+1)/2-1]==Nil)//叶子非空值但双亲为空
return0;
elseif(value==Nil&&(T[i*2+1]!
=Nil||T[i*2+2]!