IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 【数据结构与算法】3. 图[笔记] -> 正文阅读

[数据结构与算法]【数据结构与算法】3. 图[笔记]

Notes
  1. 数据结构:图 的操作集 C/C++代码实现

1. 图 - 邻接矩阵

#include <iostream>
using namespace std;

#define MaxVertexNum 100        // 最大顶点数
typedef int WeightType;         // 权值
typedef int Vertex;             // 顶点
typedef int DataType;           // 数据

// 边
typedef struct ENode *PtrToENode;
struct ENode{
    Vertex V1, V2;              // < V1, V2 > 有向边
    WeightType Weight;          // 权重
};
typedef PtrToENode Edge;

// 图
typedef struct GNode *PtrToGNode;
struct GNode{
    int Nv;                     // 顶点数
    int Ne;                     // 边数
    WeightType G[MaxVertexNum][MaxVertexNum];   // 邻接矩阵
    DataType Data[MaxVertexNum];                // 数据
};
typedef PtrToGNode MGraph;

MGraph CreateGraph(int VertexNum);          // 初始化图
void InsertEdge(MGraph Graph, Edge E);      // 插入边
MGraph BuildGraph();                        // 建图

MGraph CreateGraph(int VertexNum)
{
    Vertex v, w;
    MGraph Graph = new struct GNode;
    Graph->Nv = VertexNum;
    Graph->Ne = 0;

    for(v=0; v<VertexNum; v++)
        for(w=0; w<VertexNum; w++)  Graph->G[v][w] = 0;

    return Graph;
}

void InsertEdge(MGraph Graph, Edge E)
{
    Graph->G[E->V1][E->V2] = E->Weight;
    // 若为无向图,需要插入下面那行
    Graph->G[E->V2][E->V1] = E->Weight;
}

MGraph BuildGraph()
{
    MGraph Graph;
    Edge E;
    Vertex V;
    int Nv;
    cin >> Nv;
    Graph = CreateGraph(Nv);
    cin >> Graph->Ne;
    if(Graph->Ne != 0)
    {
        E = new struct ENode;
        for(int i=0; i<Graph->Ne; i++)
        {
            cin >> E->V1 >> E->V2 >> E->Weight;
            InsertEdge(Graph, E);
        }
    }
    return Graph;
}





2. 图 - 邻接表

#include <iostream>
using namespace std;

#define MaxVertexNum 100        // 最大顶点数
typedef int Vertex;             // 顶点
typedef int WeightType;         // 边的权值
typedef int DataType;           // 数据

// 边
typedef struct ENode *PtrToENode;
struct ENode{
    Vertex V1, V2;          // 有向边 <V1, V2>
    WeightType Weight;      // 权重
};
typedef PtrToENode Edge;

// 邻接点
typedef struct AdjVNode *PtrToAdjVNode; 
struct AdjVNode{
    Vertex ADjV;            // 邻接点下标
    WeightType Weight;      // 边权重
    PtrToAdjVNode Next;     // 指针
};

// 顶点表头结点
typedef struct VNode{
    PtrToAdjVNode FirstEdge;    // 边表头结点
    DataType Data;              // 数据
}AdjList[MaxVertexNum];         // 邻接表类型

// 图
typedef struct GNode *PtrToGNode;
struct GNode{
    int Nv;                     // 顶点数
    int Ne;                     // 边数
    AdjList G;                  // 邻接表
};
typedef PtrToGNode LGraph;      // 邻接表-图类型

// 操作集
LGraph CreateGraph(int VertexNum);      // 初始化图
void InsertEdge(LGraph Graph, Edge E);  // 插入边
LGraph BuildGraph();                    // 建图

// 操作集实现
LGraph CreateGraph(int VertexNum)
{
    Vertex v, w;
    LGraph Graph = new struct GNode;
    Graph->Nv = VertexNum;
    Graph->Ne = 0;

    for(v=0; v<Graph->Nv; v++)  Graph->G[v].FirstEdge = NULL;
    return Graph;
}

void InsertEdge(LGraph Graph, Edge E)
{
    PtrToAdjVNode newNode;
    newNode = new struct AdjVNode;
    // 插入 <V1, V2>
    newNode->ADjV = E->V2;
    newNode->Weight = E->Weight;
    newNode->Next = Graph->G[E->V1].FirstEdge;  // 旧表头接在新结点的后面
    Graph->G[E->V1].FirstEdge = newNode;        // 新结点成为新的表头

    // 插入 <V2, V1>   <---- 无向图
    newNode = new struct AdjVNode;
    newNode->ADjV = E->V1;
    newNode->Weight = E->Weight;
    newNode->Next = Graph->G[E->V2].FirstEdge;  // 旧表头接在新结点的后面
    Graph->G[E->V2].FirstEdge = newNode;        // 新结点成为新的表头
}

