标签:
图的表示方法主要有邻接矩阵和邻接表。其中邻接表最为常用,因此这里便以邻接表为例介绍一下图的创建及遍历方法。
创建图用到的结构有两种:顶点及弧
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 }
运行结果:
标签:
原文地址:http://www.cnblogs.com/zhangbaochong/p/5612410.html