邻接表的深度优先遍历算法(非递归)

z_songlin 2013-11-16 09:02:24
求大神给个邻接表的深度优先遍历算法(非递归)。。。写了很久还是写不出。。

在下面代码的基础上写个
void DFS(ListGraph* LGraph, int InitVertex)
//LGraph :邻接表
//InitVertex:遍历起始点

#include<iostream>
using namespace std;

#define MAX_VERTEX 6
#define INF INT_MAX //INF表示正无穷
typedef int VertexInfo; //顶点其它信息
typedef int EdgeInfo; //边其它信息

struct Vertex //顶点类型
{
int No; //顶点编号
VertexInfo VerInfo; //顶点其它信息
};

struct MatrixGraph //邻接矩阵图类型
{
int Edges[MAX_VERTEX][MAX_VERTEX]; //邻接矩阵的边数组
Vertex Vertex[MAX_VERTEX]; //顶点数组
int VertexCount; //顶点数
int EdgeCount; //边数
};

struct ArcNode //边节点类型
{
int AdjoinVertex; //该边的邻接点编号
EdgeInfo EdgeInfo; //边其它信息
ArcNode* pNextArc; //指向下一条边
};

struct VertexNode //邻接表表头数组节点
{
Vertex data; //顶点信息
ArcNode* FirstArc; //指向第一条边
};

typedef VertexNode AdjoinList[MAX_VERTEX]; //邻接表类型

struct ListGraph //邻接表图类型
{
AdjoinList AdjList; //邻接表
int VertexCount; //顶点数
int EdgeCount; //边数
};

//创建邻接矩阵
//mg: 指向邻接矩阵的指针
//arr: 用于创建邻接的二维数组
//VertexCount: 顶点数
//EdgeCount: 边数
void CreateMatirxGraph(MatrixGraph* &mg, int arr[MAX_VERTEX][MAX_VERTEX], int VertexCount, int EdgeCount)
{
for (int i = 0; i < MAX_VERTEX; i++)
{
mg->Vertex[i].No = i; //顶点编号为0~MAX_VERTEX-1
mg->Vertex[i].VerInfo = NULL; //顶点无其它信息

for (int j = 0; j < MAX_VERTEX; j++)
{
mg->Edges[i][j] = arr[i][j];
}
}
mg->VertexCount = VertexCount; //顶点数
mg->EdgeCount = VertexCount; //边数
}

//输出邻接矩阵
void DisplayMatirxGraph(const MatrixGraph* mg)
{
if (NULL == mg)
return;
for (int i = 0; i < mg->VertexCount; i++)
{
for (int j = 0; j < mg->VertexCount; j++)
{
if (mg->Edges[i][j] == INF)
cout << "∞" << " ";
else
cout << mg->Edges[i][j] << " ";
}
cout << endl;
}
}

//邻接矩阵转邻接表
void CreateListGraph(const MatrixGraph* MGraph, ListGraph* &LGraph)
{
ArcNode* pNew = NULL;
for (int i = 0; i < MGraph->EdgeCount; i++)
{
LGraph->AdjList[i].FirstArc = NULL;
}

for (int i = 0; i < MGraph->VertexCount; i++)
{
for (int j = MGraph->VertexCount - 1; j >= 0; j--)
{
if (MGraph->Edges[i][j] != 0 && MGraph->Edges[i][j] != INF) //如果顶点i与顶点j关联
{
pNew = new ArcNode;
pNew->AdjoinVertex = j;
pNew->EdgeInfo = MGraph->Edges[i][j]; //EdgeInfo存储该边的权重
LGraph->AdjList[i].data.No = i; //顶点编号
LGraph->AdjList[i].data.VerInfo = NULL; //该顶点无其它信息

//采用头插法创建每一条链表
pNew->pNextArc = LGraph->AdjList[i].FirstArc;
LGraph->AdjList[i].FirstArc = pNew;
}
}
}
LGraph->EdgeCount = MGraph->EdgeCount; //边数
LGraph->VertexCount = MGraph->VertexCount; //顶点数
}

//输出邻接表
void DisplayListGraph(const ListGraph* LGraph)
{
ArcNode* pCurr = NULL;
for (int i = 0; i < LGraph->EdgeCount; i++)
{
pCurr = LGraph->AdjList[i].FirstArc;
cout << LGraph->AdjList[i].data.No << " -> ";
while (NULL != pCurr->pNextArc)
{
cout << pCurr->AdjoinVertex << " -> ";
pCurr = pCurr->pNextArc;
}
cout << pCurr->AdjoinVertex << endl;
}
}


