图的存储结构可以用邻接矩阵或者邻接表来表示,对于n个顶点和e条边的无向网图,采用邻接矩阵创建时,其时间复杂度为O(n+n^2+e),深度优先算法遍历时间复杂度为O(n^2);采用邻接表创建时,其时间复杂度为O(n+e),深度优先算法遍历时间复杂度为O(n+e)。以下是两种方式的代码实现。
#include<iostream>
#define INF 65535
#define MAXVEX 100
#define TRUE 1
#define FALSE 0
using namespace std;
typedef int VertexType;
typedef int EdgeType;
typedef int Boolean;
Boolean visited[MAXVEX];
typedef struct {
VertexType vexs[MAXVEX];
EdgeType arc[MAXVEX][MAXVEX];
int numVertexs, numEdges;
}MGraph;
//建立无向网图的邻接矩阵表示
void CreateMGraph(MGraph *G)
{
int i, j, k, w;
printf("输入顶点数和边数:\n");
cin>>G->numVertexs>>G->numEdges;
printf("输入顶点:\n");
for (i = 0; i < G->numVertexs; ++i)
cin>>G->vexs[i];
for (i = 0; i < G->numVertexs; ++i)
for (j = 0; j < G->numVertexs; ++j) {
if(i==j)
G->arc[i][j] = 0;
else
G->arc[i][j] = INF;
}
for (k = 0; k < G->numEdges; ++k) {
printf("输入边(vi,vj)上的下标i,下标j和权w:\n");
cin>>i>>j>>w;
G->arc[i][j] = w;
G->arc[j][i] = G->arc[i][j];//无向图
}
}
//邻接矩阵的深度优先递归算法
void DFS(MGraph G, int i)
{
int j;
visited[i] = TRUE;
cout<<G.vexs[i]<<' ';
for (j = 0; j < G.numVertexs; ++j)
if (G.arc[i][j] != INF && !visited[j] && G.arc[i][j] != 0)
DFS(G, j);
}
//邻接矩阵的深度遍历操作
void DFSTraverse(MGraph G)
{
int i;
for (i = 0; i < G.numVertexs; ++i)
visited[i] = FALSE; //初始所有顶点状态都是未访问状态
for (i = 0; i < G.numVertexs; ++i)
if (!visited[i]) //对未访问的顶点调用DFS,若是连通图,只会执行一次
DFS(G, i);
}
int main()
{
MGraph G;
CreateMGraph(&G);
printf("输出权值矩阵:\n");
for (int i = 0; i < G.numVertexs; ++i) {
for (int j = 0; j < G.numVertexs; ++j)
cout << G.arc[i][j] << ' ';
cout << endl;
}
printf("深度优先遍历输出:\n");
DFSTraverse(G);
}
#include<iostream>
#define INF 65535
#define MAXVEX 100
#define TRUE 1
#define FALSE 0
using namespace std;
typedef int VertexType;
typedef int EdgeType;
typedef int Boolean;
Boolean visited[MAXVEX];
typedef struct EdgeNode{ //边表结点
int adjvex; //邻接点域,存储该顶点对应的下标
EdgeType weight; //存储权值
struct EdgeNode *next; //链域,指向下一个邻接点
}EdgeNode;
typedef struct VertxeNod {//顶点表结点
VertexType data; //顶点域,存储顶点信息
EdgeNode *firstedge; //边表头指针
}VertexNode,AdjList[MAXVEX];
typedef struct {
AdjList adjList;
int numVertexes, numEdges; //图中当前顶点数和边数
}GraphAdjList;
void CreaateALGraph(GraphAdjList *G)
{
int i, j, k,w;
EdgeNode *e;
cout<<"输入顶点数和边数:\n";
cin>>G->numVertexes>>G->numEdges;
cout<<"输入顶点信息:\n";
for (i = 0; i < G->numVertexes; ++i) { //输入顶点信息,建立顶点表
cin>>G->adjList[i].data;
G->adjList[i].firstedge = NULL; //将边表置为空表
}
for (k = 0; k < G->numEdges; ++k) {
cout<<"输入边(vi,vj)上的顶点序号和权值";
cin>>i>>j>>w;
e = (EdgeNode *)malloc(sizeof(EdgeNode));//向内存申请空间,生成边表结点
e->adjvex = j; //邻接序号为j
e->weight = w;
e->next = G->adjList[i].firstedge; //将e指针指向当前顶点指向的结点
G->adjList[i].firstedge = e; //将当前结点的指针指向e
//无向图添加以下代码
e = (EdgeNode *)malloc(sizeof(EdgeNode));//向内存申请空间,生成边表结点
e->adjvex = i; //邻接序号为i
e->weight = w;
e->next = G->adjList[j].firstedge; //将e指针指向当前顶点指向的结点
G->adjList[j].firstedge = e; //将当前结点的指针指向e
}
}
//邻接表的深度优先递归算法
void DFS(GraphAdjList G,int i)
{
EdgeNode *p;
visited[i] = TRUE;
cout << G.adjList[i].data<<' ';
p = G.adjList[i].firstedge;
while (p) {
if (!visited[p->adjvex])
DFS(G, p->adjvex);
p = p->next;
}
}
//邻接表的深度遍历操作
void DFSTraverse(GraphAdjList G)
{
int i;
for (i = 0; i < G.numVertexes; ++i)
visited[i] = FALSE;
for (i = 0; i < G.numVertexes; ++i)
if (!visited[i])
DFS(G, i);
}
int main()
{
GraphAdjList graph;
CreaateALGraph(&graph);
EdgeNode *p;
for (int i = 0; i < graph.numVertexes; ++i) {
cout << "顶点:" << graph.adjList[i].data;
p = graph.adjList[i].firstedge;
while (p) {
cout<<" 邻接点:" << p->adjvex <<"权值:" <<p->weight << ' ';
p = p->next;
}
cout << endl;
}
cout << "深度优先遍历输出:";
DFSTraverse(graph);
cout << endl;
}