图的邻接表创建以及遍历

原创 2013年12月03日 15:39:40


对于图的邻接表存储以及遍历,搞清思路是十分必要的。

1、首先搞清结构体。不同的处理问题的思路,对应着不同的结构体封装。下面
以我的处理方式为例为大家展示:
#define max_vertex_num 100 //该图可以为维护最大的结点个数。

typedef struct Arcnode
{
	int    adjvex;//该弧所指向的顶点的位置
	struct Arcnode  *nextarc;
	char   *info;
}Arcnode;

typedef struct Vnode
{
	char data;
	Arcnode *firstrac;//对于每一个邻接链表,这相当于是链表的头指针。
}Vnode,Adjlist[max_vertex_num];

typedef struct
{
	Adjlist vertices;
	int vexnum,arcnum;
	int kind;//1为有向图,0为无向图。
}Algrap;


看过我封装的结构体,相信大家已经很清楚的了解到,图、结点、弧之间存在一定的联系。也清楚了结构体中所具有的属性。
2、先引入几个函数以及实现。
int creatgrap(Algrap *map1);
创建图。对于每个节点的临接点所形成的链表采用头插法初始化,链表中储存的数据保存节点位置。
void  DFSTraverse(Algrap *G);
保证每个节点都会被遍历到,尽管该图不是连通图。遍历的顺序默认为从最大连通图中下表最小的开始。
void DFS(Algrap *G,int i);
图的递归遍历。
void printf(Algrap G);
把图的逻辑存储关系打印出来。

下面给出函数的实现:

//图的创建。
int creatgrap(Algrap *map1)
{
	int i,j;
	cout<<"请输入图的结点数以及弧的条数:";
	cin>>map1->vexnum>>map1->arcnum;
	cout<<"      请选择图的类型:        "<<endl;
	cout<<"      1  有向图               "<<endl;
	cout<<"      2  无向图               "<<endl;
	cout<<"      请输入选择的数字:      "<<endl;
	cin>>map1->kind;

	while(map1->kind!=1&&map1->kind!=2)
	{
	    cout<<"请重新输入选择数字,你输入的数字不合法!"<<endl;
		cin>>map1->kind;
	}

	for(i=0;i<map1->vexnum;i++)
	{
		cout<<"请输入节点数据:";
		cin>>map1->vertices[i].data;
		map1->vertices[i].firstrac=NULL;
	}


	for(i=0;i<map1->arcnum;i++)
	{
		char a,b;
		int temp1=0,temp2=0;
		cout<<"请输入两个有关系的节点:";  
		cin>>a>>b;

		for(j=0;j<map1->vexnum;j++)
		{
			if(map1->vertices[j].data==a)
				temp1=j;
			if(map1->vertices[j].data==b)
				temp2=j;
		}

		Arcnode *p,*q;

		p=(Arcnode*)malloc(sizeof(Arcnode));
		p->adjvex=temp2;
		p->nextarc=map1->vertices[temp1].firstrac;//插入表头.采用头插法,先进的弧、遍历后出。后进的弧、遍历先出。
		map1->vertices[temp1].firstrac=p;
		if(map1->kind==2)
		{
			q=(Arcnode*)malloc(sizeof(Arcnode));
			q->adjvex=temp1;
			q->nextarc=map1->vertices[temp2].firstrac;
			map1->vertices[temp2].firstrac=q;
		}
	}
	return 0;
}

void  DFSTraverse(Algrap *G)//保证每个节点都会被遍历到,尽管该图不是连通图。遍历的顺序默认为从最大连通图中下标最小的开始。
{
   int i;
   for(i=0;i<G->vexnum;i++)
			visited[i]=false;
   for(i=0;i<G->vexnum;i++)
	   if(!visited[i])
		   DFS(G,i);
}

void DFS(Algrap *G,int i)
{
	Arcnode *p=NULL;
	printf("访问顶点;%c\n",G->vertices[i].data);
	visited[i]=true;
	p=G->vertices[i].firstrac;
	while(p)
	{
		if(!visited[p->adjvex])
			DFS(G,p->adjvex);
		p=p->nextarc;
	}
}