int main()
{
int WeightArr[MAX_VERTEX][MAX_VERTEX] =
{
{ 0, 5, INF, 7, INF, INF },
{ INF, 0, 4, INF, INF, INF },
{ 8, INF, 0, INF, INF, 9 },
{ INF, INF, 5, 0, INF, 6 },
{ INF, INF, INF, 5, 0, INF },
{ 3, INF, INF, INF, 1, 0 },
};
MatrixGraph* MGraph = new MatrixGraph;
CreateMatirxGraph(MGraph, WeightArr, 6, 10);
ListGraph* LGraph = new ListGraph;
CreateListGraph(MGraph, LGraph); //创建邻接表

DisplayListGraph(LGraph);
cout << endl;

system("pause");
return 0;
}
...全文
2138 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
qq_32591305 2015-11-05
  • 打赏
  • 举报
回复
求解。。这个代码的深度优先遍历输出不了
#include<stdio.h> #include<malloc.h> #define MAXVEX 100 #define MAXSIZE 100 #define INF 32767 typedef char VertexType[10]; typedef struct vertex { int adjvex; VertexType data; }VType; typedef struct graph { int n,e; VType vexs[MAXVEX]; int edges[MAXVEX][MAXVEX]; }MatGraph; typedef struct edgenode { int adjvex; int weight; struct edgenode*nextarc; }ArcNode; typedef struct vexnode { VertexType data; ArcNode*firstarc; }VHeadNode; typedef struct { int n,e; VHeadNode adjlist[MAXVEX]; }AdjGraph; void CreateGraph(MatGraph&g,int A[][MAXVEX],int n,int e) { int i,j; g.n=n; g.e=e; for(i=0;i<n;i++) for(j=0;j<n;j++) g.edges[i][j]=A[i][j]; } void DispGraph(MatGraph g) { int i,j; for(i=0;i<g.n;i++) { for(j=0;j<g.n;j++) if(g.edges[i][j]<INF) printf("%4d",g.edges[i][j]); else printf("%4s","∞"); printf("\n"); } } void CreateGraph(AdjGraph*&G,int A[][MAXVEX],int n,int e) { int i,j; ArcNode*p; G=(AdjGraph*)malloc(sizeof(AdjGraph)); G->n=n; G->e=e; for(i=0;i<G->n;i++) G->adjlist[i].firstarc=NULL; for(i=0;i<G->n;i++) for(j=G->n-1;j>=0;j--) if(A[i][j]>0&&A[i][j]<INF) { p=(ArcNode*)malloc(sizeof(ArcNode)); p->adjvex=j; p->weight=A[i][j]; p->nextarc=G->adjlist[i].firstarc; G->adjlist[i].firstarc=p; } } void DispGraph(AdjGraph*G) { ArcNode*p; int i; for(i=0;i<G->n;i++) { printf("[%2d]",i); p=G->adjlist[i].firstarc; if(p!=NULL) printf("→"); while(p!=NULL) { printf(" %d(%d)",p->adjvex,p->weight); p=p->nextarc; } printf("\n"); } } void DFS(AdjGraph*G,int v) { int w,visited[MAXSIZE]; ArcNode*p; printf("%d",v); visited[v]=1; p=G->adjlist[v].firstarc; while(p!=NULL) { w=p->adjvex; if(visited[w]==0) DFS(G,w); p=p->nextarc; } } void BFS(AdjGraph*G,int vi) { int i,v,visited[MAXVEX]; int Qu[MAXVEX],front=0,rear=0; ArcNode*p; for(i=0;i<G->n;i++) visited[i]=0; printf("%d",vi); visited[vi]=1; rear=(rear+1)%MAXVEX; Qu[rear]=vi; while(front!=rear) { front=(front+1)%MAXVEX; v=Qu[front]; p=G->adjlist[v].firstarc; while(p!=NULL) { if(visited[p->adjvex]==0) { printf("%d",p->adjvex); visited[p->adjvex]=1; rear=(rear+1)%MAXVEX; Qu[rear]=p->adjvex; } p=p->nextarc; } } } void main() { MatGraph g; AdjGraph *G; int n=5,e=5,i,visited[MAXVEX]; int A[MAXVEX][MAXVEX]={{0,1,0,1,0},{1,0,1,1,0},{0,1,0,0,0},{1,1,0,0,1},{0,0,0,1,0}}; CreateGraph(g,A,n,e); printf("图G的邻接矩阵存储结构:\n"); DispGraph(g); printf("\n"); CreateGraph(G,A,n,e); printf("图G的邻接表存储结构:\n"); DispGraph(G); printf("\n"); for(i=0;i<G->n;i++) visited[i]=0; printf("各种遍历序列:\n"); printf("DFS:"); DFS(G,0); printf("\n"); printf("BFS:"); BFS(G,0); printf("\n"); }
一颗大水滴 2014-11-26
  • 打赏
  • 举报
