数据结构实验四五六.docx
- 文档编号:4192530
- 上传时间:2022-11-28
- 格式:DOCX
- 页数:25
- 大小:23.37KB
数据结构实验四五六.docx
《数据结构实验四五六.docx》由会员分享,可在线阅读,更多相关《数据结构实验四五六.docx(25页珍藏版)》请在冰豆网上搜索。
数据结构实验四五六
数据结构实验
实验四、图遍历的演示。
【实验学时】5学时
【实验目的】
(1)掌握图的基本存储方法。
(2)熟练掌握图的两种搜索路径的遍历方法。
【问题描述】
很多涉及图上操作的算法都是以图的遍历操作为基础的。
试写一个程序,演示连通的无向图上,遍历全部结点的操作。
【基本要求】
以邻接多重表为存储结构,实现连通无向图的深度优先和广度优先遍历。
以用户指定的结点为起点,分别输出每种遍历下的结点访问序列和相应生成树的边集。
【测试数据】
教科书图7.33。
暂时忽略里程,起点为北京。
【实现提示】
设图的结点不超过30个,每个结点用一个编号表示(如果一个图有n个结点,则它们的编号分别为1,2,…,n)。
通过输入图的全部边输入一个图,每个边为一个数对,可以对边的输入顺序作出某种限制。
注意,生成树的边是有向边,端点顺序不能颠倒。
【选作内容】
(1)借助于栈类型(自己定义和实现),用非递归算法实现深度优先遍历。
(2)以邻接表为存储结构,建立深度优先生成树和广度优先生成树,再按凹入表或树形打印生成树。
(3)正如习题7。
8提示中分析的那样,图的路径遍历要比结点遍历具有更为广泛的应用。
再写一个路径遍历算法,求出从北京到广州中途不过郑州的所有简单路径及其里程。
【源程序】
#include
#include
#include
#defineMAX_VERTEX_NUM20
#defineSTACK_INIT_SIZE100
#defineSTACKINCREMENT10
#defineTRUE1
#defineOK1
#defineFALSE0
#defineERROR0
#defineOVERFLOW-2
typedefenum{DG,DN,UDG,UDN}GraphKind;//{有向图,有向网,无向图,无向网}
boolvisited[MAX_VERTEX_NUM];
typedefstructArcNode
{
intadjvex;//该弧所指向的顶点在数组中的下标
structArcNode*nextarc;
int*info;//该弧相关信息的指针
}ArcNode;
typedefstructVNode
{
intdata;//顶点信息
ArcNode*firstarc;//指向第一条依附该顶点的弧的指针
}VNode,AdjList[MAX_VERTEX_NUM];
typedefstruct
{
AdjListvertices;
intvexnum,arcnum;//图的当前顶点数和弧数
intkind;//图的种类标志
}ALGraph;
typedefstruct
{
int*base;
int*top;
intstacksize;
}SqStack;
typedefstructQNode
{
intdata;
structQNode*next;
}QNode,*QueuePtr;
typedefstruct
{
QueuePtrfront;
QueuePtrrear;
}LinkQueue;
intLocateVex(ALGraphG,intv)
{//返回数组下标值
inti;
for(i=0;i if(G.vertices[i].data==v)returni; return-1; } voidCreateDN(ALGraph&G) {//采用邻接表存储表示,构造有向图G(G.kind=DN) inti,j,k;ArcNode*p;intv1,v2; G.kind=DN; printf("输入顶点数: "); scanf("%d",&G.vexnum); printf("输入弧数: "); scanf("%d",&G.arcnum); printf("输入顶点: \n"); for(i=0;i {//构造表头向量 scanf("%d",&G.vertices[i].data); G.vertices[i].firstarc=NULL;//初始化指针 } for(k=0;k { printf("第%d条弧: ",k+1); scanf("%d",&v1); scanf("%d",&v2);//输入一条弧的始点和终点 i=LocateVex(G,v1);j=LocateVex(G,v2);//确定v1和v2在G中位置 p=(ArcNode*)malloc(sizeof(ArcNode));//假定有足够空间 p->adjvex=j;p->nextarc=G.vertices[i].firstarc; G.vertices[i].firstarc=p; scanf("%d",&p->info); }//for } intPush(SqStack&S,inte) {//插入元素e为新的栈顶元素 if(S.top-S.base>=S.stacksize) {//栈满,追加存储空间 S.base=(int*)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(int)); if(! S.base)exit(OVERFLOW);//存储分配失败 S.top=S.base+S.stacksize; S.stacksize+=STACKINCREMENT; } *S.top++=e; returnOK; } intInitStack(SqStack&S)//栈的初始化 { S.base=(int*)malloc(STACK_INIT_SIZE*sizeof(int)); if(! S.base)exit(OVERFLOW);//存储分配失败 S.top=S.base; S.stacksize=STACK_INIT_SIZE; returnOK; } intPop(SqStack&S,int&e)//删除栈顶元素 {//若栈不空,则删除S的栈顶元素,用e返回其值 if(S.top==S.base) returnERROR; e=*--S.top; returnOK; } intGetTop(SqStackS,int&e)//取栈顶元素 {//若栈不空,则用e返回S的栈顶元素 if(S.top==S.base) returnERROR; e=*(S.top-1); returnOK; } intStackEmpty(SqStackS)//栈空 { if(S.top==S.base) returnTRUE; else returnFALSE; } intInitQueue(LinkQueue&Q)//队列初始化 { Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode)); if(! Q.front)exit(OVERFLOW); Q.front->next=NULL; returnOK; } intEnQueue(LinkQueue&Q,inte)//插入 {//插入元素e为Q的新的队尾元素 QueuePtrp=(QueuePtr)malloc(sizeof(QNode)); if(! p)exit(OVERFLOW); p->data=e;p->next=NULL; Q.rear->next=p; Q.rear=p; returnOK; } intDeQueue(LinkQueue&Q,int&e) {//若队列不空,则删除Q的队头元素,用e返回其值 if(Q.front==Q.rear) returnERROR; QueuePtrp=Q.front->next; e=p->data; Q.front->next=p->next; if(Q.rear==p)Q.rear=Q.front; free(p); returnOK; } intQueueEmpty(LinkQueueQ)//队列空 { if(Q.front==Q.rear) returnTRUE; else returnFALSE; } intFirstAdjVex(ALGraphG,intu) { if(! G.vertices[u].firstarc) return-1; returnLocateVex(G,G.vertices[u].firstarc->adjvex); } intNextAdjVex(ALGraphG,intu,intw) { ArcNode*p=G.vertices[u].firstarc; while(p&&LocateVex(G,p->adjvex)! =w) p=p->nextarc; if(! p) returnFirstAdjVex(G,u); p=p->nextarc; if(! p) return-1; returnLocateVex(G,p->adjvex); } voidVisit(ALGraphG,intv) { printf("%2d",G.vertices[v].data); } voidDFSTraverse(ALGraphG) {//按深度优先非递归遍历图G,使用辅助栈S和访问标志数组visited intv,w;SqStackS; for(v=0;v visited[v]=FALSE; InitStack(S); for(v=0;v if(! visited[v]) {//v尚未被访问 visited[v]=TRUE; Visit(G,v); Push(S,v);//v进栈 while(! StackEmpty(S)) { for(w=FirstAdjVex(G,v);w>=0;w=NextAdjVex(G,v,w)) { if(! visited[w]) { Visit(G,w); visited[w]=TRUE; Push(S,w); GetTop(S,v); }//if }//for Pop(S,v); GetTop(S,v); }//while }//if printf("\n"); } voidBFSTraverse(ALGraphG) {//按广度优先非递归遍历图G,使用辅助队列Q和访问标志数组visited intv,u,w;LinkQueueQ; for(v=0;v visited[v]=FALSE; InitQueue(Q); for(v=0;v if(! visited[v]) {//v尚未被访问 visited[v]=TRUE; Visit(G,v); EnQueue(Q,v);//v入队列 while(! QueueEmpty(Q)) { DeQueue(Q,u);//队头元素出队并置为u for(w=FirstAdjVex(G,u);w>=0;w=NextAdjVex(G,u,w)) if(! visited[w]) {//w为u的尚未访问的邻接顶点 visited[w]=TRUE;Visit(G,w); EnQueue(Q,w); }//if }//while }//if printf("\n"); } voidPrintDN(ALGraphG)//图的显示 { inti;ArcNode*p; printf("顶点: \n"); for(i=0;i printf("%2d",G.vertices[i].data); printf("\n弧: \n"); for(i=0;i { p=G.vertices[i].firstarc; if(p) { while(p) { printf("%d→%d(%d)\t",i,p->adjvex,p->info); p=p->nextarc; } printf("\n"); }//if }//for } voidmain() { ALGraphG; printf("************题目: 图的遍历***************\n\n"); CreateDN(G); PrintDN(G); printf("深度优先遍历: "); DFSTraverse(G); printf("\n广度优先遍历: "); BFSTraverse(G); } 【运行结果】 实验五查找算法实现 【实验学时】5学时 【实验目的】 熟练掌握顺序查找、折半查找及二叉排序树、平衡二叉树上的查找、插入和删除的方法,比较它们的平均查找长度。 【问题描述】 查找表是数据处理的重要操作,试建立有100个结点的二叉排序树进行查找,然后用原数据建立AVL树,并比较两者的平均查找长度。 【基本要求】 (1)以链表作为存储结构,实现二叉排序树的建立、查找和删除。 (2)根据给定的数据建立平衡二叉树。 (3)比较二叉排序树和平衡二叉树的平均查找长度。 【测试数据】 随机生成。 【实现提示】 (1)初始,二叉排序树和平衡二叉树都为空树,操作界面给出查找、插入和删除三种操作供选择。 每种操作均要提示输入关键字。 每次插入或删除一个结点后,应更新平衡二叉树或二叉排序树的显示。 (2)平衡二叉树或二叉排序树的显示可以采用凹入表形式,也可以采用图形界面画出树形。 【源程序】 #include #include #include #defineEQ(a,b)((a)==(b)) #defineLT(a,b)((a)<(b)) #defineLQ(a,b)((a)>(b)) typedefintKeytype; typedefstruct {Keytypekey; }ElemType; typedefstructBSTnode {ElemTypedata; intbf; structBSTnode*lchild,*rchild; }BSTnode,*BSTree; voidInitBSTree(BSTree&T) {T=NULL; } voidR_Rotate(BSTree&p) {BSTnode*lc; lc=p->lchild; p->lchild=lc->rchild; lc->rchild=p; p=lc; } voidL_Rotate(BSTree&p) {BSTnode*rc; rc=p->rchild; p->rchild=rc->lchild; rc->lchild=p; p=rc; } voidLeftbalance(BSTree&T) {BSTnode*lc,*rd; lc=T->lchild; switch(lc->bf) { case+1: T->bf=lc->bf=0; R_Rotate(T); break; case-1: rd=lc->rchild; switch(rd->bf) {case1: T->bf=-1; lc->bf=0; break; case0: T->bf=lc->bf=0; break; case-1: T->bf=0; lc->bf=1; break; } rd->bf=0; L_Rotate(T->lchild); R_Rotate(T); } } voidRbalance(BSTree&T) {BSTnode*lc,*ld; lc=T->rchild; switch(lc->bf) {case1: ld=lc->lchild; switch(ld->bf) {case1: T->bf=0; lc->bf=-1; break; case0: T->bf=lc->bf=0; break; case-1: T->bf=1; lc->bf=0; break; } ld->bf=0; R_Rotate(T->rchild); L_Rotate(T); case-1: T->bf=lc->bf=0; L_Rotate(T); break; } } intInsertAVL(BSTree&T,ElemTypee,bool&taller) {if(! T) {T=(BSTree)malloc(sizeof(BSTnode)); T->data=e; T->lchild=T->rchild=NULL; T->bf=0; taller=true; } else {if(EQ(e.key,T->data.key)) {taller=false; cout<<"结点"< "< return0; } if(LT(e.key,T->data.key)) {if(! InsertAVL(T->lchild,e,taller)) {return0; } if(taller) switch(T->bf) {case1: Leftbalance(T); taller=false; break; case0: T->bf=+1; taller=true; break; case-1: T->bf=0; taller=false; break; } } else {if(! InsertAVL(T->rchild,e,taller)) {return0; } if(taller) switch(T->bf) {case1: T->bf=0; taller=false; break; case0: T->bf=-1; taller=true; break; case-1: Rbalance(T); taller=false; break; } } } return1; } boolSearchBST(BSTreeT,ElemTypekey,BSTreef,BSTree&p) {if(! T) {p=f; cout<<"结点不存在。 "< returnfalse; } elseif(EQ(key.key,T->data.key)) {p=T; cout<<"查找成功,存在结点"; cout< returntrue; } elseif(LT(key.key,T->data.key)) returnSearchBST(T->lchild,key,T,p); else returnSearchBST(T->rchild,key,T,p); } voidLeftbalance_div(BSTree&p,int&shorter) {BSTreep1,p2; if(p->bf==+1)//p结点的左子树高,删除结点后p的bf减1,树变矮 {p->bf=0; shorter=1; } elseif(p->bf==0)//p结点左、右子树等高,删除结点后p的bf减1,树高不变 {p->bf=-1; shorter=0; } else {p1=p->rchild;//p1指向p的右子树 if(p1->bf==0)//p1结点左、右子树等高,删除结点后p的bf为-2,进行左旋处理,树高不变 {L_Rotate(p); p1->bf=1; p->bf=-1; shorter=0; } elseif(p1->bf==-1)//p1的右子树高,左旋处理后,树变矮 {L_Rotate(p); p1->bf=p->bf=0; shorter=1; } else {p2=p1->lchild; p1->lchild=p2->rchild; p2->rchild=p1; p->rchild=p2->lchild; p2->lchild=p; if(p2->bf==0) {p->bf=0; p1->bf=0; } elseif(p2->bf==-1) {p->bf=+1; p1->bf=0; } else {p->bf=0; p1->bf=-1; } p2->bf=0; p=p2; shorter=1; } } } voidRbalance_div(BSTree&p,int&shorter) {BSTreep1,p2; if(p->bf==-1) {p->bf=0; shorter=1; } elseif(p->bf==0) {p->bf=+1; shorter=0; } else {p1=p->lchild; if(p1->bf==0) {R_Rotate(p); p1->bf=-1; p->bf=+1; shorter=0; } elseif(p1->bf==+1) {R_Rotate(p); p1->bf=p->bf=0; shorter=1; } else {p2=p1->rchild; p1->rchild=p2->lchild; p2->lchild=p1; p->lchild=p2->rchild; p2->rchild=p; if(p2->bf==0) {p->bf=0; p1->bf=0; } elseif(p2->bf==1) {p->bf=-1; p1->bf=0; } else {p->bf=0; p1->bf=1; } p2->bf=0;
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 实验 四五