zoukankan      html  css  js  c++  java
  • 图——广度优先遍历和深度优先遍历——邻接表表示法

    // ConsoleApplication2.cpp : 定义控制台应用程序的入口点。
    //

    #include "stdafx.h"
    #include "stdafx.h"
    #include<iostream>
    #include<vector>
    #include<algorithm>
    #include<numeric>
    #include<list>
    #include<iterator>
    #include<deque>
    #include<stack>
    #include<algorithm>
    #include<forward_list>
    using namespace std;
    
    
    
    struct Edge //边的定义
    { 
    	Edge(int i):node(i),nextEdge(NULL){ }
    	int node;
    	Edge *nextEdge;
    };
    struct Node //节点的定义
    {
    	Node(int i):value(i),firstEdge(NULL){}
    	int value;
    	Edge *firstEdge;
    };
    struct Figure
    {
    	vector<Node*> nodes;//存储节点
    	int nodeNums, edgeNums;
    };
    class Solution {
    public:
    	//构建表
    	void createFigure(Figure &figure)
    	{
    		//首先输入边的信息
    		cout << "请输入节点的数目:" ;
    		cin >> figure.nodeNums;
    		cout << "请输入边的数目:";
    		cin >> figure.edgeNums;
    		for (int i = 0; i < figure.nodeNums; ++i) //输入节点信息
    		{
    			figure.nodes.push_back(new Node(i));
    		}
    		for (int i = 0; i < figure.nodeNums; ++i)//输入边的信息
    		{
    			cout << "请输入相关的边:";
    			int node1, node2;
    			cin >> node1 >> node2;
    			auto it = figure.nodes.begin();
    			while (it!=figure.nodes.end() && node1!=(*it)->value)
    			{
    				it++;//找到节点
    			}
    			if (it != figure.nodes.end())
    			{
    				//第一种插入方式
    				/*Edge* temp = (*it)->firstEdge;
    				(*it)->firstEdge = new Edge(node2);
    				(*it)->firstEdge->nextEdge = temp;*/
    				//第二种插入方式:
    				if ((*it)->firstEdge == NULL)
    				{
    					(*it)->firstEdge = new Edge(node2);
    				}
    				else
    				{
    					Edge* edge = (*it)->firstEdge;
    					while (edge->nextEdge != NULL)
    					{
    						edge = edge->nextEdge;
    					}
    					edge->nextEdge = new Edge(node2);
    				}
    				
    			}
    		}
    	}
    
    	void CreateAFigure(Figure &figure)
    	{
    		figure.nodeNums = 6;
    		for (int i = 0; i < figure.nodeNums; ++i) //输入节点信息
    		{
    			figure.nodes.push_back(new Node(i));
    		}
    		figure.nodes[0]->firstEdge = new Edge(1);
    		figure.nodes[0]->firstEdge->nextEdge = new Edge(2);
    		figure.nodes[1]->firstEdge = new Edge(3);
    		figure.nodes[1]->firstEdge->nextEdge = new Edge(4);
    		figure.nodes[2]->firstEdge = new Edge(3);
    		figure.nodes[4]->firstEdge = new Edge(5);
    		
    	}
    
    	void printFigure(Figure figure)//打印图
    	{
    		cout << "打印图的结构:" << endl;
    		for (int i = 0; i < figure.nodeNums; i++)
    		{
    			cout <<"v_"<< figure.nodes[i]->value << ": ";
    			if (figure.nodes[i]->firstEdge != NULL)
    			{
    			//	cout << figure.nodes[i]->firstEdge->node << "  ";
    				Edge* edge = figure.nodes[i]->firstEdge;
    				while (edge!=NULL)
    				{
    					cout << "v_"<<edge->node << "  ";
    					edge = edge->nextEdge;
    				}
    			}
    			cout << endl;
    		}
    	}
    	//深度优先遍历
    	void DFSTraver(Figure figure)
    	{
    		setVisit(figure);
    		for (int i = 0; i < figure.nodeNums; ++i)
    		{
    			if (visisted[i] == false)//第i个节点没有被访问
    				DFS(figure.nodes[i], figure);
    		}
    	}
    	void DFS(Node* node,Figure figure)
    	{
    		
    		if (visisted[node->value] == false)//如果该节点没有被访问过
    		{
    			cout << "v_" << node->value << "  ";
    			visisted[node->value] = true;
    		}
    		if (node->firstEdge == NULL) return;
    		if(visisted[node->firstEdge->node]==false)//第一个边没有被访问,访问第一条边
    		   DFS(figure.nodes[node->firstEdge->node],figure);
    		if (visisted[node->firstEdge->node] == true)//第一个边已经被访问过了,访问第二条没有被访问的边
    		{
    			//首先找到第一条没有被访问的边
    			Edge* edge = node->firstEdge->nextEdge; //第一条可访问的边
    			while (edge!=NULL)
    			{
    				if (visisted[edge->node] == true)//对应的节点已经访问过了
    					edge = edge->nextEdge;
    				else
    					break;//对应的节点没有被访问过
    			}
    			if (edge == NULL) //初始节点对应的边都访问完了
    				return;
    			else
    				DFS(figure.nodes[edge->node], figure);//访问第一条没有访问的边
    		}
    	}
    
    	//广度优先遍历
    	void BFSTravers(Figure figure)
    	{
    		setVisit(figure);
    		for (int i = 0; i < figure.nodeNums; ++i)
    		{
    			if (visisted[i] == false)
    			{
    				BFS(figure.nodes[i], figure);
    			}
    			   
    		}
    	}
    	deque<Node*> parent;
    	deque<Node*> child;
    	//此处应该设置两个队列;一个父队列,一个子队列,父亲队列用来存储将要答应的节点,子队列用来存储将要打印的节点
    	void BFS(Node* node,Figure figure)
    	{
    		//if (visisted[node->value] == false)//如果该节点没有被访问过
    		//{
    		//	cout << "v_" << node->value << "  ";  //打印跟节点
    		//	visisted[node->value] = true;
    		//}
    		//if (node->firstEdge == NULL) return;
    		//else
    		//{
    		//	cout << "v_" << node->firstEdge->node << "  "; //把接下来的根节点存入队列Node中
    		//	visisted[node->firstEdge->node] = true;
    		//	parent.push(figure.nodes[node->firstEdge->node]);
    		//}
    		//Edge* edge = node->firstEdge->nextEdge;
    		//while (edge!=NULL)
    		//{
    		//	cout << "v_" << edge->node << "  ";
    		//	visisted[node->firstEdge->node] = true;
    		//	parent.push(figure.nodes[edge->node]);
    		//	edge = edge->nextEdge;
    		//}
    
    		child.push_back(node);
    		while (!child.empty())
    		{
    			parent = child;
    			child.clear();
    			while (!parent.empty())
    			{
    				
    				if (visisted[parent.front()->value] == false)
    				{
    					cout << "v_" << parent.front()->value << "  ";  //打印跟节点
    					visisted[parent.front()->value] = true;
    				}
    				
    				Edge* edge = parent.front()->firstEdge;
    				while (edge!=NULL)
    				{
    					child.push_back(figure.nodes[edge->node]);
    					edge = edge->nextEdge;
    				}
    				parent.pop_front();
    			}
    		}
    		
    		
    	}
    
    	vector<bool> visisted;//访问过的设置为ture,没访问过设置为false
    	void setVisit(Figure figure)
    	{
    		visisted.clear();
    		for (int i = 0; i < figure.nodeNums; i++)
    		{
    			visisted.push_back(false);
    		}
    	}
    };
    
    int main()
    {
    
    	Solution so;
    	Figure figure;
    	so.CreateAFigure(figure);
    	cout << "节点结构:" << endl;;
    	so.printFigure(figure);
    	cout << "深度优先遍历:";
    	so.DFSTraver(figure);
    	cout << endl;
    	cout << "广度优先遍历:";
    	so.BFSTravers(figure);
    	cout << endl;
    	return 0;
    }
  • 相关阅读:
    SparkSql初级编程实践
    云时代架构之苏宁安全架构演进及实践
    云时代架构之知乎网站架构变迁史
    质量属性的六个常见属性场景之《淘宝网》
    云时代架构之游戏服务器的架构演进
    《架构漫谈阅读心得》
    转换后缀表达式
    约瑟夫环(改进3.0)
    栈结构之后缀表达式
    约瑟夫环(改进2.0)
  • 原文地址:https://www.cnblogs.com/wdan2016/p/6182125.html
Copyright © 2011-2022 走看看