##1。广度优先搜索(BFS)
bool visited[Max_vertex_num];
void BFSTraverse(Graph G) {
for (int i = 0; i < G.vexnum; ++i)
visited[i] = false; // 访问数组初始化
InitQueue(Q);
for (int i = 0; i < G.vexnum; ++i)
{
if(!visited[i])
BFS(G, i); // 访问
}
}
void BFS(Graph G, int v) {
visit(v);
visited[v] = true;
while(!isEmpty(Q)) {
DeQueue(Q, v);
for (w = FirstNeighbor(G, v); w >= 0; w = NextNeighbor(G, v, w)) // 检查所有邻接点
{
if(!visited[w]) {
visit(v);
visit[w] = true;;
EnQueue(Q, w); // 顶点w入队列
} // if
}// for
}// while
}// BFS
##2。BFS求解单源最短路径问题
const int Int_max = 0x7fffffff;
void BFS_mindist(Graph G, int u) {
for (int i = 0; i < G.vexnum; ++i)
d[i] = Int_max; // 初始化初始路径长度
visited[u] = true;
d[u] = 0;
EnQueue(Q, u);
while(!isEmpty(Q)) {
DeQueue(Q, u); // 队头出列
for (w = FirstNeighbor(G, u); w >= 0; w = NextNeighbor(G, u, w))
{
if(!visited[w]) { // 访问尚未访问的邻接顶点
visited[w] = true;
d[w] = d[u] + 1; // 路径长度+1
EnQueue(Q, w); // 顶点入队
} // if
}// for
}// while
}
##3。深度优先搜索(DFS)
// 递归形式
bool visited[Max_vertex_num];
void DFSTraverse(Graph G) {
for (int i = 0; i < G.vexnum; ++i)
visited[i] = false; // 初始化
for (int i = 0; i < G.vexnum; ++i)
if(!visited[i])
DFS(G, i);
}
void DFS(Graph, int v) {
visit(v);
visited[v] = true;
for (w = FirstNeighbor(G, w); w >= 0; w = NextNeighbor(G, v, w))
if(!visited[w]) // 访问尚未访问的顶点
DFS(G, w);
}
/*****************************************************************/
// 非递归形式
bool visited[Max_vertex_num];
void DFS_non_rc(Graph G, int v) {
int w;
InitStack(S);
for (int i = 0; i < G.vexnum; ++i)
visited[i] = false;
Push(S, v);
visited[v] = true;
while(!IsEmpty(S)) {
k = Pop(S);
visit(k);
for(w = FirstNeighbor(G, k); w >= 9; w = NextNeighbor(G, k, w)) {
if(!visited[w]) {
Push(S, w);
visited[w] = true;
}// if
}// for
}// while
}
##4。拓扑排序
// indegree[i]为第i个顶点的入度
bool TopologicalSort(Graph G) {
// 如果G存在拓扑序列,返回true;否则返回false,即G中存在环
InitStack(S);
for (int i = 0; i < G.vexnum; ++i) // 寻找入度为0的点,即无前驱的点
{
if(indegree[i] == 0)
Push(S, i);
}// for
int count = 0; // 记录当前以输出的点的个数
while(!IsEmpty(S)) {
Pop(S, i);
print[count++] = i; // 记录输出顶点
for (p = G.vertices[i].firstarc; p; p = p->nextarc)
{// 将此顶点所指向的顶点的入度减1,减完之后入度为0的点入栈,此步骤即删除顶点和其出边的操作
v = p->adjvex;
if(!(--indegree[v]))
Push(S, v);
}// for
}// while
if(count < G.vexnum) return false; // 若输出点的个数小于图顶点个数,说明图中存在环
else return true;
}
##5。最短路径(Dijkstra)
5.1 邻接矩阵版 O(V^2)
// 邻接矩阵版
const int maxv = 1000;
const int inf = 100000000;
int n, G[maxv][maxv];
int d[maxv];
bool vis[maxv] = {false};
void Dijkstra(int s) {
fill(d, d + maxv, inf); // fill函数将整个d数组赋值为inf
d[s] = 0; // 起点到达自身的距离为0
for (int i = 0; i < n; ++i)
{
int u = -1, min = inf; // u是d[u]最小,min存放该最小的d[u]
// 找到未访问顶点中d[]最小的
for (int j = 0; j < n; ++j)
{
if(!vis[j] && d[j] < min) {
u = j;
min = d[j];
}
}// for
// 若找不到小于inf的d[u],则说明剩下的顶点和起点s不连通
if(u == -1) return ;
vis[u] = true; // 标记u已访问
for (int v = 0; v < n; ++v)
{
// 如果v未访问 且 u能达到v 且 以u为中介可以使d[v]更优
if(!vis[v] && G[u][v] != inf && d[u] + G[u][v] < d[v]) {
d[v] = d[u] + G[u][v]; // 优化d[v]
}
}// for
}// for
}// Dijkstra
5.2 邻接表版 O(V^2)
// 邻接表版
const int maxv = 1000;
const int inf = 100000000;
struct Node
{
int v, dis; // v为顶点, dis表示边权
};
vector adj[maxv]; // 邻接表
int n; // 标记顶点个数
int d[maxv]; // 记录到达各点的最短路径长度
bool vis[maxn] = {false};
void Dijkstra(int s) {
fill(d, d + maxv, inf);
d[s] = 0;
for (int i = 0; i < n; ++i)
{
int u = -1, min = inf;
for (int j = 0; j < n; ++j)
{
if(!vis[j] && d[j] < min) {
u = j;
min = d[j];
}
}// for
// 若找不到小于inf的d[u],则说明剩下的顶点和起点s不连通
if(u == -1) return ;
vis[u] = true;
// 只有此处与邻接矩阵版不同
for (int j = 0; j < adj[u].size(); ++j)
{
int v = adj[u][j].v;
// 如果v未访问 且 u能达到v 且 以u为中介可以使d[v]更优
if(!vis[v] && d[u] + adj[u][j].dis < d[v]) {
d[v] = d[u] + adj[u][j].dis;
}
}// for
}// for
}// Dijkstra
5.3 优先队列改进版
已测试
// 改进版
#include
#include
using namespace std;
const int inf = 100000000;
const int maxn = 510;
int n;
int d[maxn], G[maxn][maxn];
bool vis[maxn] = { false };
typedef pair P; // first是最短距离,second是顶点编号, pair默认以first排序
priority_queue, greater
> pq;
void Dijkstra(int s) {
P p;
int u, v;
fill(d, d + maxn, inf);
d[s] = 0;
vis[s] = true;
while (!pq.empty()) pq.pop(); // 清空
pq.push(P(0, s));
while (!pq.empty()) {
p = pq.top(); pq.pop();
int u = p.second;
if (p.first > d[u]) continue;
vis[u] = true;
for (int v = 0; v < n; v++) {
if (vis[v] == false && G[u][v] != inf) {
if (d[v] > d[u] + G[u][v]) {
d[v] = d[u] + G[u][v];
pq.push(P(d[v], v));
}
}
}
}
}
6。Prim最小生成树
和Dijkstra很相似,由Dijkstra代码修改而来
还没有测试
#include
#include
using namespace std;
const int inf = 100000000;
const int maxn = 510;
int n;
int d[maxn], G[maxn][maxn]; // d[]的定义与 Dijkstra不同,Prim的d[]表示的是顶点与集合S的最短距离
bool vis[maxn] = { false };
typedef pair P; // first是最短距离,second是顶点编号, pair默认以first排序
priority_queue, greater
> pq;
vector pre[v], path, temp;
int Prim(int s) {
P p;
int cost = 0; // 记录最小生成树的边权之和
d[s] = 0; vis[0] = true;
while(!pq.empty()) pq.pop();
pq.push(P(0, s));
while(!pq.empty()) {
p = pq.top(); pq.pop();
int u = p.second;
if(p.first > d[u]) continue;
vis[u] = true;
cost += d[u];
for (int v = 0; v < n; ++v)
{
// 以u为中介点可以使v距离集合S更近
if(!vis[u] && G[u][v] != inf
&& G[u][v] < d[v]) {
d[v] = G[u][v];
pq.push(P(d[v], v));
pre[v].push_back(u); // 记录最小生成树
}
}
}
return cost; // 返回最小生成树的点权之和
}// Prim