void printf(Algrap G)
{
    int i;
	Arcnode *p;
	cout<<"下面把图的逻辑存储打印出来:"<<endl;
	for(i=0;i<G.vexnum;i++)
	{
		cout<<G.vertices[i].data;
		p=G.vertices[i].firstrac;
		while(p)
		{
			cout<<"->"<<p->adjvex;
			p=p->nextarc;
		}
		cout<<endl;
	}
}

下面给出完整的程序:
// 邻接表图的建立与遍历.cpp : 定义控制台应用程序的入口点。
#include "stdafx.h"
#include<cstdlib>
#include<cstdio>
#include<iostream>
using namespace std;

bool visited[100];

#define max_vertex_num 100 //该图可以为维护最大的结点个数。

typedef struct Arcnode
{
	int    adjvex;//该弧所指向的顶点的位置
	struct Arcnode  *nextarc;
	char   *info;
}Arcnode;

typedef struct Vnode
{
	char data;
	Arcnode *firstrac;//对于每一个邻接链表,这相当于是链表的头指针。
}Vnode,Adjlist[max_vertex_num];

typedef struct
{
	Adjlist vertices;
	int vexnum,arcnum;
	int kind;//1为有向图,2为无向图。
}Algrap;

int creatgrap(Algrap *map1);
void  DFSTraverse(Algrap *G);
void DFS(Algrap *G,int i);
void printf(Algrap G);

int main()
{
	Algrap *map=(Algrap* )malloc(sizeof(Algrap));
	creatgrap(map);
	printf(*map);
	DFSTraverse(map);
	return 0;
}


//图的创建。
int creatgrap(Algrap *map1)
{
	int i,j;
	cout<<"请输入图的结点数以及弧的条数:";
	cin>>map1->vexnum>>map1->arcnum;
	cout<<"      请选择图的类型:        "<<endl;
	cout<<"      1  有向图               "<<endl;
	cout<<"      2  无向图               "<<endl;
	cout<<"      请输入选择的数字:      "<<endl;
	cin>>map1->kind;

	while(map1->kind!=1&&map1->kind!=2)
	{
	    cout<<"请重新输入选择数字,你输入的数字不合法!"<<endl;
		cin>>map1->kind;
	}

	for(i=0;i<map1->vexnum;i++)
	{
		cout<<"请输入节点数据:";
		cin>>map1->vertices[i].data;
		map1->vertices[i].firstrac=NULL;
	}


	for(i=0;i<map1->arcnum;i++)
	{
		char a,b;
		int temp1=0,temp2=0;
		cout<<"请输入两个有关系的节点:";  
		cin>>a>>b;

		for(j=0;j<map1->vexnum;j++)
		{
			if(map1->vertices[j].data==a)
				temp1=j;
			if(map1->vertices[j].data==b)
				temp2=j;
		}

		Arcnode *p,*q;

		p=(Arcnode*)malloc(sizeof(Arcnode));
		p->adjvex=temp2;
		p->nextarc=map1->vertices[temp1].firstrac;//插入表头.采用头插法,先进的弧、遍历后出。后进的弧、遍历先出。
		map1->vertices[temp1].firstrac=p;
		if(map1->kind==2)
		{
			q=(Arcnode*)malloc(sizeof(Arcnode));
			q->adjvex=temp1;
			q->nextarc=map1->vertices[temp2].firstrac;
			map1->vertices[temp2].firstrac=q;
		}
	}
	return 0;
}

void  DFSTraverse(Algrap *G)//保证每个节点都会被遍历到,尽管该图不是连通图。遍历的顺序默认为从最大连通图中下表最小的开始。
{
   int i;
   for(i=0;i<G->vexnum;i++)
			visited[i]=false;
   for(i=0;i<G->vexnum;i++)
	   if(!visited[i])
		   DFS(G,i);
}

