토폴로지 정렬 토폴로지 정렬

AOV 네트워크 소개

프로젝트를 나타내는 방향성 그래프 에서 꼭짓점은 활동을 나타내고 호는 활동 간의 우선순위 관계를 나타내는데 이러한 방향성 그래프는 꼭짓점이 활동을 나타내는 네트워크입니다. AOV 네트워크(Activity On Vertex Network).그림에서와 같이
:
여기에 이미지 설명 삽입
G(V,E)를 n개의 꼭짓점, V에서 꼭짓점 시퀀스 v1, v2,...vn을 갖는 유향 그래프라고 가정합니다 . 꼭짓점 vi에서 vj로 , 그런 다음 꼭짓점 시퀀스의 꼭짓점 vi는 꼭짓점 vj 사이에 있어야 합니다. 그런 다음 이러한 정점 시퀀스를 위상 시퀀스라고 합니다.

토폴로지 정렬

토폴로지 정렬은 유향 그래프에 대한 토폴로지 시퀀스를 구성하는 프로세스입니다 .
구성할 때 두 가지 결과가 있습니다.

  1. 이 네트워크의 모든 정점이 출력되면 링(루프)이 없는 AOV 네트워크임을 의미합니다.
  2. 출력 고정점 수가 적으면 하나가 없어도 AOV 네트워크가 아니라 이 네트워크에 루프가 있음을 의미합니다.

토폴로지 정렬 알고리즘

AOV 네트워크에 대한 토폴로지 정렬 구성의 기본 아이디어는 다음과 같습니다. AOV 네트워크에서 진입차수가 0인 정점 출력을 선택한 다음 이 정점을 삭제하고 이 정점이 따르는 호를 삭제하고 이를 계속 반복합니다. 모든 정점이 출력될 때까지 단계 또는 AOV 네트워크에서 진입차수가 0인 정점이 없을 때까지.
토폴로지 정렬에 적용 가능한 데이터 구조: 인접 목록(노드 삭제가 용이함)은
여기에 이미지 설명 삽입
차수를 저장하고, 데이터는 데이터를 저장하고, 첫 번째 가장자리는 다음 요소를 가리킵니다.

밤을 들어 올리다

그림과 같이 AOV 그래프는
여기에 이미지 설명 삽입
인접 리스트 구조 로 주어집니다
여기에 이미지 설명 삽입
.먼저 인접 매트릭스의 구조 코드를 살펴보겠습니다.

/*邻接矩阵结构*/
typedef struct
{
    
    
    VertexType vexs[MAXVEX];   /*vertex*/
    int arc[MAXVEX][MAXVEX];   /*邻接矩阵*/
    int numVertexes, numEdges; /*顶点个数,边个数*/
} MGraph;

인접 목록의 구조 코드를 살펴보겠습니다.

//邻接表结构
typedef struct EdgeNode /*边表节点*/
{
    
    
    int adjvex;            /*邻接点域,存储该顶点对应的下标*/
    int weight;            //用于存储权值,非网图可不需要
    struct EdgeNode *next; //链域,指向下一个邻接点
} EdgeNode;

typedef struct VertexNode //定点表结点
{
    
    
    int in;              //顶点入度
    char data;           //顶点域,存储顶点信息
    EdgeNode *firstedge; //边表头指针
} VertexNode, AdjList[MAXVEX];

typedef struct
{
    
    
    AdjList adjList;
    int numVertexes, numEdges; //图中当前顶点数和边数
} graphAdjList, *GraphAdjList;

진입차수가 0인 정점을 삭제하려면 보조 데이터 구조인 스택 도 필요합니다 .
다음은 토폴로지 정렬의 코드 구현입니다.

