数据结构:以邻接表为存储结构,实现深度优先遍历的非递归算法

难点:1.邻接表结构的实现(链表学好了就很顺利,学的不好危)

           2.用栈实现非递归DFS(不要忘了递归的本质就是栈的进出)

关键函数实现:

邻接表构造函数:

template<class	T>
ALGraph<T>::ALGraph()
{
	int	n, m;
	int	start, end;
	cout << "请输入你所要构建的图的顶点数目和边的数目" << endl;
	cin >> n >> m;
	vNum = n;
	arcNum = m;
	cout << "请依次输入各顶点的值" << endl;
	for (int i = 1; i <= n; i++)
	{
		cin >> adjlist[i].vertex;
		adjlist[i].firstarc = NULL;
	}
	cout << "请输入每条边的两个顶点" << endl;
	for (int i = 1; i <= m; i++)
	{
		cin >> start >> end;
		insert(start, end);
		insert(end, start);
	}
}



template<class	T>
void	ALGraph<T>::insert(int	start, int	end)
{
	
	

	if (adjlist[start].firstarc == NULL)
	{
		ArcNode	*Node = new ArcNode;
		Node->adjvex = end;
		adjlist[start].firstarc = Node;
		Node->nextarc = NULL;
	}//当头结点是孤岛时的情况,做直接连接 
	else
	{
		ArcNode	*Node = new ArcNode;
		Node->adjvex = end;
		Node->nextarc = adjlist[start].firstarc;
		adjlist[start].firstarc = Node;
	}//当头节点已经有路的时候,做链表插入 
}

非递归DFS:

template<class	T>
void	ALGraph<T>::staDFS(int	v)
{
	int	Vis[MAXSIZE];//标记是否访问 
	memset(Vis, 0, sizeof(Vis));
	stack<int>s;
	s.push(v);
	Vis[v] = 1;
	int	j = 0;
	while (s.empty() != 1)//当栈非空时 
	{
		ArcNode	*Node = adjlist[s.top()].firstarc;
		int	npop = 1;//判断是否弹出栈顶,1时弹出
		while (Node)//不是空结点时,向后推进 
		{ 
			if (Vis[Node->adjvex] == 0)//该结点还没有被访问过
			{
				s.push(Node->adjvex);
				Vis[Node->adjvex] = 1;
				npop = 0;
				break;
			}
			Node = Node->nextarc;
		}
		if (npop)
		{
			cout << adjlist[s.top()].vertex << " ";
			s.pop();
		}
		//cout << "进行栈操作" << ++j << "次" << endl;
	}//以加入或弹出为单独一次操作 
	cout << endl;
}

遇到的困难总结:

邻接表构造的时候链表插入,忽略了表头一开始是NULL为空的情况,导致一直指不对

总代码:

ALGraph.h

#include<iostream>
#include<algorithm>
#include<stack>
using	namespace	std;
#define	MAXSIZE	10
struct	ArcNode {
	int	adjvex;//数据域,邻接顶点下标
	ArcNode	*nextarc;//指针域,指向下一条弧结点 (疑教材有误) 
};//弧结点 
struct	VertexNode {
	char	vertex;//数据域,顶点信息 
	ArcNode	*firstarc;//指针域:指向第一条弧 
};//顶点结点 



template<class	T>class	ALGraph
{
public:
	ALGraph();
	//~ALGraph();
	//void	DFS(int	v);
	//void	BFS(int	v);
	void	staDFS(int v);
	void	insert(int start, int	end);//将每一条路插入进邻接表里 
	void	print();
private:
	VertexNode	adjlist[MAXSIZE];//结点 
	int	vNum, arcNum;//顶点数目和弧的数目 
};


template<class	T>
ALGraph<T>::ALGraph()
{
	int	n, m;
	int	start, end;
	cout << "请输入你所要构建的图的顶点数目和边的数目" << endl;
	cin >> n >> m;
	vNum = n;
	arcNum = m;
	cout << "请依次输入各顶点的值" << endl;
	for (int i = 1; i <= n; i++)
	{
		cin >> adjlist[i].vertex;
		adjlist[i].firstarc = NULL;
	}
	cout << "请输入每条边的两个顶点" << endl;
	for (int i = 1; i <= m; i++)
	{
		cin >> start >> end;
		insert(start, end);
		insert(end, start);
	}
}

//template<class	T>
//void	ALGraph<T>::DFS(int	v)
//{
//	int	visited[MAXSIZE];
//	memset(visited, 0, sizeof(visited));
//	cout << adjlist[v].vertex << endl;
//	visited[v] = 1;
//	ArcNode	*p = adjlist[v].firstarc;
//	while (p)
//	{
//		int	j = p->adjvex;
//		if (visited[j] == 0)
//			DFS(j);
//		p = p->nextarc;
//	}
//}


template<class	T>
void	ALGraph<T>::insert(int	start, int	end)
{
	
	

	if (adjlist[start].firstarc == NULL)
	{
		ArcNode	*Node = new ArcNode;
		Node->adjvex = end;
		adjlist[start].firstarc = Node;
		Node->nextarc = NULL;
	}//当头结点是孤岛时的情况,做直接连接 
	else
	{
		ArcNode	*Node = new ArcNode;
		Node->adjvex = end;
		Node->nextarc = adjlist[start].firstarc;
		adjlist[start].firstarc = Node;
	}//当头节点已经有路的时候,做链表插入 
}


template<class	T>
void	ALGraph<T>::print()
{
	for (int i = 1; i <= vNum; i++)
	{
		ArcNode	*Node = adjlist[i].firstarc;
		cout << adjlist[i].vertex ;
		while (Node)
		{
			cout <<"->"<< Node->adjvex ;
			Node = Node->nextarc;
		}
		cout << endl;
	}
}

template<class	T>
void	ALGraph<T>::staDFS(int	v)
{
	int	Vis[MAXSIZE];//标记是否访问 
	memset(Vis, 0, sizeof(Vis));
	stack<int>s;
	s.push(v);
	Vis[v] = 1;
	int	j = 0;
	while (s.empty() != 1)//当栈非空时 
	{
		ArcNode	*Node = adjlist[s.top()].firstarc;
		int	npop = 1;//判断是否弹出栈顶,1时弹出
		while (Node)//不是空结点时,向后推进 
		{ 
			if (Vis[Node->adjvex] == 0)//该结点还没有被访问过
			{
				s.push(Node->adjvex);
				Vis[Node->adjvex] = 1;
				npop = 0;
				break;
			}
			Node = Node->nextarc;
		}
		if (npop)
		{
			cout << adjlist[s.top()].vertex << " ";
			s.pop();
		}
		//cout << "进行栈操作" << ++j << "次" << endl;
	}//以加入或弹出为单独一次操作 
	cout << endl;
}
//FOR Caicai

main.cpp

#include<iostream>
#include"ALGraph.h" 
using	namespace	std;
int	main()
{
	ALGraph<char>ALG;
	cout << "邻接表构造结果如下:" << endl;
	ALG.print();
//	ALG.DFS(1);
	cout << "遍历结果如下" << endl;
	ALG.staDFS(1);
}
//6 1
//1 2
//2 5
//1 3
//3 2
//3 4
//FOR Caicai

测试样例图:

效果图:

 

posted @   Gustavo09  阅读(196)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示