LGraph BuildGraph()
{
    LGraph Graph;
    Edge E;
    Vertex V;
    int Nv;
    cin >> Nv;
    Graph = CreateGraph(Nv);
    cin >> Graph->Ne;
    if(Graph->Ne)
        for(int i=0; i<Graph->Ne; i++)
        {
            E = new struct ENode;
            cin >> E->V1 >> E->V2 >> E->Weight;
            InsertEdge(Graph, E);
        }
    return Graph;
}





3. DFS - 深度优先搜索

#include <iostream>
using namespace std;
// DFS 深度优先搜索 算法

bool Visited[10] = {0};

#define MaxVertexNum 100        // 最大顶点数
typedef int Vertex;             // 顶点
typedef int WeightType;         // 边的权值
typedef int DataType;           // 数据

// 边
typedef struct ENode *PtrToENode;
struct ENode{
    Vertex V1, V2;          // 有向边 <V1, V2>
    WeightType Weight;      // 权重
};
typedef PtrToENode Edge;

// 邻接点
typedef struct AdjVNode *PtrToAdjVNode; 
struct AdjVNode{
    Vertex ADjV;            // 邻接点下标
    WeightType Weight;      // 边权重
    PtrToAdjVNode Next;     // 指针
};

// 顶点表头结点
typedef struct VNode{
    PtrToAdjVNode FirstEdge;    // 边表头结点
    DataType Data;              // 数据
}AdjList[MaxVertexNum];         // 邻接表类型

// 图
typedef struct GNode *PtrToGNode;
struct GNode{
    int Nv;                     // 顶点数
    int Ne;                     // 边数
    AdjList G;                  // 邻接表
};
typedef PtrToGNode LGraph;      // 邻接表-图类型

// 操作集
void Visit(Vertex V);
void DFS(LGraph Graph, Vertex V);

void Visit(Vertex V)
{
    cout << "This Vertex is: " << V << endl;
}

void DFS(LGraph Graph, Vertex V, void (*Visit)(Vertex))
{
    PtrToAdjVNode W;
    Visit(V);
    Visited[V] = true;

    for(W=Graph->G[V].FirstEdge; W; W=W->Next)
        if(!Visited[W->ADjV])  DFS(Graph, W->ADjV, Visit);
}





4. BFS - 广度优先搜索

#include <iostream>
#include <queue>
using namespace std;
// BFS 广度优先搜索 算法


#define MaxVertexNum 100        // 最大顶点数
typedef int WeightType;         // 权值
typedef int Vertex;             // 顶点
typedef int DataType;           // 数据
bool Visited[10] = {0};

// 边
typedef struct ENode *PtrToENode;
struct ENode{
    Vertex V1, V2;              // < V1, V2 > 有向边
    WeightType Weight;          // 权重
};
typedef PtrToENode Edge;

// 图
typedef struct GNode *PtrToGNode;
struct GNode{
    int Nv;                     // 顶点数
    int Ne;                     // 边数
    WeightType G[MaxVertexNum][MaxVertexNum];   // 邻接矩阵
    DataType Data[MaxVertexNum];                // 数据
};
typedef PtrToGNode MGraph;

// 操作集
bool IsEdge(MGraph Graph, Vertex V, Vertex W);
void BFS(MGraph Graph, Vertex S, void (*Visit)(Vertex));
void Visit(Vertex V);


void Visit(Vertex V)
{
    cout << "This Vertex is: " << V << endl;
}

bool IsEdge(MGraph Graph, Vertex V, Vertex W)
{
    return (Graph->G[V][W]>0?true:false);
}

void BFS(MGraph Graph, Vertex S, void (*Visit)(Vertex))
{
    queue <Vertex> Q;
    Vertex V, W;

    Visit(S);
    Visited[S] = true;
    Q.push(S);

    while(!Q.empty())
    {
        V = Q.front();
        Q.pop();
        for(W=0; W<Graph->Nv; W++)
            if(!Visited[W] && IsEdge(Graph, V, W))
            {
                Visit(W);
                Visited[W] = true;
                Q.push(W);
            }
    }
}





