本文用于学习图的遍历(深度优先遍历、广度优先遍历)!!!
#include <iostream> using namespace std; typedef char VertexType; typedef int EdgeType; const int MAXSIZE = 100; bool visited[MAXSIZE]; typedef int QElemType; typedef struct { QElemType data[MAXSIZE]; int front;//头指针 int rear;//尾指针 }SqQueue;//定义循环队列顺序存储类型 void InitQueue(SqQueue &q)//队列初始化 { q.front = 0; q.rear = 0; } void EnQueue(SqQueue &q, QElemType &e)//入队列,将元素插入循环队列的队尾 { q.data[q.rear] = e; q.rear = (q.rear + 1) % MAXSIZE; } void DeQueue(SqQueue &q, QElemType &e)//出队列,头指针后移 { e = q.front; q.front = (q.front) % MAXSIZE; } bool QueueEmpty(SqQueue &q)//判断队列是否为空,头指针等于尾指针 { if (q.front == q.rear) return true; } typedef struct//定义邻接矩阵类型 { int numVertexes, numEdges; VertexType vertex[MAXSIZE];//顶点数组 EdgeType arc[MAXSIZE][MAXSIZE];//边数组 }MGraph; void createMGraph(MGraph *G)//创建邻接矩阵存储无向图 { cout << "输入顶点数量和边数量:"; cin >> G->numVertexes >> G->numEdges; cout << "输入顶点信息:"; for (int i = 0; i < G->numVertexes; i++) cin >> G->vertex[i]; for (int i = 0; i < G->numVertexes; i++)//邻接表初始化 for (int j = 0; j < G->numVertexes; j++) G->arc[i][j] = false; cout << "输入边(下标,下标):" << endl; for (int i = 0; i < G->numEdges; i++) { int a, b; cin >> a >> b; G->arc[a][b] = true; G->arc[b][a] = G->arc[a][b];//无向图是对称矩阵 } } void DFS(MGraph *g, int i) { visited[i] = true; cout << "访问的顶点:" << g->vertex[i] << endl; for (int j = 0; j < g->numVertexes; j++) { if (g->arc[i][j] == 1 && !visited[i])//遍历每行 DFS(g, j);//未访问的顶点递归操作 } } void DFSTraverse(MGraph *g)//深度优先遍历,类似树的前序遍历 { for (int i = 0; i < g->numVertexes; i++)//访问标志数组初始化 visited[i] = false; for (int i = 0; i < g->numVertexes; i++) { if (!visited[i]) DFS(g, i); cout << "test!!!" << endl; } } void BFSTraverse(MGraph *g)//广度优先遍历,类似树的层序遍历 { int i, j; SqQueue q = {}; InitQueue(q); for (i = 0; i < g->numVertexes; i++)//初始化访问标志数组 visited[i] = false; for (i = 0; i < g->numVertexes; i++)//遍历每个顶点 { if (!visited[i]) { visited[i] = true; cout << "当前访问的顶点:" << g->vertex[i] << endl; EnQueue(q, i);//此顶点入队列 while (!QueueEmpty(q)) { DeQueue(q, i);//队首元素出队列 for (j = 0; j < g->numVertexes; j++)//遍历与出队列元素连接的所有顶点 { if (g->arc[i][j] == 1 && !visited[j]) { visited[j] = true; cout << "当前访问的顶点:" << g->vertex[i] << endl; EnQueue(q, j);//此顶点入队列,队列中的元素都是已经访问过的 } } } } } } typedef struct EdgeNode//定义边表结点类型 { EdgeType weight;//权重 int adjVex;//邻接结点 struct EdgeNode *next;//指向下一个结点 }EdgeNode; typedef struct VertexNode//定义顶点结点类型 { VertexType data;//顶点信息 EdgeNode *firstEdge;//指向边表的头一结点 }VertexNode,AdjList[MAXSIZE]; typedef struct//定义邻接链表类型 { int numVertexes, numEdges; AdjList adjList; }GraphAdjList;//直接创建结构体变量 void createGraphAdjList(GraphAdjList *G)//创建邻接表存储无向图 { cout << "输入顶点数量和边数量:"; cin >> G->numVertexes >> G->numEdges; cout << "输入顶点信息:"; for (int i = 0; i < G->numVertexes; i++)//存储顶点表结点信息 { cin >> G->adjList[i].data; G->adjList[i].firstEdge = NULL; } EdgeNode *e; for (int k = 0; k < G->numEdges; k++)//头插法,存储边表结点信息 { int i, j; cout << "输入边(下标,下标):" << endl; cin >> i >> j; e = (EdgeNode *)malloc(sizeof(EdgeNode)); e->adjVex = j;//存储邻接点j e->next = G->adjList[i].firstEdge;//将e结点插入到顶点表指向的头结点前面 G->adjList[i].firstEdge = e;//将顶点表结点指向e结点 e = (EdgeNode *)malloc(sizeof(EdgeNode));//无向图,反向操作 e->adjVex = i; e->next = G->adjList[j].firstEdge; G->adjList[j].firstEdge = e; } } void DFS(GraphAdjList *gl, int i) { EdgeNode *p; visited[i] = true; cout << "当前访问的结点:" << gl->adjList[i].data << endl; p = gl->adjList[i].firstEdge;//获得邻接边表结点 while (p) { if (!visited[p->adjVex]) DFS(gl, p->adjVex);//未访问的顶点递归操作 p = p->next; } } void DFSTraverse(GraphAdjList *gl) { for (int i = 0; i < gl->numVertexes; i++) visited[i] = false; for (int i = 0; i < gl->numVertexes; i++) { if (!visited[i])//连通图仅调用DFS函数一次 DFS(gl, i); cout << "test!!!" << endl; } } void BFSTraverse(GraphAdjList *gl) { int i; for (i = 0; i < gl->numVertexes; gl++) visited[i] = false; SqQueue q = {}; InitQueue(q); EdgeNode *p; for (i = 0; i < gl->numVertexes; gl++) { if (!visited[i]) { visited[i] = true; cout << "当前访问的顶点:" << gl->adjList[i].data << endl; EnQueue(q, i); if (!QueueEmpty(q)) { DeQueue(q, i); p = gl->adjList[i].firstEdge; while (p) { if (!visited[p->adjVex]) { visited[p->adjVex] = true; cout << "当前访问的顶点:" << gl->adjList[p->adjVex].data << endl; EnQueue(q, p->adjVex); } p = p->next; } } } } } int main(int *argc, int **argv) { MGraph G = {}; MGraph *g; g = &G; createMGraph(g); for (int i = 0; i < g->numVertexes; i++) { for (int j = 0; j < g->numVertexes; j++) { cout << g->arc[i][j] << " ";//打印邻接表信息 } cout << endl; } DFSTraverse(g); BFSTraverse(g); GraphAdjList GL = {}; GraphAdjList *gl; gl = &GL; createGraphAdjList(gl); EdgeNode *p; for (int i = 0; i < gl->numVertexes; i++) { cout << "顶点:" << gl->adjList[i].data << " "; p = gl->adjList[i].firstEdge; while (p) { cout << "边表结点:" << p->adjVex << " "; p = p->next; } cout << endl; } DFSTraverse(gl); BFSTraverse(gl); return 0; }
参考资料:
1.《大话数据结构》