//拓扑排序,有环返回0,无环返回1并输出序列
Status TopologicalSort(GraphAdjList GL)
{
    
    
    EdgeNode *e;
    int i, k;
    char gettop;
    int top = 0;   //用于栈指针下标
    int count = 0; //用于统计输出顶点的个数
    char *stack;   //建立栈将入度为0的顶点入栈
    stack = (char *)malloc(GL->numVertexes * sizeof(char));//为栈分配内存空间
    for (i = 0; i < GL->numVertexes; i++)
        if (0 == GL->adjList[i].in)
            stack[++top] = vexs1[i]; //入度为0 的顶点入栈
    int index;
    while (top != 0)
    {
    
    
        gettop = stack[top--];
        for (int kk = 0; kk < MAXVEX; kk++)
            if (vexs1[kk] == gettop)
                index = kk;
        printf("%c -> ", GL->adjList[index].data);
        count++; //输出i顶点,并计数
        for (e = GL->adjList[find_index(gettop)].firstedge; e; e = e->next)
        {
    
    
            k = e->adjvex;
            if (!(--GL->adjList[k].in)) /*将i顶点的邻接点的入度减一,如果减一后等于0,则入栈*/
                stack[++top] = vexs1[k];
        }
    }
    printf("\n");
    if (count < GL->numVertexes)
        return ERROR;
    else
        return OK;
}

테스트 데이터:

// G->arc[0][4] = 1;
    // G->arc[0][5] = 1;
    // G->arc[0][11] = 1;
    // G->arc[1][2] = 1;
    // G->arc[1][4] = 1;
    // G->arc[1][8] = 1;
    // G->arc[2][5] = 1;
    // G->arc[2][6] = 1;
    // G->arc[2][9] = 1;
    // G->arc[3][2] = 1;
    // G->arc[3][13] = 1;
    // G->arc[4][7] = 1;
    // G->arc[5][8] = 1;
    // G->arc[5][12] = 1;
    // G->arc[6][5] = 1;
    // G->arc[8][7] = 1;
    // G->arc[9][10] = 1;
    // G->arc[9][11] = 1;
    // G->arc[10][13] = 1;
    // G->arc[12][9] = 1;

전체 코드:

#include <stdio.h>
#include <stdlib.h>

#include <math.h>
#include <time.h>

#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXEDGE 20
#define MAXVEX 14

typedef int Status; /*Status是函数返回值类型*/
typedef char VertexType;

VertexType vexs1[MAXVEX];
/*邻接矩阵结构*/
typedef struct
{
    
    
    VertexType vexs[MAXVEX];   /*vertex*/
    int arc[MAXVEX][MAXVEX];   /*邻接矩阵*/
    int numVertexes, numEdges; /*顶点个数,边个数*/
} MGraph;

//邻接表结构
typedef struct EdgeNode /*边表节点*/
{
    
    
    int adjvex;            /*邻接点域,存储该顶点对应的下标*/
    int weight;            //用于存储权值,非网图可不需要
    struct EdgeNode *next; //链域,指向下一个邻接点
} EdgeNode;

typedef struct VertexNode //定点表结点
{
    
    
    int in;              //顶点入度
    char data;           //顶点域,存储顶点信息
    EdgeNode *firstedge; //边表头指针
} VertexNode, AdjList[MAXVEX];

typedef struct
{
    
    
    AdjList adjList;
    int numVertexes, numEdges; //图中当前顶点数和边数
} graphAdjList, *GraphAdjList;

// function declaration
void CreateMGraph_matrix(MGraph *G);
void CreateMGraph_list(MGraph *G);
void CreateALGraph(MGraph G, GraphAdjList *GL);
Status TopologicalSort(GraphAdjList GL);
void menu();

void menu()
{
    
    
    printf("Please input the method you want to bulid a graph:\n");
    printf(" 1. Adjacent matrix   2. Adjacent list\n");
    int choice;
    scanf("%d", &choice);
}
void CreateMGraph_matrix(MGraph *G) //邻接矩阵法构建矩阵
{
    
    
    int i, j, k, value;
    G->numEdges = MAXEDGE;
    G->numVertexes = MAXVEX;
    G->arc[MAXVEX][MAXVEX] = {
    
    0};
    G->vexs[MAXVEX] = {
    
    '0'};
    printf("Please input number of vertexs and edges:\n");
    scanf("%d %d", &G->numVertexes, &G->numEdges);
    getchar();
    printf("please input your vertexs\n");
    for (i = 0; i < G->numVertexes; i++)
    {
    
    
        scanf("%c", &G->vexs[i]);
        vexs1[i] = G->vexs[i];
    }
    //初始化
    for (i = 0; i < G->numVertexes; i++)
        for (j = 0; j < G->numVertexes; j++)
            G->arc[i][j] = 0;
    for (k = 0; k < G->numEdges; k++)
    {
    
    
        printf("please input the value of(vi,vj):\n");
        scanf("%d %d %d", &i, &j, &value);
        G->arc[i][j] = value;
    }
    //打印邻接矩阵
    printf("The adjancent matirx is :\n");
    for (i = 0; i < G->numVertexes; i++)
    {
    
    
        for (j = 0; j < G->numVertexes; j++)
            printf("%d ", G->arc[i][j]);
        printf("\n");
    }
    // G->arc[0][4] = 1;
    // G->arc[0][5] = 1;
    // G->arc[0][11] = 1;
    // G->arc[1][2] = 1;
    // G->arc[1][4] = 1;
    // G->arc[1][8] = 1;
    // G->arc[2][5] = 1;
    // G->arc[2][6] = 1;
    // G->arc[2][9] = 1;
    // G->arc[3][2] = 1;
    // G->arc[3][13] = 1;
    // G->arc[4][7] = 1;
    // G->arc[5][8] = 1;
    // G->arc[5][12] = 1;
    // G->arc[6][5] = 1;
    // G->arc[8][7] = 1;
    // G->arc[9][10] = 1;
    // G->arc[9][11] = 1;
    // G->arc[10][13] = 1;
    // G->arc[12][9] = 1;
}

