/<span style="font-size:18px;">/1.邻接矩阵实现</span>
</pre><pre code_snippet_id="693878" snippet_file_name="blog_20150613_1_2994608" name="code" class="cpp">#include<iostream>
using namespace std;
#define MAX_VEX_NUM 50
typedef char VertexType;
typedef enum{
UDG,DG
}GraphType;
typedef struct Graph
{
VertexType name[MAX_VEX_NUM];
int adjMatrix[MAX_VEX_NUM][MAX_VEX_NUM];
int vnum;
int linenum;
GraphType type;
}*MyGraph,G;
int isVisited[MAX_VEX_NUM];
int indexofv(MyGraph &g,VertexType c )
{
for(int i=1;i<=g->vnum;i++)
{
if(g->name[i]==c)
return i;
}
}
void createGraph(G *g)
{
int type;
VertexType c1,c2;
int v1,v2;
cout<<"请输入顶点数量"<<endl;
cin>>g->vnum;
cout<<"请输入边数"<<endl;
cin>>g->linenum;
cout<<"请输入图的类型,0代表无向图,1代表有向图"<<endl;
cin>>type;
if(type==1)
{
g->type=DG;
}else if(type==0)
{
g->type=UDG;
}else
{
cout<<"输入类型不正确"<<endl;
return;
}
//初始化邻接矩阵
for(int i=1;i<=g->vnum;i++)
{
for(int j=1;j<=g->vnum;j++)
{
g->adjMatrix[i][j]=0;
}
}
//输入顶点的名称
cout<<"请输入顶点"<<endl;
for(int i=1;i<=g->vnum;i++)
{
cin>>g->name[i];
}
//请输入由哪两个顶点组成边
cout<<"请输入组成顶点的边"<<endl;
//如果为无向图
if(g->type==UDG)
{
for(int i=1;i<=g->linenum;i++)
{
cin>>c1;
cin>>c2;
v1=indexofv(g,c1);
v2=indexofv(g,c2);
g->adjMatrix[v1][v2]=1;
g->adjMatrix[v2][v1]=1;
}
}
else
{
for(int i=1;i<=g->linenum;i++)
{
cin>>c1;
cin>>c2;
v1=indexofv(g,c1);
v2=indexofv(g,c2);
g->adjMatrix[v1][v2]=1;
//g->adjMatrix[v2][v1]=1;
}
}
cout<<"邻接矩阵如下"<<endl;
for(int i=1;i<=g->vnum;i++)
{
int count=0;
for(int j=1;j<=g->vnum;j++)
{
count++;
cout<<g->adjMatrix[i][j]<<" ";
if(count==g->vnum)
cout<<endl;
}
}
cout<<"顶点信息如下:"<<endl;
for(int i=1;i<=g->vnum;i++)
{
cout<<g->name[i]<<"";
}
cout<<endl;
}
//isVisited[MAX_VEX_NUM]
void initVisit(){
for(int i=1;i<=MAX_VEX_NUM;i++)
{
isVisited[i]=0;
}
}
void DFSTraverse(G *g,int i)
{
cout<<"DFS遍历结果为如下"<<endl;
isVisited[i]=1;
cout<<g->name[i]<<"";
for(int j=1;j<=g->vnum;j++)
{
if(isVisited[j]==0&&g->adjMatrix[i][j]==1)
<pre code_snippet_id="693878" snippet_file_name="blog_20150613_1_2994608" name="code" class="cpp"><span style="white-space:pre"> </span>DFSTraverse(g,j);<pre code_snippet_id="693878" snippet_file_name="blog_20150613_1_2994608" name="code" class="cpp">
}cout<<endl;}void main(){G g;createGraph(&g);DFSTraverse(&g,2);system(“pause”);//DFSTranverse(g);}
//邻接表实现
#include <stdio.h>
#include <stdlib.h>
#include <stdio.h>
#define MAX_VERTEX_NUM 50
typedef enum {
DG, UDG
} GraphType;
typedef char VertexType;
//表节点
typedef struct ArcNode {
int adjvex; //邻接节点
int weight; //边权重
struct ArcNode *nextarc; //下一个节点指针
} ArcNode, *ArcPtr;
//头节点
typedef struct {
VertexType vexdata;
int id;
ArcPtr firstarc;
} VNode;
//头节点数组
typedef struct {
VNode vertices[MAX_VERTEX_NUM];
int vexnum, arcnum;
GraphType type;
} ALGraph;
int visit[MAX_VERTEX_NUM];
/**
* 根据顶点字符得到在顶点数组中的下标
*/
int getIndexOfVexs(char vex, ALGraph *AG) {
int i;
for (i = 1; i <= AG->vexnum; i++) {
if (AG->vertices[i].vexdata == vex) {
return i;
}
}
return 0;
}
/**
* 创建邻接表
*/
void create_AG(ALGraph *AG) {
ArcPtr p,q;
int i, j, k, type;
VertexType v1, v2;
printf("Please input graph type UG(0) or UDG(1) :");
scanf("%d", &type);
if (type == 0)
AG->type = DG;
else if (type == 1)
AG->type = UDG;
else {
printf("Please input correct graph type UG(0) or UDG(1)!");
return;
}
printf("please input vexnum:");
scanf("%d", &AG->vexnum);
printf("please input arcnum:");
scanf("%d", &AG->arcnum);
getchar();
for (i = 1; i <= AG->vexnum; i++) {
printf("please input the %dth vex(char) : ", i);
scanf("%c", &AG->vertices[i].vexdata);
getchar();
AG->vertices[i].firstarc = NULL;
}
for (k = 1; k <= AG->arcnum; k++) {
printf("please input the %dth arc v1(char) v2(char) :", k);
scanf("%c %c", &v1, &v2);
i = getIndexOfVexs(v1, AG);
j = getIndexOfVexs(v2, AG);
//根据图的类型创建邻接表
//方法1,插入到链表头
/*
if (AG->type == DG) { //有向图
p = (ArcPtr) malloc(sizeof(ArcNode));
p->adjvex = j;
p->nextarc = AG->vertices[i].firstarc;
AG->vertices[i].firstarc = p;
} else { //无向图
p = (ArcPtr) malloc(sizeof(ArcNode));
p->adjvex = j;
p->nextarc = AG->vertices[i].firstarc;
AG->vertices[i].firstarc = p;
p = (ArcPtr) malloc(sizeof(ArcNode));
p->adjvex = i;
p->nextarc = AG->vertices[j].firstarc;
AG->vertices[j].firstarc = p;
}
*/
//方法2,插入到链表尾
if (AG->type == DG) { //有向图
p = (ArcPtr) malloc(sizeof(ArcNode));
p->adjvex = j;
//表为空
if(AG->vertices[i].firstarc == NULL){
AG->vertices[i].firstarc = p;
}
else{
//找最后一个表节点
q = AG->vertices[i].firstarc;
while(q->nextarc != NULL){
q = q->nextarc;
}
q->nextarc = p;
}
p->nextarc = NULL;
} else { //无向图
p = (ArcPtr) malloc(sizeof(ArcNode));
p->adjvex = j;
//表为空
if(AG->vertices[i].firstarc == NULL){
AG->vertices[i].firstarc = p;
}
else{
//找最后一个表节点
q = AG->vertices[i].firstarc;
while(q->nextarc != NULL){
q = q->nextarc;
}
q->nextarc = p;
}
p->nextarc = NULL;
p = (ArcPtr) malloc(sizeof(ArcNode));
p->adjvex = i;
//表为空
if(AG->vertices[j].firstarc == NULL){
AG->vertices[j].firstarc = p;
}
else{
//找最后一个表节点
q = AG->vertices[j].firstarc;
while(q->nextarc != NULL){
q = q->nextarc;
}
q->nextarc = p;
}
p->nextarc = NULL;
}
getchar();
}
}
/**
* 输出图的相关信息
*/
void print_AG(ALGraph AG) {
ArcPtr p;
int i;
if (AG.type == DG) {
printf("Graph type: Direct graph\n");
} else {
printf("Graph type: Undirect graph\n");
}
printf("Graph vertex number: %d\n", AG.vexnum);
printf("Graph arc number: %d\n", AG.arcnum);
printf("Vertex set :\n");
for (i = 1; i <= AG.vexnum; i++)
printf("%c\t", AG.vertices[i].vexdata);
printf("\nAdjacency List:\n");
for (i = 1; i <= AG.vexnum; i++) {
printf("%d", i);
p = AG.vertices[i].firstarc;
while (p != NULL) {
printf("-->%d", p->adjvex);
p = p->nextarc;
}
printf("\n");
}
}
/**
* 初始化顶点访问标志
**/
void init_Visit(){
int i;
for(i = 0;i < MAX_VERTEX_NUM;i++)
visit[i] = 0;
}
/**
* 深度遍历图
**/
void DFS_AG(ALGraph AG,int i){
ArcPtr p;
printf("%c\t",AG.vertices[i].vexdata);
visit[i] = 1;
p = AG.vertices[i].firstarc;
while( p!= NULL ){
if(visit[p->adjvex] == 0)
DFS_AG(AG,p->adjvex);
p = p->nextarc;
}
}
int main(void) {
ALGraph AG;
create_AG(&AG);
print_AG(AG);
printf("The result of DFS:\n");
DFS_AG(AG,1);
system("pause");
return EXIT_SUCCESS;
}
算法说明:
对于具有n个顶点,e条边的连通图,算法DFS_MG,DFS_AG 均调用n次。除了初始调用是来自外部,基于n-1次调用均是来自DFS_MG和DFS_AG内部的递归调用,用邻接矩阵实现时,遍历一个顶点的所有邻接点需要O(n)时间,则遍历整个图需要O(n^2),即DFS_MG的时间复杂度为O(n^2)。
用邻接表实现时,遍历n个顶点的所有邻接点是对边表节点的扫描一遍,故算法DFS_AG时间复杂度为O(n+e)。
采用深度优先遍历算法时,都要用到访问标志,所以该算法的空间复杂度为O(n).