无向图邻接多重链表实现与创建算法详解

版权申诉
0 下载量 58 浏览量 更新于2024-07-07 收藏 662KB DOCX 举报
"本篇文章是蛤蟆的数据结构笔记,主要探讨图的邻接多重链表表示实现。邻接多重表(AdjacencyMultilist)是一种常用的数据结构,特别适用于无向图的存储,因为它解决了无向图中每条边双向关联的问题。相比于邻接表,邻接多重表在处理无向图时更加高效,特别是涉及到查找、标记或删除重复边的操作。 邻接多重表的存储结构类似于十字链表,由顶点表和边表构成。顶点表中的每个结点包含两个域:vertex用于存储顶点的相关信息,firstedge则指示与该顶点相连的第一条边。边表结点则有六个域,包括mark标记域用于标记边是否被搜索过,ivex和jvex分别记录边依附的两个顶点的索引,以及ilink和jlink分别指向下一条依附于ivex和jvex顶点的边,info域则存放与边相关的额外信息。 在邻接多重表中,同一顶点的所有边都被组织成一个链表,且每条边的两个端点在它们各自所属的链表中都有对应的边结点。这样设计使得图的操作更加直观和高效。例如,创建无向图G时,函数creategraph首先打开cmnet.txt文件,读取顶点数和边数,接着为每个顶点分配节点并初始化第一条边为NULL,然后逐条读取边的信息,创建边表节点并将其插入到对应顶点的链表头部。整个过程确保了无向图的正确构建。 文章还提到,邻接多重表对于处理无向图的遍历、搜索和边的增删操作非常适用,体现了“一个人的价值在于他所做出的贡献”这一理念,即在实际问题中选择合适的数据结构能够提高算法的效率,从而实现更大的价值。通过这篇笔记,读者可以深入了解邻接多重链表的实现原理及其在无向图处理中的应用。"
2010-06-15 上传
这是我的作业。。。。希望对各位有#include <stdio.h> #include <malloc.h> #include <stdlib.h> #define SIZE (xsize*ysize+1) //一系列全局变量便于传递参数 int *location,*way, xsize,ysize,firstx,firsty, noworder; int getnum (void);//取数函数,取数成功返回1,否则返回-1 int init (void); //初始化函数,申请数组空间,以及初始化数组, //申请成功返回1,否则返回-1 int play (void); //下棋函数,下棋成功返回1,否则返回-1 int back (void); //悔棋函数,悔棋成功返回1,否则返回-1 void print (void);//输出函数,顺序输出马踩的棋盘一维坐标 //////////////////////////// void main () { int canget,caninit,canplay,canback; do canget=getnum(); while(canget==-1); caninit=init(); if(caninit==-1) exit (0);//终止程序运行 for (;noworder<SIZE-1;) { if(way[location[noworder]]>0 && way[location[noworder]]<=8) { canplay=play(); if(canplay==-1) way[location[noworder]]++;//当前方法不可行,改变方法 } else { canback=back(); if(canback==-1) { printf("不可能遍历整个棋盘!\n"); getchar();getchar(); exit (0);//当程序不能再悔棋时终止程序运行 } else way[location[noworder]]++; //当前方法不可行,改变方法 } } if(noworder==SIZE-1)//已经遍历整个棋盘 print(); getchar();getchar(); } //////////////////////////// int getnum() { printf("输入棋盘规格(假定无0点)和入口坐标:\n"); printf("输入棋盘规格xsize="); scanf("%d",&xsize); printf("输入棋盘规格ysize="); scanf("%d",&ysize); printf("输入入口坐标x="); scanf("%d",&firstx); printf("输入入口坐标y="); scanf("%d",&firsty); if (firstx>xsize || firsty>ysize || firstx<=0 || firsty<=0 || xsize <3 || ysize<3) { printf("输入有误,重新输入:\n\n\a"); return -1; } else return 1; } //////////////////////////// int init (void) { location=(int *)malloc(sizeof(int)*SIZE); way=(int *)malloc(sizeof(int)*SIZE); if(location==NULL || way==NULL) { printf("系统申请内存空间失败!程序执行终止!\a"); return -1; } for(int i=0;i<SIZE;i++)//初始化数组 { way[i]=0; location[i]=0; } noworder=1; location[1]=(firsty-1)*xsize+firstx; way[location[1]]=1; return 1; } //////////////////////////// void print(void) { printf("\n\n可以遍历,顺序如下:\n\n"); for (int i=1;i<SIZE;i++) { printf("%3d-->",location[i]); printf("OK\n"); } } //////////////////////////// int play() { int x,y,nextlocation; //一维坐标值à二维坐标值 x=location[noworder] % xsize; if(x==0) x=xsize; y=(location[noworder]-x)/xsize+1; switch (way[location[noworder]]) { case 1 : x+=2;y-=1;break; case 2 : x+=2;y+=1;break; case 3 : x+=1;y+=2;break; case 4 : x-=1;y+=2;break; case 5 : x-=2;y+=1;break; case 6 : x-=2;y-=1;break; case 7 : x-=1;y-=2;break; case 8 : x+=1;y-=2;break; } nextlocation = xsize*(y-1)+x; if (x>xsize || y>ysize || x<=0 || y<=0 || way[nextlocation]!=0)//越界或重复 return -1; else//下棋 { noworder++; location[noworder] = nextlocation; way[location[noworder]]=1; return 1; } } //////////////////////////// int back (void) { if(noworder==1)//不能再悔棋,不能遍历 return -1; else { way[location[noworder]]=0;//注意不能搞错语句顺序 location[noworder]=0; noworder--; return 1; } }用