5. 例题 - 六度空间 ( BFS算法邻接矩阵图 )

#include <iostream>
#include <cstdio>
#include <queue>
using namespace std;
// 例题:六度空间 ---> BFS算法 - 邻接矩阵图

int ENode[1001][1001] = {0};
int Nv, Ne;

int BFS(int v)
{
    queue <int> Q;
    bool visited[1001] = {false};
    Q.push(v);
    int cnt=0, level=0, last=v, tail=v;
    while(!Q.empty())
    {
        v = Q.front();
        Q.pop();
        for(int w=1; w<=Nv; w++)
            if(!visited[w] && ENode[v][w])  Q.push(w), cnt++, tail = w, visited[w] = true;
            else continue;
        // cout << "V: " << v << ' ' << "Level:" << level << ' ' << tail << endl;
        if(v == last)  level++, last = tail;
        if(level == 6)  break;
    }
    return cnt;
}

int main()
{
    cin >> Nv >> Ne;
    for(int i=1; i<=Ne; i++)
    {
        int v, w;
        cin >> v >> w;
        ENode[v][w] = 1;
        ENode[w][v] = 1;
    }
    for(int v=1; v<=Nv; v++)
    {
        float tmp = BFS(v)/(Nv*1.0)*100;
        cout << v << ": ";
        printf("%.2f%\n", tmp);
    }
    return 0;
}





6. 无权图的最短路径问题

#include <iostream>
#include <queue>
#include <vector>
using namespace std;
// 邻接矩阵 - 无权图的单源最短路算法

#define MaxVertexNum 100        // 最大顶点数
typedef int WeightType;         // 权值
typedef int Vertex;             // 顶点
typedef int DataType;           // 数据

vector <int> dist(MaxVertexNum, -1);     // 存储路径, 并初始化为 -1      
vector <int> path(MaxVertexNum);         // 存储路径长度

// 边
typedef struct ENode *PtrToENode;
struct ENode{
    Vertex V1, V2;              // < V1, V2 > 有向边
    WeightType Weight;          // 权重
};
typedef PtrToENode Edge;

// 图
typedef struct GNode *PtrToGNode;
struct GNode{
    int Nv;                     // 顶点数
    int Ne;                     // 边数
    WeightType G[MaxVertexNum][MaxVertexNum];   // 邻接矩阵
    DataType Data[MaxVertexNum];                // 数据
};
typedef PtrToGNode MGraph;

/* 邻接矩阵 - 无权图的单源最短路算法 */
void Unweighted(MGraph Graph, Vertex V);

void Unweighted(MGraph Graph, Vertex V)
{
	queue<Vertex> Q;
    dist[V] = 0, path[V] = -1;
    Q.push(V);
    while(!Q.empty())
    {
        V = Q.front();
        Q.pop();
        for(Vertex W=0; W < Graph->Nv; W++)
            if(Graph->G[V][W] && dist[W] == -1)
            {
                dist[W] = dist[V] + 1;
                path[W] = V;
                Q.push(W);
            }
    }
}





7. 邻接矩阵 - 有权图的单源最短路算法 - Dijkstra算法

#include <iostream>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;
// 邻接矩阵 - 有权图的单源最短路算法 - Dijkstra算法

#define MaxVertexNum 100        // 最大顶点数
#define Maxdist 100000000        // 最大顶点数
typedef int WeightType;         // 权值
typedef int Vertex;             // 顶点
typedef int DataType;           // 数据

vector <int> dist(MaxVertexNum, -1);              // 存储路径, 并初始化为 -1      
vector <int> path(MaxVertexNum, Maxdist);         // 存储路径长度, 并初始化为 Maxdist
vector <bool> collected(MaxVertexNum, false);     // 判断该Vertex是否收集, 并初始化为 false

// 边
typedef struct ENode *PtrToENode;
struct ENode{
    Vertex V1, V2;              // < V1, V2 > 有向边
    WeightType Weight;          // 权重
};
typedef PtrToENode Edge;

// 图
typedef struct GNode *PtrToGNode;
struct GNode{
    int Nv;                     // 顶点数
    int Ne;                     // 边数
    WeightType G[MaxVertexNum][MaxVertexNum];   // 邻接矩阵
    DataType Data[MaxVertexNum];                // 数据
};
typedef PtrToGNode MGraph;

/* 邻接矩阵 - Dijkstra算法 */
void Dijkstra(MGraph Graph, Vertex V);

