初学图论-Kahn拓扑排序算法(Kahn's Topological Sort Algorithm)

    笔者使用了较为方便的邻接链表表示法。如果使用邻接矩阵,可能需要平方量级的时间消耗。

    为了实现的方便,笔者使用了STL库中的队列结构。当队列为空时终止循环,此时如果仍然有边存在,则说明图中存在环,没有拓扑顺序。

    代码如下:

/**
 * The Kahn's Topological Sort Algorithm in C++
 * Using the Adjecency List
 * Time Cost : O(|V|+|E|)
 * Author: Zheng Chen / Arclabs001
 * Copyright 2015 Xi'an University of Posts & Telecommunications
 */
#include <iostream>
#include <queue>
#include <vector>
using namespace std;

const int N = 5; // The number of Vertex

enum status {UNDISCOVERED,VISITED};

struct Vertex
{
    int inDegree, outDegree;
    int data;
    status _stat;
}V[N];

vector<int> AdjList[N];   //Using vector to simulate the adjlist
queue<int> vertexQueue;   //The call queue
/**
 * Initialize the graph as below:
The Graph:

0->1->3
|  |  |
\/ \/ \/
2->4<--

 * @return The pointer to the start vertex
 */
Vertex* init_graph()
{
    while(!vertexQueue.empty())
        vertexQueue.pop();

    for(int i=0; i<N; i++)
    {
        AdjList[i].clear();
        V[i]._stat = UNDISCOVERED;
        V[i].data = i;
    }

    V[0].inDegree = 0; V[0].outDegree = 2;
    V[1].inDegree = 1; V[1].outDegree = 3;
    V[2].inDegree = 1; V[2].outDegree = 1;
    V[3].inDegree = 1; V[3].outDegree = 1;
    V[4].inDegree = 3; V[4].outDegree = 0;

    AdjList[0].push_back(1); AdjList[0].push_back(2);
    AdjList[1].push_back(3); AdjList[1].push_back(4);
    AdjList[2].push_back(4);
    AdjList[3].push_back(4);

    return & V[0];
}

bool Topological_Sort()
{
    for(int i=0; i<N; i++)
    {
        if(V[i].inDegree == 0)
            vertexQueue.push(i);
    }

    while(!vertexQueue.empty())
    {
        int top = vertexQueue.front();
        V[top].outDegree = 0;
        V[top]._stat = VISITED;
        int i=0;

        for(int v : AdjList[top])
        {
            --V[v].inDegree;

            AdjList[top][i++] = -1;
            if(V[v].inDegree == 0)
                vertexQueue.push(v);
        }
        cout<<top<<" ";

        vertexQueue.pop();
    }

    for(int i=0; i<N; i++)
    {
        for(int v : AdjList[i])
            if(v != -1)
            {
                return false;
            }
    }

    return true;
}

int main()
{
    init_graph();

    bool status = Topological_Sort();
    if(status == false)
    {
        cout<<"Error! The graph has at least one cycle!"<<endl;
    }
    return 0;
}

谢谢观看~

转载于:https://my.oschina.net/bgbfbsdchenzheng/blog/488796

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是用C语言实现拓扑排序Kahn算法和DFS算法的示例代码: 1. 拓扑排序Kahn算法: ```c #include <stdio.h> #include <stdlib.h> #define MAX_SIZE 100 struct Node { int data; struct Node* next; }; struct Graph { int numVertices; struct Node** adjLists; int* indegree; }; struct Node* createNode(int data) { struct Node* newNode = malloc(sizeof(struct Node)); newNode->data = data; newNode->next = NULL; return newNode; } struct Graph* createGraph(int vertices) { struct Graph* graph = malloc(sizeof(struct Graph)); graph->numVertices = vertices; graph->adjLists = malloc(vertices * sizeof(struct Node*)); graph->indegree = malloc(vertices * sizeof(int)); int i; for (i = 0; i < vertices; i++) { graph->adjLists[i] = NULL; graph->indegree[i] = 0; } return graph; } void addEdge(struct Graph* graph, int src, int dest) { struct Node* newNode = createNode(dest); newNode->next = graph->adjLists[src]; graph->adjLists[src] = newNode; graph->indegree[dest]++; } void topologicalSort(struct Graph* graph) { int* result = malloc(graph->numVertices * sizeof(int)); int front = 0, rear = 0; int* indegree = graph->indegree; int i; for (i = 0; i < graph->numVertices; i++) { if (indegree[i] == 0) { result[rear++] = i; } } while (front != rear) { int currentVertex = result[front++]; struct Node* temp = graph->adjLists[currentVertex]; while (temp) { int adjVertex = temp->data; indegree[adjVertex]--; if (indegree[adjVertex] == 0) { result[rear++] = adjVertex; } temp = temp->next; } } if (rear != graph->numVertices) { printf("Graph contains a cycle!\n"); return; } printf("Topological Sort:"); for (i = 0; i < graph->numVertices; i++) { printf(" %d", result[i]); } printf("\n"); } int main() { int vertices, edges; printf("Enter the number of vertices: "); scanf("%d", &vertices); printf("Enter the number of edges: "); scanf("%d", &edges); struct Graph* graph = createGraph(vertices); int i, src, dest; for (i = 0; i < edges; i++) { printf("Enter edge %d (source destination): ", i+1); scanf("%d %d", &src, &dest); addEdge(graph, src, dest); } topologicalSort(graph); return 0; } ``` 2. 拓扑排序的DFS算法: ```c #include <stdio.h> #include <stdlib.h> #define MAX_SIZE 100 struct Node { int data; struct Node* next; }; struct Graph { int numVertices; struct Node** adjLists; int* visited; }; struct Node* createNode(int data) { struct Node* newNode = malloc(sizeof(struct Node)); newNode->data = data; newNode->next = NULL; return newNode; } struct Graph* createGraph(int vertices) { struct Graph* graph = malloc(sizeof(struct Graph)); graph->numVertices = vertices; graph->adjLists = malloc(vertices * sizeof(struct Node*)); graph->visited = malloc(vertices * sizeof(int)); int i; for (i = 0; i < vertices; i++) { graph->adjLists[i] = NULL; graph->visited[i] = 0; } return graph; } void addEdge(struct Graph* graph, int src, int dest) { struct Node* newNode = createNode(dest); newNode->next = graph->adjLists[src]; graph->adjLists[src] = newNode; } void DFS(struct Graph* graph, int vertex, int* result, int* index) { struct Node* adjList = graph->adjLists[vertex]; graph->visited[vertex] = 1; while (adjList) { int connectedVertex = adjList->data; if (!graph->visited[connectedVertex]) { DFS(graph, connectedVertex, result, index); } adjList = adjList->next; } result[(*index)++] = vertex; } void topologicalSort(struct Graph* graph) { int* result = malloc(graph->numVertices * sizeof(int)); int index = 0; int i; for (i = 0; i < graph->numVertices; i++) { if (!graph->visited[i]) { DFS(graph, i, result, &index); } } printf("Topological Sort:"); for (i = graph->numVertices - 1; i >= 0; i--) { printf(" %d", result[i]); } printf("\n"); } int main() { int vertices, edges; printf("Enter the number of vertices: "); scanf("%d", &vertices); printf("Enter the number of edges: "); scanf("%d", &edges); struct Graph* graph = createGraph(vertices); int i, src, dest; for (i = 0; i < edges; i++) { printf("Enter edge %d (source destination): ", i+1); scanf("%d %d", &src, &dest); addEdge(graph, src, dest); } topologicalSort(graph); return 0; } ``` 这些代码可以帮助您实现拓扑排序Kahn算法和DFS算法。您可以根据需要进行修改和调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值