谨以此文记录无向图的实现:
#include <iostream>
#define MaxInt 32767
#define MVNum 100
using namespace std;
typedef int QElemType;
typedef struct QNode
{
QElemType data;
QNode *next;
} QNode, *QueuePtr;
typedef struct
{
QueuePtr front = nullptr, rear = nullptr;
} LinkQueue;
typedef char VertexType; //顶点数据类型
typedef int ArcType; //边的权值类型
typedef struct
{
VertexType vexs[MVNum]; //顶点表
ArcType arcs[MVNum][MVNum]; //邻接矩阵
int vexnum, arcnum; //图的顶点数和边数
} AMGraph;
typedef int OtherInfo;
typedef struct ArcNode //边结构
{
int adjvex; //该边指向的顶点的位置
ArcNode *next; //下一条边的指针
OtherInfo info;
} ArcNode;
typedef struct VNode //顶点结构
{
VertexType data; //顶点信息
ArcNode *firstarc;
} VNode, AdjList[MVNum];
typedef struct //图结构
{
AdjList vertics; //邻接表
int vexnum, arcnum;
int kind; //图的种类
} ALGraph;
bool visited[MVNum];
/**
* @brief 初始化
*
* @param Q
* @return true
* @return false
*/
bool InitQueue(LinkQueue &Q)
{
Q.front = Q.rear = new QNode;
Q.front->next = nullptr;
return true;
}
/**
* @brief 销毁队列
*
* @param Q
* @return true
* @return false
*/
bool DestroyQueue(LinkQueue &Q)
{
while (Q.front)
{
Q.rear = Q.front->next;
delete Q.front;
Q.front = Q.rear;
}
return true;
}
/**
* @brief 判断队列是否为空
*
* @param Q
* @return true
* @return false
*/
bool QueueEmpty(LinkQueue Q)
{
return Q.front == Q.rear;
}
/**
* @brief 入队
*
* @param Q
* @param e
* @return true
* @return false
*/
bool EnQueue(LinkQueue &Q, QElemType e)
{
QNode *p = new QNode;
p->data = e;
p->next = nullptr;
Q.rear->next = p;
Q.rear = p;
return true;
}
/**
* @brief 出队
*
* @param Q
* @param e
* @return true
* @return false
*/
bool DeQueue(LinkQueue &Q, QElemType &e)
{
if (Q.front == Q.rear)
return false;
QNode *p = Q.front->next;
e = p->data;
Q.front->next = p->next;
if (Q.rear == p)
Q.rear = Q.front;
delete p;
return true;
}
void printUI()
{
cout << "*******************************************" << endl;
cout << "*************** 无向网图 **************" << endl;
cout << "*******************************************" << endl;
cout << "************* 1.构建网图 *********" << endl;
cout << "************* 2.输出邻接矩阵 *********" << endl;
cout << "************* 3.深度优先遍历 *********" << endl;
cout << "************* 4.广度优先遍历 *********" << endl;
cout << "************* 5.退出 *********" << endl;
cout << "*******************************************" << endl;
}
/**
* @brief 确定顶点v在图G的顶点表中的下标
*
* @param G
* @param v
* @return int
*/
int LocateVex(AMGraph G, VertexType v)
{
for (int i = 0; i < G.vexnum; i++)
{
if (G.vexs[i] == v)
return i;
}
return -1;
}
/**
* @brief 用邻接矩阵创建无向网图
*
* @param G
* @return true
* @return false
*/
bool CreateUDN(AMGraph &G)
{
cout << "请输入顶点数和边数:";
cin >> G.vexnum >> G.arcnum;
cout << "请输入顶点信息:";
for (int i = 0; i < G.vexnum; i++)
cin >> G.vexs[i];
//邻接矩阵初始化
for (int i = 0; i < G.vexnum; i++)
for (int j = 0; j < G.vexnum; j++)
G.arcs[i][j] = 0;
cout << "请输入边依附的顶点:" << endl;
for (int k = 0; k < G.arcnum; k++)
{
VertexType v1, v2;
ArcType w;
cin >> v1 >> v2;
int i = LocateVex(G, v1);
int j = LocateVex(G, v2);
G.arcs[i][j] = 1;
G.arcs[j][i] = G.arcs[i][j];
}
return true;
}
/**
* @brief 从邻接矩阵获得邻接表
*
* @param GA
* @param G
* @return true
* @return false
*/
bool CreateUDG(AMGraph GA, ALGraph &G)
{
G.vexnum = GA.vexnum;
G.arcnum = GA.arcnum;
for (int i = 0; i < G.vexnum; i++)
{
G.vertics[i].data = GA.vexs[i];
G.vertics[i].firstarc = nullptr;
}
for (int i = 0; i < GA.vexnum; i++)
for (int j = GA.vexnum - 1; j >= 0; j--)
{
if (GA.arcs[i][j])
{
ArcNode *p1 = new ArcNode;
p1->adjvex = j;
p1->next = G.vertics[i].firstarc;
G.vertics[i].firstarc = p1;
}
}
return true;
}
/**
* @brief 输出邻接矩阵
*
* @param G
*/
void PrintUDN(AMGraph G)
{
for (int i = 0; i < G.vexnum; i++)
{
for (int j = 0; j < G.vexnum; j++)
{
cout << G.arcs[i][j] << " ";
}
cout << endl;
}
}
/**
* @brief 从v开始深度优先遍历图G
*
* @param G
* @param v
*/
void DFS_AM(AMGraph G, int v)
{
cout << G.vexs[v] << " ";
visited[v] = true;
for (int w = 0; w < G.vexnum; w++)
{
if (G.arcs[v][w] != 0 && !visited[w])
DFS_AM(G, w);
}
}
void DFS_AL(ALGraph G, int v)
{
cout << G.vertics[v].data << " ";
visited[v] = true;
ArcNode *p = G.vertics[v].firstarc;
while (p != nullptr)
{
int w = p->adjvex;
if (!visited[w])
DFS_AL(G, w);
p = p->next;
}
}
/**
* @brief 从v开始广度优先搜索图G
*
* @param G
* @param v
*/
void BFS_AL(ALGraph G, int v)
{
LinkQueue Q;
QElemType u;
cout << G.vertics[v].data << " ";
visited[v] = true;
InitQueue(Q);
EnQueue(Q, v);
while (!QueueEmpty(Q))
{
DeQueue(Q, u);
for (ArcNode *p = G.vertics[u].firstarc; p != nullptr; p = p->next)
{
int w = p->adjvex;
if (!visited[w])
{
cout << G.vertics[w].data << " ";
visited[w] = true;
EnQueue(Q, w);
}
}
}
}
int main()
{
AMGraph G;
ALGraph algraph;
int mode;
printUI();
while (true)
{
cout << "请输入选择:";
cin >> mode;
if (mode == 5)
break;
switch (mode)
{
case 1:
CreateUDN(G);
break;
case 2:
PrintUDN(G);
break;
case 3:
for (int i = 0; i < G.vexnum; i++)
visited[i] = false;
CreateUDG(G, algraph);
DFS_AL(algraph, 0);
cout << endl;
break;
case 4:
for (int i = 0; i < G.vexnum; i++)
visited[i] = false;
CreateUDG(G, algraph);
BFS_AL(algraph, 0);
cout << endl;
break;
}
}
return 0;
}