/*邻接矩阵构建邻接表*/
void CreateALGraph(MGraph G, GraphAdjList *GL)
{
    
    
    int i, j;
    EdgeNode *e;

    *GL = (GraphAdjList)malloc(sizeof(graphAdjList));

    (*GL)->numVertexes = G.numVertexes;
    (*GL)->numEdges = G.numEdges;
    for (i = 0; i < G.numVertexes; i++) //读入顶点信息,建立顶点表
    {
    
    
        (*GL)->adjList[i].in = 0;
        (*GL)->adjList[i].data = G.vexs[i];
        (*GL)->adjList[i].firstedge = NULL; //将边表置为空表
    }

    for (i = 0; i < G.numVertexes; i++) //建立边表
    {
    
    
        for (j = 0; j < G.numVertexes; j++)
        {
    
    
            if (G.arc[i][j] == 1)
            {
    
    
                e = (EdgeNode *)malloc(sizeof(EdgeNode));
                e->adjvex = j;                         //邻接序号为j
                e->next = (*GL)->adjList[i].firstedge; //将当前顶点上的指向的节点指针赋值给e
                (*GL)->adjList[i].firstedge = e;       //将当前顶点的指针指向e
                (*GL)->adjList[j].in++;
            }
        }
    }
}
int find_index(char s)
{
    
    
    for (int i = 0; i < MAXVEX; i++)
    {
    
    
        if (vexs1[i] == s)
            return i;
    }
    return 0;
}
//拓扑排序,有环返回0,无环返回1并输出序列
Status TopologicalSort(GraphAdjList GL)
{
    
    
    EdgeNode *e;
    int i, k;
    char gettop;
    int top = 0;   //用于栈指针下标
    int count = 0; //用于统计输出顶点的个数
    char *stack;   //建立栈将入度为0的顶点入栈
    stack = (char *)malloc(GL->numVertexes * sizeof(char));
    for (i = 0; i < GL->numVertexes; i++)
        if (0 == GL->adjList[i].in)
            stack[++top] = vexs1[i]; //入度为0 的顶点入栈
    int index;
    while (top != 0)
    {
    
    
        gettop = stack[top--];
        for (int kk = 0; kk < MAXVEX; kk++)
            if (vexs1[kk] == gettop)
                index = kk;
        printf("%c -> ", GL->adjList[index].data);
        count++; //输出i顶点,并计数
        for (e = GL->adjList[find_index(gettop)].firstedge; e; e = e->next)
        {
    
    
            k = e->adjvex;
            if (!(--GL->adjList[k].in)) /*将i顶点的邻接点的入度减一,如果减一后等于0,则入栈*/
                stack[++top] = vexs1[k];
        }
    }
    printf("\n");
    if (count < GL->numVertexes)
        return ERROR;
    else
        return OK;
}

int main(void)
{
    
    
    MGraph G;
    GraphAdjList GL;
    int result;
    CreateMGraph_matrix(&G);
    CreateALGraph(G, &GL);
    result = TopologicalSort(GL);
    printf("result:%d", result);

    return 0;
}

작업 결과:
여기에 이미지 설명 삽입

추천

출처blog.csdn.net/qq_52109814/article/details/121884306