1、图的邻接矩阵表示法
#include <iostream>
/*
图 G = (V, E);
/ \
n个顶点集合 边的集合(两个顶点之间有没有边)
图分为3种:
无向图、有向图
网(边带权的图)
*/
#define MAXSIZE 100
typedef char VerTexType;//顶点值的数据类型
typedef int ArcType;//无向图、有向图直接用0、1表示两个顶点之间有没有边
//网直接用边的权、无穷大值表示两个顶点之间有没有边
#define NoArc 65535//网的两个顶点之间没有边的情况
typedef struct AMGraph
{
VerTexType vexs[MAXSIZE];//顶点集合 一维数组
ArcType arcs[MAXSIZE][MAXSIZE];//边的集合 二维数组
int curvexs;//当前顶点的数目
int curarcs;//当前边的数目
} AMGraph;
//构造图(初始化)
int CreatUDN(AMGraph & G);
//补充:在图中查找顶点并返回下标
int Locate(AMGraph G, VerTexType v);
int main()
{
return 0;
}
//构造图(初始化)
int CreatUDN(AMGraph & G)
{
/*
1、输入顶点的总数、边的总数
2、构造顶点表
3、构造邻接矩阵
*/
int v;
int a;
std::cout << "Enter the num of Vertexs: ";
std::cin >> v;
G.curvexs = v;
std::cout << "Enter the num of Arcs: ";
std::cin >> a;
G.curarcs = a;
for (int i = 0; i < G.curvexs; i++)
{
std::cout << "Enter the val of Vertexs: ";
std::cin >> G.vexs[i];
}
//初始化--所有顶点之间都没有边
for (int j = 0; j < NoArc; j++)
{
for (int k = 0; k < NoArc; k++)
G.arcs[j][k] = NoArc;
}
/*std::cout << "Enter the val of Arcs: ";
for (int m = 0; m < G.curvexs; m++)
{
for (int n = 0; n < G.curvexs; n++)
std::cin >> G.vexs[m][n];
}*/
//利用无向图的邻接阵是对称的
VerTexType v1, v2;
ArcType weight;//边的权值
int m, n;//用来接收顶点所在顶点表中的位置
for (int k = 0; k < G.curarcs; k++)
{
std::cin >> v1 >> v2 >> weight;//边依附于哪两个顶点
m = Locate(G, v1);
n = Locate(G, v2);
G.arcs[m][n] = G.arcs[n][m] = weight;//无向图的邻接阵是对称阵
}
return 1;
}
//补充:在图中查找顶点并返回下标
int Locate(AMGraph G, VerTexType v)
{
for (int i = 0; i < G.curvexs; i++)
{
if (G.vexs[i] == v)
return i + 1;
}
return 0;
}
2、图的邻接表表示法
#include <iostream>
/*
G = (V, E);
/
n个顶点的集合(顺序存储)一维数组实现
/
要存储的数据
该顶点与哪几个顶点之间有边(非固定的)(边链表实现)
*/
#define MAXSIZE 100
//i顶点的边链表
typedef struct Node
{
int loc;//出度顶点的下标
Node * next;//下一个(出度顶点)链结点的位置
} *LinkList;
//i顶点
typedef char VerTexsType;
typedef struct Vertexs
{
VerTexsType data;
LinkList L;//i顶点的边链表(i顶点与哪些顶点之间有边)
} VerTexs;
//图
typedef struct AMGraph
{
VerTexs vexs[MAXSIZE];
int vexnum;//当前共有多少个顶点
int arcnum;//当前共有多少边
} AMGraph;
//构造1个图
int CreateGraph(AMGraph & G);
//在图中找顶点
int Locate(AMGraph G, VerTexsType v);
int main()
{
return 0;
}
//构造1个图
int CreateGraph(AMGraph & G)
{
/*
1、输入顶点总数、边总数
2、依次输入G的顶点表的值
把顶点表的每个元素的边链表头指针置空
3、输入边依附于的两个顶点
找出顶点对应的下标i, j
新建2个链结点并初始化,分别进行头插 顶点表的头指针
*/
int v, a;
std::cout << "Enter the num of Vertexs: ";
std::cin >> v;
std::cout << "Enter the num of Arcs: ";
std::cin >> a;
G.vexnum = v;
G.arcnum = a;
std::cout << "Enter the val of Vertexs: ";
for (int i = 0; i < G.vexnum; i++)
{
std::cin >> G.vexs[i].data;
G.vexs[i].L = nullptr;
}
std::cout << "Enter the pointer of Vertexs:\n";
std::cout << "Enter the arc between two vertexs: ";
VerTexsType m, n;
int p, q;
Node * ln1, *ln2;
for (int j = 0; j < G.arcnum; j++)
{
std::cin >> m >> n;
p = Locate(G, m);
q = Locate(G, n);
//新建两个链结点
ln1 = new Node;
ln1->loc = p;
ln1->next = nullptr;
ln2 = new Node;
ln2->loc = q;
ln2->next = nullptr;
//分别头插
ln2->next = G.vexs[p].L->next;
G.vexs[p].L = ln2;
ln1->next = G.vexs[q].L->next;
G.vexs[q].L = ln1;
}
return 1;
}
//在图中找顶点
int Locate(AMGraph G, VerTexsType v)
{
for (int i = 0; i < G.vexnum; i++)
{
if (G.vexs[i].data == v)
return i;
}
return -1;
}
3、 BFS广度优先搜索
#include <iostream>
/*
图 G = (V, E);
/ \
n个顶点集合 边的集合(两个顶点之间有没有边)
图分为3种:
无向图、有向图
网(边带权的图)
*/
#define MAXSIZE 100
typedef char VerTexType;//顶点值的数据类型
typedef int ArcType;//无向图、有向图直接用0、1表示两个顶点之间有没有边
//网直接用边的权、无穷大值表示两个顶点之间有没有边
#define NoArc 65535//网的两个顶点之间没有边的情况
typedef struct AMGraph
{
VerTexType vexs[MAXSIZE];//顶点集合 一维数组
ArcType arcs[MAXSIZE][MAXSIZE];//边的集合 二维数组
int curvexs;//当前顶点的数目
int curarcs;//当前边的数目
} AMGraph;
//图的广度优先搜索DFS
void BFS(AMGraph G, int v);
//辅助数组(用来判断i顶点是否被访问过)
int visited[MAXSIZE] = { 0 };//实际长度应该为n个顶点
//单向队列--浪费内存
#define MAXSIZE 100
typedef struct
{
int data[MAXSIZE];//静态数组
int head;//头指针(队头元素)
int rear;//尾指针(队尾元素的下一个位置)
} Queue;
//初始化为空队列
void InitQueue(Queue &Q);
//队空?
int EmptyQueue(Queue Q);
//队满
int FullQueue(Queue Q);
//入队
int EnQueue(Queue & Q, int e);
//出队
int DelQueue(Queue & Q, int & e);
int main()
{
return 0;
}
//图的广度优先搜索DFS
void BFS(AMGraph G, int v)
{
/*
1、从v顶点出发, visited[v] = 1, visited[v]入队;
2、判断队列非空--v顶点出队, 遍历邻接矩阵的第v行v的所有邻接点并入队
*/
Queue Q;
InitQueue(Q);
std::cout << v << '\t';
visited[v] = 1;
EnQueue(Q, v);
int e;
while (!EmptyQueue(Q))
{
DelQueue(Q, e);
for (int w = 0; w < G.curvexs; w++)
{
if (G.arcs[e][w] != 0)
{
std::cout << e << '\t';
visited[w] = 1;
EnQueue(Q, w);
}
}
}
}
//初始化为空队列
void InitQueue(Queue &Q)
{
Q.head = Q.rear = 0;
}
//队空?
int EmptyQueue(Queue Q)
{
if (Q.head == Q.rear)
return 1;
else
return 0;
}
//队满
int FullQueue(Queue Q)
{
if (Q.rear == MAXSIZE)
return 1;
else
return 0;
}
//入队
int EnQueue(Queue & Q, int e)
{
if (!FullQueue(Q))
{
Q.data[Q.rear++] = e;
return 1;
}
else
return 0;
}
//出队
int DelQueue(Queue & Q, int & e)
{
if (!EmptyQueue(Q))
{
e = Q.data[Q.head++];
return 1;
}
else
return 0;
}
4、 DFS深度优先搜索
#include <iostream>
/*
图 G = (V, E);
/ \
n个顶点集合 边的集合(两个顶点之间有没有边)
图分为3种:
无向图、有向图
网(边带权的图)
*/
#define MAXSIZE 100
typedef char VerTexType;//顶点值的数据类型
typedef int ArcType;//无向图、有向图直接用0、1表示两个顶点之间有没有边
//网直接用边的权、无穷大值表示两个顶点之间有没有边
#define NoArc 65535//网的两个顶点之间没有边的情况
typedef struct AMGraph
{
VerTexType vexs[MAXSIZE];//顶点集合 一维数组
ArcType arcs[MAXSIZE][MAXSIZE];//边的集合 二维数组
int curvexs;//当前顶点的数目
int curarcs;//当前边的数目
} AMGraph;
//图的深度优先搜索DFS
void DFS(AMGraph G, int v);
//辅助数组(用来判断i顶点是否被访问过)
int visited[MAXSIZE] = {0};//实际长度应该为n个顶点
int main()
{
return 0;
}
//图的深度优先搜索DFS
void DFS(AMGraph G, int v)
{
/*
1、从v顶点出发, 辅助数组visited[v]置1
2、访问邻接矩阵的第v行
如果第1个非0元素G.arcs[v][w] != 0且该顶点未被访问visited[w] != 1则递归调用DFS(G, w);
递归出口visited[k] = 1且 G.arcs[k][] = 0
*/
std::cout << v << "\t";//输出该顶点信息
visited[v] = 1;
for (int w = 0; w < G.curvexs; w++)//访问邻接矩阵第v行
{
if (G.arcs[v][w] != 0 && visited[w] != 1)//第1个非0元素且顶点未被访问过
DFS(G, w);//则递归调用, 从该顶点出发
}
}