void Dijkstra(MGraph Graph, Vertex V)
{
    dist[V] = 0, path[V] = -1;
    collected[V] = true;
    for(Vertex W=0; W<Graph->Nv; W++)
        if(Graph->G[V][W])
        {
            dist[W] = dist[V] + Graph->G[V][W];
            path[W] = V;
        }

    while(1)
    {
        for(Vertex W=0; W<Graph->Nv; W++)
            if(V != W && !collected[W])  V = min(dist[W], Maxdist);
            else  V = 0;
        
        if(!V)  break;
        
        collected[V] = true;
        
        for(Vertex W=0; W<Graph->Nv; W++)
            if(Graph->G[V][W] && !collected[W])
                if(dist[V] + Graph->G[V][W] < dist[W])
                {
                    dist[W] = dist[V] + Graph->G[V][W];
                    path[W] = V;
                }
    }
}





8. 邻接矩阵 - 有权图的多源最短路算法 - Floyd算法

#include <iostream>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;
// 邻接矩阵 - 有权图的多源最短路算法 - Floyd算法

#define MaxVertexNum 100        // 最大顶点数
#define Maxdist 100000000        // 最大顶点数
typedef int WeightType;         // 权值
typedef int Vertex;             // 顶点
typedef int DataType;           // 数据

vector<vector<int>> dist(MaxVertexNum, vector<int>(MaxVertexNum, 0));          // 存储路径长度, 并初始化为 0      
vector<vector<int>> path(MaxVertexNum, vector<int>(MaxVertexNum, -1));         // 存储路径, 并初始化为 -1  

// 边
typedef struct ENode *PtrToENode;
struct ENode{
    Vertex V1, V2;              // < V1, V2 > 有向边
    WeightType Weight;          // 权重
};
typedef PtrToENode Edge;

// 图
typedef struct GNode *PtrToGNode;
struct GNode{
    int Nv;                     // 顶点数
    int Ne;                     // 边数
    WeightType G[MaxVertexNum][MaxVertexNum];   // 邻接矩阵
    DataType Data[MaxVertexNum];                // 数据
};
typedef PtrToGNode MGraph;

/* 邻接矩阵 - Floyd算法 */
void Floyd(MGraph Graph, Vertex V);

void Floyd(MGraph Graph, Vertex V)
{
    Vertex i, j, k;
    for(i=0; i<Graph->Nv; i++)
        for(j=0; j<Graph->Nv; j++)
            if(i!=j)                                                // dist[i][j] 初始化为 0, 所以 i=j对角 均跳过(为默认值0)
                if(Graph->G[i][j])  dist[i][j] = Graph->G[i][j];    // 若Graph->G[i][j] 为 0, 则判定为 无边,因此初始化为Maxdist;
                else  dist[i][j] = Maxdist;

    for(k=0; k<Graph->Nv; k++)
        for(i=0; i<Graph->Nv; i++)
            for(j=0; j<Graph->Nv; j++)
                if(dist[i][k] + dist[k][j] < dist[i][j])  dist[i][j] = dist[i][k] + dist[k][j], path[i][j] = k;
}





9. 例题 - 哈利·波特的考试 ( BFS + Floyd 算法 )

#include <iostream>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;
// 邻接矩阵 - BFS + Floyd 算法

struct animalTra{
    int Ne;
    int Nv;
    int Weight[102][102] = {0};
};
typedef struct animalTra AniTran;

bool BFS_LT(AniTran Graph)
{
    queue <int> Q;
    Q.push(1);
    int v;
    bool res = true;
    int checked[102] = {0};
    checked[1] = 1;

    while(!Q.empty())
    {
        v = Q.front();
        Q.pop();
        for(int w=2; w<=Graph.Nv; w++)
            if(Graph.Weight[v][w] && !checked[w])
            {
                Q.push(w);
                checked[w] = 1;
            }
    }

    for(int w=1; w<=Graph.Nv; w++)
        if(checked[w] == 0)  res = false;

    return res;
}

