Graph
BFS 广度优先遍历
void BFS(Graph& G, int V){
using std::queue;
queue<int> Q;
G.Mark[V]= VISITED;
Visit(G, V);
Q.push(V);
while(!Q.empty())
{
int V=Q.front();
Q.pop();
for(Edge e=G.FirstEdge(V);G.IsEdge(e);e=G.NextEdge(e))
{
if(G.Mark[G.ToVertex(e)]== UNVISITED)
{
G.Mark[G.ToVertex(e)]=VISITED;
Visit(G, G.ToVertex(e));
Q.push(G.ToVertex(e));
}
}
}
}
DFS 深度优先遍历
void DFS(Graph& G, int v) {
G.Mark[v] = VISITED;
Visit(G,v);
for (Edge e = G.FirstEdge(v); G.IsEdge(e); e = G.NextEdge(e))
if (G.Mark[G.ToVertex(e)] == UNVISITED)
DFS(G, G.ToVertex(e));
}
Prim算法
Edge * Prim(AdjGraph& G,int s){
int i,j;
Edge *MST;
int *nearest;
int *neighbor;
int n = G.vertexNum;
nearest = new int[n];
neighbor = new int[n];
MST = new Edge[n-1];
for(i = 0;i < n;i++){
neighbor[i] = s;
nearest[i] = 9999;
}
for(Edge e = G.FirstEdge(s);G.IsEdge(e);e = G.NextEdge(e)){
nearest[e.end] = e.weight;
}
neighbor[s] = -1;
for(i = 1;i < n;i++){
int min = 9999;
int v = -1;
for(j = 0;j < n;j++){
if(nearest[j]<min && neighbor[j]>-1){
min = nearest[j];
v = j;
}
}
if(v > 0){
Edge tempEdge(neighbor[v],v,nearest[v]);
MST[i-1] = tempEdge;
neighbor[v] = -1;
for(Edge e = G.FirstEdge(v);G.IsEdge(e);e = G.NextEdge(e)){
int u = e.end;
if(neighbor[u] != -1&&nearest[u] > e.weight){
neighbor[u] = v;
nearest[u] = e.weight;
}
}
}
}
delete []neighbor;
delete []nearest;
return MST;
}
Kruskal算法
class UFSets{
private:
int n;
int* root;
int* next;
int* length;
public:
UFSets(int size){
n = size;
root = new int[n];
next = new int[n];
length = new int[n];
for(int i = 0;i < n;i++){
root[i] = i;
next[i] = i;
length[i] = 1;
}
}
void swap(int & i,int & j)
{
int temp;
temp = i;
i = j;
j = temp;
}
int Find(int v){
return root[v];
}
void Union(int v,int u);
};
void UFSets::Union(int v,int u){
if(root[u] == root[v])
return;
else if(length[root[v]] < length[root[u]]){
int rt = root[v];
length[root[u]] += length[rt];
root[rt] = root[u];
for(int j = next[rt];j != rt;j = next[j])
root[j] = root[u];
swap(next[rt],next[root[u]]);
}
else{
int rt = root[u];
length[root[v]] += length[rt];
root[rt] = root[v];
for(int j = next[rt];j != rt;j = next[j])
root[j] = root[v];
swap(next[rt],next[root[v]]);
}
}
Edge * Kruskal(Graph& G){
int n = G.vertexNum;
UFSets set(n);
Edge *MST = new Edge[n-1];
Heap<Edge> H(G.edgeNum);
Edge edge;
for(int i = 0;i < G.vertexNum;i++){
for(edge = G.FirstEdge(i);G.IsEdge(edge);edge = G.NextEdge(edge)){
if(G.StartVertex(edge) < G.EndVertex(edge)){
H.Insert(edge);
}
}
}
int edgeNum = 0;
while(edgeNum < n-1){
if(!H.isEmpty()){
H.Delete(edge);
int v = edge.start;
int u = edge.end;
if(set.Find(v) != set.Find(u)){
set.Union(v,u);
MST[edgeNum++] = edge;
}
}
}
return MST;
}
Dijkstra算法
void Dijkstra(Graph &G,int s,int D[],int Path[]){
int n = G.vertexNum;
int i,j;
for(i = 0;i < n;i++){
G.Mark[i] = 0;
D[i] = 9999;
Path[i] = -1;
}
G.Mark[s] = 1;
D[s] = 0;
Path[s] = s;
for(i = 0;i < n;i++){
int min = 9999;
int k = 0;
for(j = 0;j < n;j++){
if(G.Mark[j]==0 && min>D[j]){
min = D[j];
k = j;
}
}
G.Mark[k] = 1;
for(Edge e = G.FirstEdge(k);G.IsEdge(e);e = G.NextEdge(e)){
int endVertex = e.end;
if(G.Mark[endVertex]==0 && D[endVertex]>(D[k]+e.weight)){
D[endVertex] = D[k] + e.weight;
Path[endVertex] = k;
}
}
}
}
Floyd算法
void Floyd(int **Adj,int **Path){
int i,j,v;
int n = vertexNum;
for(i = 0;i < n;i++){
for(j = 0;j < n;j++){
if(i == j){
Adj[i][j] = 0;
Path[i][j] = i;
}
else{
Adj[i][j] = 9999;
Path[i][j] = -1;
}
}
}
for(v = 0;v < n;v++){
for(Edge e = FirstEdge(v);IsEdge(e);e = NextEdge(e)){
Adj[v][e.end] = Weight(e);
Path[v][e.end] = v;
}
}
for(v = 0;v < n;v++)
for(i = 0;i < n;i++)
for(j = 0;j < n;j++)
if(Adj[i][j] > (Adj[i][v]+Adj[v][j])){
Adj[i][j] = Adj[i][v]+Adj[v][j];
Path[i][j] = v;
}
}