邻接矩阵存储结构
typedef struct {
int no;
}VertexType;
typedef struct {
int edges[maxSize][maxSize];
int n,
e;
VertexType vex[maxSize];
}MGraph;
邻接表存储结构
typedef struct ArcNode {
int adjvex;
struct ArcNode * nextarc;
}ArcNode;
typedef struct {
char data;
ArcNode * firstarc;
}VNode;
typedef struct {
VNode adjlist[maxSize];
int n,
e;
}AGraph;
广度优先遍历算法
public class BFSearch {
/**
* 广度优先搜索
* BFSearch
* @param node
* 搜索的入口节点
*/
public void searchTraversing(GraphNode node) {
List <GraphNode> visited = new ArrayList <GraphNode>(); // 已经被访问过的元素
Queue <GraphNode> q = new LinkedList <GraphNode>(); // 用队列存放依次要遍历的元素
q.offer(node);
while (!q.isEmpty()) {
GraphNode currNode = q.poll();
if (!visited.contains(currNode)) {
visited.add(currNode);
System.out.println("节点:" + currNode.getLabel());
for (int i = 0; i < currNode.edgeList.size(); i++) {
q.offer(currNode.edgeList.get(i).getNodeRight());
}
}
}
}
}
深度优先遍历算法
int verNum;
int visited[verNum];
void DFS_Traverse(Graph G) {
for(int v=0;v<G.verNum;v++){
if(visited[v]==0)
DFS(G,v);
}
}
void DFS(Graph G,int v) {
visit(v);
visited[v]=1;
for(int w=G.getFirstNeighbor(v);w>=0;p=getNextNeighbor(v,w)){
if(visited[w]==0) DFS(G,w);
}
}
Prim
Prim void Prim(MGraph g, int v0, int & sum) {
int lowcost[maxSize],
vset[maxSize],v;
int i,j,k,min;
v = v0;
for (i = 0; i < g.n; ++i) {
lowcost[i] = g.edges[v0][i];
vset[i] = 0;
}
vset[v0] = 1; //将v0并入树中
sum = 0; //sum清零用来累计树的权值
for (i = 0; i < g.n - 1; ++i) {
min = INF; //INF是一个已经定义的比图中所有边权值都大的常量
/* 下面这个循环用于选出候选边中的最小者 */
for (j = 0; j < g.n; ++j) if (vset[j] == 0 && lowcost[j] < min) //选出当前生成树到其余顶点
{ //最短边中最短的一条(注意这里两个最短的含义)
min = lowcost[j];
k = j;
}
vset[k] = 1;
v = k;
sum += min; //这里用sum记录了最小生成树的权值
for (j = 0; j < g.n; ++j)
if (vset[j] == 0 && g.edges[v][j] < lowcost[j])
lowcost[j] = g.edges[v][j];
}
}
Kruskal
typedef struct {
int a,
b; //a和b为一条边所连的两个顶点
int w; //边的权值
}Road;
Road road[maxSize];
int v[maxSize]; //定义并查集数组
int getRoot(int a) //在并查集中查找根节点的函数
{
while (a != v[a]) a = v[a];
return a;
}
void Kruskal(MGraph g, int & sum, Road road[]) {
int i;
int N,E,a,b;N = g.n;
E = g.e;
sum = 0;
for (i = 0; i < N; ++i) v[i] = i;
sort(road, E); //对road数组中的E条边按其权值从小到大排序
for (i = 0; i < E; ++i) {
a = getRoot(road[i].a);
b = getRoot(road[i].b);
if (a != b) {
v[a] = b;
sum += road[i].w;
}
}
}
Dijkstra
void Dijkstra(MGraph g, int v, int dist[], int path[]) {
int set[maxSize];
int min,j,k,u;
/* 从这句开始对各数组进行初始化 */
for (i = 0; i < g.n; ++i) {
dist[i] = g.edges[v][i];
set[i] = 0;
if (g.edges[v][i] < INF) path[i] = v;
else path[i] = -1;
}
set[v] = 1;
path[v] = -1;
/* 初始化结束 */
/* 关键操作开始 */
for (i = 0; i < g.n - 1; ++i) {
min = INF;
/* 这个循环每次从剩余顶点中选出一个顶点,通往这个顶点的路径在通往所有剩余顶点的路径中是长度最短的 */
for (j = 0; j < g.n; ++j) if (set[j] == 0 && dist[j] < min) {
u = j;
min = dist[j];
}
set[u] = 1;
/* 这个循环以刚并入的顶点作为中间点,对所有通往剩余顶点的路径进行检测 */
for (j = 0; j < g.n; ++j) {
/* 这个if语句判断顶点u的加入是否会出现通往顶点j的更短的路径,如果出现,则改变原来路径及其长度,否则什么都不做 */
if (set[j] == 0 && dist[u] + g.edges[u][j] < dist[j]) {
dist[j] = dist[u] + g.edges[u][j];
path[j] = u;
}
}
}
/* 关键操作结束 */
}
Floyd
void Floyd(MGraph g, int Path[][MaxSize]) {
int i,j,k;
int A[MaxSize][MaxSize];
/* 这个双循环对数组A[][]和Path[][]进行了初始化 */
for (i = 0; i < g.n; ++i) {
A[i][j] = g.edges[i][j];
Path[i][j] = -1;
}
/* 下面这个三重循环是本算法的主要操作,完成了以k为中间点对所有的顶点对{i,j}进行检测和修改 */
for (k = 0; k < g.n; ++k) for (i = 0; i < g.n; ++i) for (j = 0; j < g.n; ++j) if (A[i][j] > A[i][k] + A[k][j]) {
A[i][j] = A[i][k] + A[k][j];
Path[i][j] = k;
}
}