void DFS(Algrap *G,int i)
{
	Arcnode *p=NULL;
	printf("访问顶点;%c\n",G->vertices[i].data);
	visited[i]=true;
	p=G->vertices[i].firstrac;
	while(p)
	{
		if(!visited[p->adjvex])
			DFS(G,p->adjvex);
		p=p->nextarc;
	}
}

void printf(Algrap G)
{
    int i;
	Arcnode *p;
	cout<<"下面把图的逻辑存储打印出来:"<<endl;
	for(i=0;i<G.vexnum;i++)
	{
		cout<<G.vertices[i].data;
		p=G.vertices[i].firstrac;
		while(p)
		{
			cout<<"->"<<p->adjvex;
			p=p->nextarc;
		}
		cout<<endl;
	}
}



相关文章推荐

图的遍历 - 数据结构

概述 图的遍历是指从图中的任一顶点出发,对图中的所有顶点访问一次且只访问一次。图的遍历操作和树的遍历操作功能相似。图的遍历是图的一种基本操作,图的其它算法如求解图的连通性问题,拓扑排序,求关键路...
  • hguisu
  • hguisu
  • 2012年07月04日 17:19
  • 22403

图---邻接表(建立,深度遍历,广度遍历)

图的邻接表表示法类似于树的孩子链表表示法。对于图G中的每个顶点vi,该方法把所有邻接于vi的顶点vj链成一个带头结点的单链表,这个单链表就称为顶点vi的邻接表(Adjacency List)。以下代码...
  • akof1314
  • akof1314
  • 2009年07月28日 21:50
  • 35988

实验十二 图的建立与遍历

Description 按邻接矩阵的方法创建图,分别用深度优先和广度优先方法遍历图。 Input 输入的数据有多组 对于每组测试数据第一行为图中点的个数n(0 接下来有m行,每行两个整数a...

图的邻接表和DFS遍历

邻接矩阵和邻接表的对比之前一篇文章我们学习了 图的邻接矩阵和DFS遍历, 邻接矩阵对于图来说是一种很不错的存储结构,但是也有特殊的情况,例如边数很少的时候。此时的邻接矩阵,只有(v0,v1)和(v1,...
  • jeffleo
  • jeffleo
  • 2016年11月24日 21:52
  • 1305

邻接表实现图的储存,遍历

邻接表是图的一种链式存储结构。对图的每个顶点建立一个单链表(n个顶点建立n个单链表),第i个单链表中的结点包含顶点Vi的所有邻接顶点。又称链接表。 1.在有向图的邻接表中不易找到指向该顶点的弧。...

邻接表 实现图的遍历 C++

#include #include using namespace std; const int MaxSize = 5; struct ArcNode //边表节点 { int adj...

图的结构定义及遍历方法

一、图的存储结构 1.1 邻接矩阵     图的邻接矩阵存储方式是用两个数组来表示图。一个一维数组存储图中顶点信息,一个二维数组(邻接矩阵)存储图中的边或弧的信息。     设图...

图的遍历

概述     遍历分为深度优先遍历和广度优先遍历,其对有向图和无向图都适用。深度优先,顾名思义,就是只要存在后续节点就一直往下走,直到没有后续节点或者后续节点已经被访问输出了;广度优先,就是节点一层...
  • cqnuztq
  • cqnuztq
  • 2013年05月21日 16:48
  • 18488

数据结构:图的存储结构之邻接表

对于图来说,邻接矩阵是不错的一种图存储结构,但是我们也发现,对于边数相对顶点较少的图,这种结构是存在对存储空间的极大浪费的。因此我们考虑另外一种存储结构方式:邻接表(Adjacency List),即...

邻接表创建图

邻接表:        当图中的边或弧数量远远小于图中的顶点数时,即为稀疏图时,邻接矩阵就成为稀疏矩阵,因此采用邻接表存储会避免造成空间浪费。        邻接表是图的链式存储,它克服了邻接矩阵...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:图的邻接表创建以及遍历
举报原因:
原因补充:

(最多只允许输入30个字)