《数据结构》-Chapter5-3-图的基础算法

邻接矩阵存储结构

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;
    }
}
发布了51 篇原创文章 · 获赞 1 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/m0_37302219/article/details/104308565