void Floyd(AniTran Graph)
{
    vector <vector <int>> dist(102, vector<int>(102, 0));
    int res[102] = {0}, resMin = 102;

    for(int i=1; i<=Graph.Nv; i++)
        for(int j=1; j<=Graph.Nv; j++)
            if(i!=j)
                if(Graph.Weight[i][j])  dist[i][j] = Graph.Weight[i][j];
                else dist[i][j] = 102;
    
    for(int k=1; k<=Graph.Nv; k++)
        for(int i=1; i<=Graph.Nv; i++)
            for(int j=1; j<=Graph.Nv; j++)
                    if(dist[i][k] + dist[k][j] < dist[i][j])  dist[i][j] = dist[i][k] + dist[k][j];

    for(int i=1; i<=Graph.Nv; i++)
    {
        for(int j=1; j<=Graph.Nv; j++)
            res[i] = max(res[i], dist[i][j]);
        resMin = min(resMin, res[i]);
    }
    
    for(int i=1; i<=Graph.Nv; i++)
        if(resMin == res[i])
        { 
            cout << i << ' ' << res[i];
            break;
        }
}

int main()
{
    AniTran AniGraph;
    cin >> AniGraph.Nv >> AniGraph.Ne;
    for(int i=1; i<=AniGraph.Ne; i++)
    {
        int v, w, weight;
        cin >> v >> w >> weight;
        AniGraph.Weight[v][w] = weight;
        AniGraph.Weight[w][v] = weight;
    }
    if(BFS_LT(AniGraph))  Floyd(AniGraph);
    else cout << BFS_LT(AniGraph);

    return 0;
}





10. 邻接矩阵 - 最小生成树 - Prim算法

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
// 邻接矩阵 - 最小生成树 - Prim算法

#define Maxdist 10000000
#define MaxVertexNum 100        // 最大顶点数
typedef int WeightType;         // 权值
typedef int Vertex;             // 顶点
typedef int DataType;           // 数据

vector <int> dist(MaxVertexNum, Maxdist);   // 存储距离, 并初始化为 Maxdist
vector <Vertex> parent(MaxVertexNum, -1);      // 储存父节点, 并初始化为 -1
vector <Vertex> MST;                           // 最小生成树

// 边
typedef struct ENode *PtrToENode;
struct ENode{
    Vertex V1, V2;              // < V1, V2 > 有向边
    WeightType Weight;          // 权重
};
typedef PtrToENode Edge;

// 图
typedef struct GNode *PtrToGNode;
struct GNode{
    int Nv;                     // 顶点数
    int Ne;                     // 边数
    WeightType G[MaxVertexNum][MaxVertexNum];   // 邻接矩阵
    DataType Data[MaxVertexNum];                // 数据
};
typedef PtrToGNode MGraph;

// 操作集
void initPrim(Vertex s);                         // 初始化 Prim
int FindMinVertex(MGraph Graph, Vertex v);      // 找出dist最小值
void Prim(MGraph Graph, Vertex s);               // Prim算法

void initPrim(MGraph Graph, Vertex s)
{
    MST.push_back(s), dist[s] = 0;
    for(Vertex w=0; w<Graph->Nv; w++)
        if(Graph->G[s][w])  dist[w] = Graph->G[s][w], parent[w] = s;
}

int FindMinVertex(MGraph Graph, Vertex v)
{
    Vertex vMin = -1;
    int minV = Maxdist;
    for(Vertex w=0; w<Graph->Nv; w++)
        if(dist[w] && dist[w] < minV)  minV = dist[w], vMin = w;
    return vMin;
}

void Prim(MGraph Graph, Vertex s)
{
    initPrim(Graph, s);
    Vertex v;
    int cnt=1;
    while(1)
    {
        v = FindMinVertex(Graph, v);
        if(v==-1)  break;
        MST.push_back(v), dist[v] = 0, cnt++;

        for(Vertex w=0; w<Graph->Nv; w++)
            if(dist[w] && Graph->G[v][w])
                if(Graph->G[v][w] < dist[w])  dist[w] = Graph->G[v][w], parent[w] = v;

        if(cnt < Graph->Nv)  cout << "Bu Lian Tong !" << endl;
    }
}





11. 邻接矩阵 - 最小生成树 - Kruskal算法

#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
// 邻接矩阵 - 最小生成树 - Kruskal算法

#define Maxdist 10000000
#define MaxVertexNum 100        // 最大顶点数
typedef int WeightType;         // 权值
typedef int Vertex;             // 顶点
typedef int DataType;           // 数据

vector <int> dist(MaxVertexNum, Maxdist);   // 存储距离, 并初始化为 Maxdist
vector <int> parent(MaxVertexNum, -1);      // 储存父节点, 并初始化为 -1


