码迷,mamicode.com
首页 > 其他好文 > 详细

图的创建和遍历(BFS/DFS)

时间:2016-06-23 23:54:48      阅读:201      评论:0      收藏:0      [点我收藏+]

标签:

     图的表示方法主要有邻接矩阵和邻接表。其中邻接表最为常用,因此这里便以邻接表为例介绍一下图的创建及遍历方法。

     创建图用到的结构有两种:顶点及弧

struct ArcNode
    {
        int vertexIndex;        //该弧指向的顶点位置
        struct ArcNode* next;    //指向下一个弧
        InfoType info;            //该弧的相关信息,如权重等
    };

    struct Vertex
    {
        VertexType data;    //顶点信息
        ArcNode* firstArc;    //指向第一条依附该节点弧的指针
        ColorType color;    //访问情况
    };
  

其中ColorType是一个枚举,遍历的时候才会用到以后再说明。图的创建比较简单,直接看代码很容易理解,这里不再详细说了。 图的深度和广度遍历直接看算法导论中的两张图就明白了:技术分享技术分享

 
代码:
技术分享
  1 #include <queue>
  2 #include <iostream>
  3 using namespace std;
  4 
  5 
  6 enum GraphType
  7 {    
  8     UNDIR_UNWEIGHT_GRAPH,        //无向无权图
  9     UNDIR_WEIGHT_GRAPH,            //无向带权图
 10     DIR_UNWEIGHT_GRAPH,            //有向无权图
 11     DIR_WEIGHT_GRAPH            //有向带权图    
 12 };
 13 
 14 //结点颜色代表遍历情况
 15 enum ColorType
 16 {
 17     WHITE,    //未访问
 18     GRAY,    //正在访问,邻接点还没访问完
 19     BLACK    //访问完毕
 20 };
 21 
 22 template<typename VertexType,typename InfoType>
 23 class Graph
 24 {
 25 private:
 26     struct ArcNode
 27     {
 28         int vertexIndex;        //该弧指向的顶点位置
 29         struct ArcNode* next;    //指向下一个弧
 30         InfoType info;            //该弧的相关信息,如权重等
 31     };
 32 
 33     struct Vertex
 34     {
 35         VertexType data;    //顶点信息
 36         ArcNode* firstArc;    //指向第一条依附该节点弧的指针
 37         ColorType color;    //访问情况
 38     };
 39 
 40     //最大顶点数
 41     static const int MAX_VERTEX_NUM = 20;
 42     Vertex m_vertices[MAX_VERTEX_NUM];    //顶点列表
 43     int m_vertexNum;    //当前顶点数量
 44     int m_arcNum;        //当前弧数量
 45     GraphType m_type;    //图类型:有向无权图、有向带权图、无向无权图、无向无权图
 46 private:
 47     //初始化顶点列表
 48     void InitVertices()
 49     {
 50         cout << "请输入每个顶点的关键字" << endl;
 51         VertexType data;
 52         for (int i = 0; i < m_vertexNum; ++i)
 53         {
 54             cin >> data;
 55             m_vertices[i].data = data;
 56         }
 57     }
 58     //插入一个表结点
 59     void Insert(int headVertex, int tailVertex, InfoType info)
 60     {
 61         //构造一个邻接表结点,即创建一条弧
 62         ArcNode* newNode = new ArcNode;
 63         newNode->info = info;
 64         newNode->next = nullptr;
 65         newNode->vertexIndex = tailVertex;
 66 
 67         //找到邻接表的最后一个节点
 68         ArcNode* lastNode = m_vertices[headVertex].firstArc;
 69         if (lastNode == nullptr)
 70             m_vertices[headVertex].firstArc = newNode;
 71         else
 72         {
 73             while (lastNode->next)
 74             {
 75                 lastNode = lastNode->next;
 76             }
 77             lastNode->next = newNode;
 78         }
 79         ++m_arcNum;
 80     }
 81 
 82     //创建无向无权图
 83     void CreateUndirUnweightGraph()
 84     {
 85         InitVertices();
 86         cout << "请分别输入每条边的起始结点:" << endl;
 87         int head, tail;
 88         while (cin >> head >> tail)
 89         {
 90             //无向图head->tail tail->head插入两次
 91             Insert(head, tail, 0);
 92             Insert(tail, head, 0);
 93         }
 94     }
 95     //创建无向有权图
 96     void CreateUndirWeightGraph()
 97     {
 98         InitVertices();
 99         cout << "请分别输入每条边的起始结点和权值:" << endl;
100         int head, tail;
101         InfoType weight;
102         while (cin >> head >> tail >> weight)
103         {
104             Insert(head, tail, weight);
105             Insert(tail, head, weight);
106         }
107     }
108     //创建有向无权图
109     void CreateDirUnweightGraph()
110     {
111         InitVertices();
112         cout << "请分别输入每条边的起始结点值:" << endl;
113         int head, tail;
114         while (cin >> head >> tail)
115         {
116             Insert(head, tail,0);
117         }
118     }
119     //创建有向带权图 
120     void CreateDirWeightGraph()
121     {
122         InitVertices();
123         cout << "请分别输入每条边的起始结点和权值:" << endl;
124         int head, tail;
125         InfoType weight;
126         while (cin >> head >> tail >> weight)
127         {
128             Insert(head, tail, weight);
129         }
130     }
131 
132     void BFS(Vertex* vertex)
133     {
134         vertex->color = GRAY;
135         queue<Vertex*> vertices;
136         vertices.push(vertex);
137         while (!vertices.empty())
138         {
139             Vertex* curVertex = vertices.front();
140             vertices.pop();
141             cout << curVertex->data << "->";
142             ArcNode* node = curVertex->firstArc;
143             while (node)
144             {
145                 Vertex* tmpVertex = &m_vertices[node->vertexIndex];
146                 if (tmpVertex->color == WHITE)
147                 {
148                     tmpVertex->color = GRAY;
149                     vertices.push(tmpVertex);
150                 }
151                 node = node->next;
152             }
153             curVertex->color = BLACK;
154         }
155     }
156 public:
157     Graph(int vertexNum, GraphType type) :m_vertexNum(vertexNum), m_type(type), m_arcNum(0)
158     {
159         for (int i = 0; i < MAX_VERTEX_NUM; ++i)
160         {
161             m_vertices[i].firstArc = nullptr;
162         }
163     }
164 
165     void Create()
166     {
167         switch (m_type)
168         {
169         case UNDIR_UNWEIGHT_GRAPH:
170             CreateUndirUnweightGraph();
171             break;
172         case UNDIR_WEIGHT_GRAPH:
173             CreateUndirWeightGraph();
174             break;
175         case DIR_UNWEIGHT_GRAPH:
176             CreateDirUnweightGraph();
177             break;
178         case DIR_WEIGHT_GRAPH:
179             CreateDirWeightGraph();
180             break;
181         default:
182             break;
183         }
184     }
185 
186     //输出图的信息
187     void Display()
188     {
189         for (int i = 0; i < m_vertexNum; ++i)
190         {
191             cout << "" << i + 1 << "个结点为" << m_vertices[i].data << " 邻接表为:";
192             ArcNode* node = m_vertices[i].firstArc;
193             while (node)
194             {
195                 cout << "->" << m_vertices[node->vertexIndex].data << "(" << node->info << ")";
196                 node = node->next;
197             }
198             cout << endl;
199         }
200     }
201 
202     void BFS()
203     {
204         for (int i = 0; i < m_vertexNum; ++i)
205         {
206             m_vertices[i].color = WHITE;
207         }
208         cout << "图的广度优先遍历为:";
209         BFS(&m_vertices[0]);
210         cout << endl;
211     }
212 };
213 
214 int main()
215 {
216     int  vertexNum;
217     cout << "请输入要创建的图的结点数:";
218     cin >> vertexNum;
219     Graph<char, int> g(vertexNum,GraphType::UNDIR_UNWEIGHT_GRAPH);
220     g.Create();
221     g.Display();
222     g.BFS();
223 }
View Code
运行结果:
 
 

图的创建和遍历(BFS/DFS)

标签:

原文地址:http://www.cnblogs.com/zhangbaochong/p/5612410.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!