【数据结构-图】判断图是否有环

1.首先判断无向图

方法:1首先求出每个顶点的度

            2将图中顶点度<=1的顶点放入队列中

            3.将队列中的点x出列,然后删除其他顶点中与x有关联的顶点的这个边,并且将度数减一;将这个顶点从adjlist线性表中删除

           4.重复2

            5.当队列中元素都出来后,如果adjlist不为0,就说明有环,否则没有环。

代码:

 #include
using namespace std;
typedef int VexType;
typedef struct Arcnode{
VexType data;
struct Arcnode *nextarc;
}ArcNode;
typedef struct Vexnode
{
VexType data;
    ArcNode *firstarc;
}Vnode,AdjList[100]; 
typedef struct Graph
{
AdjList adjlist;
int vexnum;
int arcnum;
}*MGraph,Graph;
MGraph Create_Graph()
{
MGraph mygraph =new Graph;
int key;
int i;
int m;
int x,y,z;
printf("图一共有多少个顶点?\n");
scanf("%d",&x);
mygraph->vexnum=x;
printf("图一共有多少个边?\n");
scanf("%d",&y);
mygraph->arcnum=y;
printf("请输入每个顶点\n");
for(i=1;i<=mygraph->vexnum;i++)
{
scanf("%d",&z);
   mygraph->adjlist[i].data=z;
}
for(i=1;i<=mygraph->vexnum;i++)
{
printf("%d有没有相关连的顶点?有输入1,没有输入0\n",mygraph->adjlist[i].data);
scanf("%d",&key);
if(key)
{
   printf("请输入与%d相关联的顶点,以-123结束\n",mygraph->adjlist[i].data);
            scanf("%d",&m);
ArcNode *p=new ArcNode;
p->data=m;
p->nextarc=NULL;
mygraph->adjlist[i].firstarc=p;
printf("请输入与%d相关联的顶点,以-123结束\n",mygraph->adjlist[i].data);
            scanf("%d",&m);
while(m!=-123)
{
               ArcNode *q=new ArcNode;
  q->data=m;
  p->nextarc=q;
  p=q; 
  printf("请输入与%d相关联的顶点,以-123结束\n",mygraph->adjlist[i].data);
               scanf("%d",&m);
}
p->nextarc=NULL;
}
if(!key)
{
mygraph->adjlist[i].firstarc=NULL;
}
//printf("完成了第%d个节点\n",i);
}
printf("done\n");
return mygraph;
}
void isCycle(MGraph root)
{
MGraph mygraph=root;
int i;
int *dushu=new int;//每个顶点的度
for(i=1;i<=mygraph->vexnum;i++)
{
dushu[i]=0;
}
ArcNode *p=new ArcNode;
ArcNode *prior=new ArcNode;
for(i=1;i<=mygraph->vexnum;i++)
{
if(mygraph->adjlist[i].firstarc!=NULL)
{
 p=mygraph->adjlist[i].firstarc;
 while(p->nextarc!=NULL)
 {
dushu[i]++;
p=p->nextarc;
 }
 dushu[i]++;//因为邻接表中最后一个元素的nextarc为NULL,但是也需要加入这个顶点。
}
//否则这个顶点的度数为0,前面memset都设置为0.
}//所有顶点的度数都求出来了。
int *Q=new int;
int rear=1;
int front=1;
int k,w;
for(i=1;i<=mygraph->vexnum;i++)
{
if(dushu[i]<=1)
Q[rear++]=i;//把度数<=1的结点都放入队列中
}
while(front!=rear)
{
int t=Q[front++];
  if(dushu[t]==1)
{
  for(k=1;k<=mygraph->vexnum;k++)//删除其他顶点上与i有关联的边
  { 
  if(k!=t)
  {
  p=mygraph->adjlist[k].firstarc;
  while(p->nextarc!=NULL)
  {
  if(p->data!=mygraph->adjlist[i].data)
  {
  prior=p;
  p=p->nextarc;
  }
  else
  {
  if(p==mygraph->adjlist[k].firstarc)
  {
   prior=p;
  }
  prior->nextarc=p->nextarc;
  delete p;
  dushu[k]--;
  if(dushu[k]<=1)
  Q[rear++]=i;
  break;
  }
  }//while
  }
 
  }//for
  for(w=t+1;w<=mygraph->vexnum;w++)
  mygraph->adjlist[w-1].data=mygraph->adjlist[w].data;//把t这个元素从线性表中删除
  mygraph->vexnum--;
}
  if(dushu[t]==0)
  {
   for(w=t+1;w<=mygraph->vexnum;w++)
  mygraph->adjlist[w-1].data=mygraph->adjlist[w].data;//把t这个元素从线性表中删除
  mygraph->vexnum--;
  }
}
if((rear-1)==mygraph->vexnum)
printf("无环\n");
else
printf("有环\n");
}

void prints(MGraph root)
{
MGraph mygraph=root;
int i;
ArcNode *q;
printf("这个图的邻接表表示为:\n");
for(i=1;i<=mygraph->vexnum;i++)
{
printf("%d:",mygraph->adjlist[i].data);
q=mygraph->adjlist[i].firstarc;
if(q)
{
while(q->nextarc!=NULL)
{
printf("%d,",q->data);
q=q->nextarc;
}
printf("%d",q->data);
}
printf("\n");
}
}

int main(void)
{
MGraph mygraph;
mygraph=Create_Graph();
prints(mygraph);
isCycle(mygraph);
return 0;
}


你可能感兴趣的:(数据结构)