// 边
typedef struct ENode *PtrToENode;
struct ENode{
    Vertex V1, V2;              // < V1, V2 > 有向边
    WeightType Weight;          // 权重
    bool operator< (const ENode &b) const       // 重载运算符
    {
        return this->Weight>b.Weight;
    }
};
typedef PtrToENode Edge;
priority_queue <Edge> MinHeap;     // 最小堆 <优先队列> 需存入边集合
vector <Edge> MST;                 // 最小生成树

// 图
typedef struct GNode *PtrToGNode;
struct GNode{
    int Nv;                     // 顶点数
    int Ne;                     // 边数
    WeightType G[MaxVertexNum][MaxVertexNum];   // 邻接矩阵
    DataType Data[MaxVertexNum];                // 数据
};
typedef PtrToGNode MGraph;

// 操作集
int Kruskal(MGraph Graph);
void Union(Vertex v, Vertex w);
bool Union_HL(MGraph Graph, Edge E);        // 判断回路

bool Union_HL(MGraph Graph, Edge E)
{
    Vertex v = E->V1, w = E->V2;
    for(; parent[v]>=0; v=parent[v]);
    for(; parent[w]>=0; w=parent[w]);
    
    if(v==w) return true;
    else
    {
        Union(v, w);
        return false;
    }
}

void Union(Vertex v, Vertex w)
{
    if(parent[v]<parent[w])  
        parent[v]+=parent[w], parent[w]=v;
    else  
        parent[w]+=parent[v], parent[v]=w;
}

int Kruskal(MGraph Graph)
{
    WeightType weight = 0;
    while(MST.size()<(Graph->Nv-1) && !MinHeap.empty())
    {
        Edge E = MinHeap.top();
        MinHeap.pop();
        if(!Union_HL(Graph, E))  weight+=E->Weight, MST.push_back(E);
    }
    if(MST.size()<(Graph->Nv-1))  cout << "Bu Lian Tong !!!" << endl;
    return weight;
}





12. 邻接表 - 拓扑排序

#include <iostream>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;
// 邻接表 - 拓扑排序

#define MaxVertexNum 100        // 最大顶点数
typedef int Vertex;             // 顶点
typedef int WeightType;         // 边的权值
typedef int DataType;           // 数据

vector <Vertex> TopOrder(MaxVertexNum);          // 拓扑排序后的下标顺序

// 边
typedef struct ENode *PtrToENode;
struct ENode{
    Vertex V1, V2;          // 有向边 <V1, V2>
    WeightType Weight;      // 权重
};
typedef PtrToENode Edge;

// 邻接点
typedef struct AdjVNode *PtrToAdjVNode; 
struct AdjVNode{
    Vertex ADjV;            // 邻接点下标
    WeightType Weight;      // 边权重
    PtrToAdjVNode Next;     // 指针
};

// 顶点表头结点
typedef struct VNode{
    PtrToAdjVNode FirstEdge;    // 边表头结点
    DataType Data;              // 数据
}AdjList[MaxVertexNum];         // 邻接表类型

// 图
typedef struct GNode *PtrToGNode;
struct GNode{
    int Nv;                     // 顶点数
    int Ne;                     // 边数
    AdjList G;                  // 邻接表
};
typedef PtrToGNode LGraph;      // 邻接表-图类型

// 操作集
bool TopSort(LGraph Graph, Vertex *TopOrder);   // 拓扑排序

bool TopSort(LGraph Graph, Vertex *TopOrder)
{
    queue <Vertex> zeroDegree;  // 0 度 队列
    int Indegree[MaxVertexNum], cnt = 0;
    
    for(Vertex V=0; V<Graph->Nv; V++)  Indegree[V] = 0;
    for(Vertex V=0; V<Graph->Nv; V++)
        for(PtrToAdjVNode W=Graph->G[V].FirstEdge; W; W=W->Next)
            Indegree[W->ADjV]++;
    
    for(Vertex V=0; V<Graph->Ne; V++)
        if(!Indegree[V])  zeroDegree.push(V);
    
    while(!zeroDegree.empty())
    {
        Vertex V = zeroDegree.front();
        TopOrder[cnt++] = V;
        zeroDegree.pop();
        for(PtrToAdjVNode W=Graph->G[V].FirstEdge; W; W->Next)
            if(--Indegree[W->ADjV] == 0)  zeroDegree.push(W->ADjV);
    }

    if(cnt < Graph->Nv)  return false;      // 存在回路
    else  return true;                      // 排序成功
}





  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-08-19 19:31:09  更:2022-08-19 19:32:47 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/6 23:25:35-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码