关闭

图的邻接表创建以及遍历

930人阅读 评论(0) 收藏 举报
分类:


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

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;
	}
}



0
0

猜你在找
【直播】计算机视觉原理及实战—屈教授
【套餐】深度学习入门视频课程—唐宇迪
【套餐】Hadoop生态系统零基础入门--侯勇蛟
【套餐】嵌入式Linux C编程基础--朱有鹏
【套餐】2017软考系统集成项目——任铄
【套餐】Android 5.x顶级视频课程——李宁
【直播】广义线性模型及其应用——李科
【直播】从0到1 区块链的概念到实践
【直播】机器学习之凸优化——马博士
【套餐】微信订阅号+服务号Java版 v2.0--翟东平
查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:10491次
    • 积分:387
    • 等级:
    • 排名:千里之外
    • 原创:28篇
    • 转载:2篇
    • 译文:0篇
    • 评论:0条
    文章分类