输出结果为:
#include <iostream>
#include <iomanip>
#include <queue>
#include <cstdlib>
#include <string.h>
using namespace std;
#define OK 1;
#define TRUE 1;
#define ERROR 0;
#define FALSE 0;
#define MAX_VERTEX_NUM 25 //最大顶点个数
#define DATA_NUM_PER_LINE 25
typedef enum { DG, DN, UDG, UDN } GraphKind;//{有向图,有向网,无向图,无向网}
typedef int InfoType;
typedef char* VertexType;
typedef int Status;
typedef int VRType;
bool visited[MAX_VERTEX_NUM]; //访问标志数组,定义成全局变量
Status(*VisitFunc)(int v); //函数变量
//图的邻接矩阵表示
typedef struct ArcCell {
VRType adj;//VRType是顶点关系类型。对无权图,用1或0表示是否相邻;对带权图,则为权值类型;
InfoType* info;//该户相关信息的指针
}ArcCell, AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
typedef struct {
VertexType vexs[MAX_VERTEX_NUM];//顶点向量
AdjMatrix arcs;//邻接矩阵
int vexnum, arcnum;//图的当前顶点数合弧数
GraphKind kind;//图的种类标志
}MGraph;
//图的邻接表表示
typedef struct ArcNode {
int adjvex;//该弧所指顶点的位置
struct ArcNode* nextarc;//该弧下一条弧的指针
int weight;
InfoType* info;//该弧相关信息的指针
}ArcNode;
typedef struct VNode {
VertexType data;//顶点信息--名字
ArcNode* firstarc;//指向第一条依附该顶点的弧的指针
}VNode, AdjList[MAX_VERTEX_NUM];
typedef struct {
AdjList vertices;
int vexnum, arcnum;//图的当前顶点数合弧数
GraphKind kind;//图的种类标志
}ALGraph;
Status CreateUDN_AdjMatrix(MGraph& G)
{
G.vexnum = 25;
for (int i = 0; i < 25; i++)
{
for (int j = 0; j < 25; j++)
{
G.arcs[i][j].adj = INT_MAX;
}
}
G.arcs[0][1].adj = 137; G.arcs[0][2].adj = 695; G.arcs[0][15].adj = 668;
G.arcs[1][10].adj = 674; G.arcs[1][12].adj = 704;
G.arcs[2][3].adj = 534; G.arcs[2][10].adj = 349; G.arcs[2][16].adj = 511;
G.arcs[3][4].adj = 409;
G.arcs[4][5].adj = 675; G.arcs[4][7].adj = 367; G.arcs[4][19].adj = 902; G.arcs[4][20].adj = 672;
G.arcs[5][6].adj = 140;
G.arcs[7][8].adj = 633; G.arcs[7][9].adj = 825;
G.arcs[9][10].adj = 651;
G.arcs[11][12].adj = 397;
G.arcs[12][13].adj = 305;
G.arcs[13][14].adj = 241;
G.arcs[15][22].adj = 1145;
G.arcs[16][17].adj = 842; G.arcs[16][22].adj = 676;
G.arcs[17][18].adj = 1100; G.arcs[17][19].adj = 967;
G.arcs[18][19].adj = 639;
G.arcs[19][20].adj = 607;
G.arcs[20][21].adj = 255;
G.arcs[22][23].adj = 216; G.arcs[22][24].adj = 1892;
for (int i = 0; i < G.vexnum; i++) {
G.vexs[i] = (char*)malloc(20 * sizeof(char));
}
const char* name[] = { "北京","天津","哈尔滨","长春","沈阳","大连","呼和浩特","乌鲁木齐","西宁","兰州","西安","郑州",
"徐州","上海","武汉","成都","昆明","贵阳","南宁","柳州","株洲","南昌","福州","广州","深圳" };
for (int i = 0; i < G.vexnum; ++i)
{
strcpy(G.vexs[i], name[i]);
}
for (int i = 0; i < 25; i++)
{
for (int j = 0; j < 25; j++)
{
G.arcs[j][i].adj = G.arcs[i][j].adj;//由于构造的是无向网,所以还需要置<v1,v2>的对称弧<v2,v1>
}
}
return OK;
}
Status CreateUDN_AdjList(MGraph& g, ALGraph& G)
{
int i, j;
ArcNode* p;
ALGraph* pG;
pG = (ALGraph*)malloc(sizeof(ALGraph));
if (pG) G = *pG;
for (int i = 0; i < g.vexnum; i++) {
G.vertices[i].data = (char*)malloc(20 * sizeof(char));
}
for (int i = 0; i < g.vexnum; ++i)
{
strcpy(G.vertices[i].data, g.vexs[i]);
}
for (i = 0; i < g.vexnum; i++)
G.vertices[i].firstarc = NULL;
for (i = 0; i < g.vexnum; i++)
{
for (j = g.vexnum - 1; j >= 0; j--)
{
if (g.arcs[i][j].adj != INT_MAX)
{
p = (ArcNode*)malloc(sizeof(ArcNode));
p->adjvex = j;
p->weight = g.arcs[i][j].adj;
p->nextarc = G.vertices[i].firstarc;
G.vertices[i].firstarc = p;
}
}
}
G.vexnum = g.vexnum;
G.arcnum = g.arcnum;
return OK;
}
Status LocateVex(MGraph& G, VertexType v) //若找到结点返回i
{//查找顶点v
for (int i = 0; i <= G.vexnum; ++i)
{
if (!strcmp(G.vexs[i], v))
{
return i;
}
}
return -1; //否则返回-1,表示没有找到
}
Status DestroyGraph(MGraph& G)
{//返回值:状态码,操作成功返回OK,作用:销毁图G
//若是网
if (G.kind % 2) //重置邻接矩阵所有顶点之间不可达
{
for (int i = 0; i < G.vexnum; i++)
{
for (int j = 0; j < G.vexnum; j++)
{
G.arcs[i][j].adj = INT_MAX;
}
}
}
else
{ //若是图 ,重置邻接矩阵所有顶点之间不可达
for (int i = 0; i < G.vexnum; i++)
{
for (int j = 0; j < G.vexnum; j++)
{
G.arcs[i][j].adj = 0;
}
}
}
G.vexnum = 0;//重置顶点数为0
G.arcnum = 0;//重置边数为0
return OK;
}
Status PrintAdjMatrix(MGraph& G)
{//打印邻接矩阵
int p = 1;
cout << "AdjMatrix:" << endl;
cout << " ";
for (int i = 0; i < G.vexnum; i++) //输出邻接矩阵的上坐标(全部顶点)
{
cout <<setw(5)<< i+1;
}
cout << endl;
for (int i = 0; i < G.vexnum; i++)//输出邻接矩阵的左坐标(全部顶点)和内容
{
cout << setw(2) <<i+1;//输出邻接矩阵左边的坐标
for (int j = 0; j < G.vexnum; j++, p++)
{
if (G.arcs[i][j].adj == INT_MAX)
{
cout << " ∞";
}
if (G.arcs[i][j].adj != INT_MAX)
{
cout << setw(5) << G.arcs[i][j].adj;
}
if (p % DATA_NUM_PER_LINE == 0)
cout << endl;
}
}
cout << "PrintAdjMatrix Over" << endl << endl;
return OK;
}
Status PrintAdjList(ALGraph& G)
{//打印邻接表
cout << "AdjList:" << endl;
for (int i = 0; i < G.vexnum; i++)
{//顶点
ArcNode* p = G.vertices[i].firstarc;
cout << G.vertices[i].data<<'\t';
while (p)
{
cout << '\t' <<"->" << G.vertices[i].data<<"("<<p->weight<<")";
p = p->nextarc;
}
cout << endl;
}
cout << endl;
return OK;
}
Status FirstAdjVex(MGraph G, VertexType v)
{//求顶点v在图G中的第一个邻接点
int j = 0;//j表示不可达,在图中,0表示不可达,在网中INT_MAX表示不可达
int k = LocateVex(G, v); //v是顶点,不是序号!需要定位 //k就是顶点v在顶点数组中的序号
if (G.kind == DN || G.kind == UDN) //若是网,则INT_MAX表示不可达
{
j = INT_MAX;
}
for (int i = 0; i < G.vexnum; ++i) //在顶点v对应的第k行查找第一个邻接点的序号i
{
if (G.arcs[k][i].adj != j)
{
return i;
}
}
return -1; //若未找到返回-1
}
Status NextAdjVex(MGraph G, VertexType v, VertexType w)
{//求顶点v在图G中相对于邻接点w的下一个邻接点
int j = 0;//j表示不可达,在图中,0表示不可达,在网中INT_MAX表示不可达
int k1 = LocateVex(G, v);//k1是顶点v在顶点数组中的位序
int k2 = LocateVex(G, w);//k2是顶点w在顶点数组中的位序
if (G.kind == DN || G.kind == UDN)//若是网,则使用INT_MAX表示不可达
{
j = INT_MAX;
}
for (int i = k2 + 1; i < G.vexnum; ++i) //在图G中查找顶点v相对于顶点w的下一个邻接点的位置
{//若找到则返回i
if (G.arcs[k1][i].adj != j)
{
return i;
}
}
return -1;//若未找到返回-1
}
void DFS_AdjMatrix(MGraph& G, int i)
{//从节点i开始DFS遍历
int j;
cout << G.vexs[i] << '\t';//输出起始结点
visited[i] = TRUE;//将已访问的结点标志成1
for (j = 0; j < G.vexnum; j++)//依次搜索vi的邻接点
{
if (G.arcs[i][j].adj != INT_MAX && !visited[j])//当满足有边且未被访问过时,递归调用去查找该邻接点
{
DFS_AdjMatrix(G, j);//注意此处的G已经是指针类型,不需要再&G
}
}
}
void DFSTraverse_AdjMatrix(MGraph G)
{//邻接矩阵的深度优先遍历
int i;//初始化"标志"数组为0,代表未访问
for (i = 0; i < G.vexnum; i++)
{
visited[i] = 0;
}
for (i = 0; i < G.vexnum; i++)
{
if (!visited[i])
{
DFS_AdjMatrix(G, i);
}
}
cout << endl << endl;
}
void BFSTraverse_AdjMatrix(MGraph G)
{//邻接矩阵的广度优先遍历
int i, j;//数组初始化为全0
queue<int>Q;
for (i = 0; i < G.vexnum; i++)
{
visited[i] = 0;
}
for (i = 0; i < G.vexnum; i++)
{
if (!visited[i])
{
cout << G.vexs[i] << '\t';//输出当前结点
visited[i] = 1;//将已访问的结点标志成1
Q.push(i);//将已访问结点入队
while (!Q.empty())
{
j = Q.front();
Q.pop();
//接下来访问节点j的邻接节点
for (int m = 0; m < G.vexnum; m++) {
if (G.arcs[j][m].adj != INT_MAX && !visited[m]) //邻接且未访问
{
cout << G.vexs[m] << '\t'; //输出顶点
visited[m] = 1; //设置成已访问状态1
Q.push(m);
}
}
}
}
}
cout << endl << endl;
}
void DFS_AdjList(ALGraph& G, ArcNode* p)
{//从p所指节点开始DFS遍历,邻接链表
cout << G.vertices[p->adjvex].data << '\t';//输出起始结点
visited[p->adjvex] = TRUE;//将已访问的结点标志成1
p = G.vertices[p->adjvex].firstarc;
while (p) {
if (!visited[p->adjvex]) DFS_AdjList(G, p);
p = p->nextarc;
}
}
void DFSTraverse_AdjList(ALGraph G)
{//邻接表的深度优先遍历
int i;//初始化"标志"数组
ArcNode* p;
for (i = 0; i < G.vexnum; i++)
{
visited[i] = 0;
}
for (i = 0; i < G.vexnum; i++)
{
if (!visited[i])
{
cout << G.vertices[i].data << '\t';//访问当前节点
visited[i] = TRUE;//将当前节点标记成已访问结点
p = G.vertices[i].firstarc;
while (p) //依次搜索vi的邻接点
{
if (!visited[p->adjvex]) DFS_AdjList(G, p);
p = p->nextarc;//查找下一个邻接节点
}
}
}
cout << endl << endl;
}
void BFSTraverse_AdjList(ALGraph G)
{//邻接表的广度优先遍历
int i, j;
queue<int> Q;
ArcNode* p;
for (i = 0; i < G.vexnum; i++)
{
visited[i] = 0;
}
for (i = 0; i < G.vexnum; i++)
{
if (!visited[i])
{
cout << G.vertices[i].data << '\t';//输出当前结点
visited[i] = 1;//将已访问的结点标志成1
Q.push(i);//将已访问结点入队
while (!Q.empty())
{
j = Q.front();
Q.pop();
//接下来访问节点j的邻接节点
p = G.vertices[j].firstarc;
while (p) {
if (!visited[p->adjvex]) {
cout << G.vertices[p->adjvex].data << '\t';//访问当前节点
visited[p->adjvex] = TRUE;//将当前节点标记成已访问结点
Q.push(p->adjvex);
}
p = p->nextarc;
}
}
}
}
cout << endl << endl;
}
int main()
{
system("color F0");
MGraph G1;
ALGraph G2;
CreateUDN_AdjMatrix(G1);
cout << "所有顶点为:" << endl;
for (int i = 0; i < G1.vexnum; i++)
{
cout <<setw(5)<<setfill(' ')<< i + 1 << "." << G1.vexs[i];
if ((i+1)% 10 == 0) cout << endl;
}
cout << endl;
CreateUDN_AdjList(G1, G2);
PrintAdjMatrix(G1);//打印邻接矩阵
PrintAdjList(G2);//打印邻接表
cout << "邻接矩阵的深度优先遍历" << endl;
DFSTraverse_AdjMatrix(G1);//邻接矩阵的深度优先遍历
cout << "邻接矩阵的广度优先遍历" << endl;
BFSTraverse_AdjMatrix(G1);//邻接矩阵的广度优先遍历
cout << "邻接表的深度优先遍历" << endl;
DFSTraverse_AdjList(G2);//邻接表的深度优先遍历
cout << "邻接表的广度优先遍历" << endl;
BFSTraverse_AdjList(G2);//邻接表的广度优先遍历
system("pause");
return 0;
}