回复
怎么输出啊 啊啊啊啊
z_songlin 2013-11-23
  • 打赏
  • 举报
回复
求人不如求已。 问题已解决。
//深度优先(非递归)
//LGraph: 邻接表
//InitVertex: 遍历起始顶点
void st_DFS(const ListGraph* LGraph, int InitVertex)
{
	bool Visited[MAX_VERTEX] = { false };		
	int stack[MAX_VERTEX];		//栈
	int top = -1;

	ArcNode* pEdge = NULL;
	int Pre[MAX_VERTEX];
	int index = -1;		//Pre数组的下标

	Visited[InitVertex] = true;			//起始顶点标记已访问
	cout << InitVertex << " ";			//输出起始顶点

	//把所有与起始顶点关联的顶点存入Per数组中
	pEdge = LGraph->AdjList[InitVertex].FirstArc;
	while (NULL != pEdge)
	{
		Pre[++index] = pEdge->AdjoinVertex;
		pEdge = pEdge->pNextArc;
	}
	//逆序把Pre数组中的顶点加入栈中
	for (int i = index; i >= 0; i--)
	{
		top++;
		stack[top] = Pre[i];
		Visited[Pre[i]] = 1;		//入栈的顶点标记已访问
	}

	while (top > -1)
	{
		int TopVertex = stack[top];
		top--;
		cout << TopVertex << " ";		//输出栈顶节点

		pEdge = LGraph->AdjList[TopVertex].FirstArc;		//把所有与栈底顶点关联且未访问过的顶点入栈
		index = -1;	//重置Pre数组下标
		while (NULL != pEdge)
		{
			if (Visited[pEdge->AdjoinVertex] == 0)
				Pre[++index] = pEdge->AdjoinVertex;
			pEdge = pEdge->pNextArc;
		}
		for (int i = index; i >= 0; i--)		//逆序把Pre数组中的顶点加入到栈中
		{
			top++;
			stack[top] = Pre[i];
			Visited[Pre[i]] = 1;
		}
	}//end while(top > -1)
}
colorfulcode 2013-11-17
  • 打赏
  • 举报
回复
引用 3 楼 qq6680040 的回复:
[quote=引用 1 楼 ColorfulCode 的回复:] 话说都忘了啥是邻接表了。 是那种深度优先方式遍历一棵树吗?
不是树,是图[/quote] 图也应该差不多吧,也可以借助一个数组来遍历,只不过注意下别重复遍历就行了,否则就死循环了
z_songlin 2013-11-17
  • 打赏
  • 举报
回复

//深度优先(非递归)
//LGraph: 邻接表
//InitVertex: 遍历起始顶点
void st_DFS(const ListGraph* LGraph, int InitVertex)
{
	bool Visited[MAX_VERTEX] = { 0 };
	ArcNode* pEdge = NULL;
	ArcNode* stack[20];		//栈
	int top = -1;

	Visited[InitVertex] = true;			//起始顶点标记已访问
	cout << InitVertex << " ";
	top++;
	stack[top] = LGraph->AdjList[InitVertex].FirstArc;
	while (top > -1)
	{	
		pEdge = stack[top];
		top--;
		cout << pEdge->AdjoinVertex << " ";
		Visited[pEdge->AdjoinVertex] = true;			//栈顶顶点标记已访问

		pEdge = LGraph->AdjList[pEdge->AdjoinVertex].FirstArc;
		ArcNode* pTemp = LGraph->AdjList[pEdge->AdjoinVertex].FirstArc;
 		while (pEdge != NULL && Visited[pEdge->AdjoinVertex] != false)
		{
				pEdge = pEdge->pNextArc;
		}

		if (NULL != pEdge)
		{
			top++;
			stack[top] = pEdge;
		}
	
	}
}
这是我写的一个,起始点为0的时候是正确的,但起始点换成其他的就不行了。 我知道错在哪。。但不知道怎么改。
z_songlin 2013-11-16
  • 打赏
  • 举报
回复
引用 1 楼 ColorfulCode 的回复:
话说都忘了啥是邻接表了。 是那种深度优先方式遍历一棵树吗?
不是树,是图
colorfulcode 2013-11-16
  • 打赏
  • 举报
回复
用循环代替递归, 用一个数组记录遍历过程中遇到的所有非叶子节点的指针,并将该节点插入数组中,然后不断地读取数组中的节点,每读一个就将这个节点从数组中移除。 等把数组移空了,也就遍历完了。 当然得排除循环或其他现象。 其实函数递归也只不过是另一种形式的“数组”做了一次循环
colorfulcode 2013-11-16
  • 打赏
  • 举报
回复
话说都忘了啥是邻接表了。 是那种深度优先方式遍历一棵树吗?

64,637

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