用栈实现拓扑排序

#include<stdio.h>
#include<stdlib.h>
#define MAXVEX 100 //最大顶点数
typedef char VertexType;     //顶点
typedef int EdgeType;   //权值
#define UNVISITED -1 //标记未访问
#define VISITED 1 //标记未访问
#define OK 1
#define ERROR 0
typedef int Status;

typedef struct
{
    int from;   //边的始点
    int to; //边的终点
    EdgeType weight;    //权重
}Edge;  //边的结构

typedef struct EdgeNode
{
    int adjvex; //该顶点对应的下标
    EdgeType weight;    //权重
    struct EdgeNode * next;
}EdgeNode;

typedef struct  //顶点结构
{
    int in; //记录入度
    VertexType data;
    EdgeNode * firstedge;
}VertexNode,AdjList[MAXVEX];

typedef struct
{
    AdjList adjList;
    int numVertexes;
    int numEdges;
    int Mark[MAXVEX];   //标记是否被访问过
}GraphAdjList;  //图结构


//初始化邻接表
void InitGraphAdjList(GraphAdjList * G,int numVer,int numEd)    //传入顶点数和边数
{
    G->numVertexes=numVer;
    G->numEdges=numEd;
    for(int i=0;i<G->numVertexes;i++)
    {
        G->Mark[i]=UNVISITED;
        G->adjList[i].in=0;
        G->adjList[i].firstedge=NULL;   //将边表置空表
    }
}



//创建一条边(有向图)
void Creat_Edge(GraphAdjList * G,int from,int to,int weight)
{
    EdgeNode * temp= G->adjList[from].firstedge;
    if(temp==NULL)
    {
        EdgeNode * NewEdgeNode=(EdgeNode *)malloc(sizeof(EdgeNode));
        NewEdgeNode->adjvex=to;
        NewEdgeNode->weight=weight;
        NewEdgeNode->next=NULL;
        G->adjList[from].firstedge=NewEdgeNode;
        G->adjList[to].in++;
    }
    else
    {
        while(temp->next!=NULL)
        {
            temp=temp->next;
        }
        EdgeNode * NewEdgeNode=(EdgeNode *)malloc(sizeof(EdgeNode));
        NewEdgeNode->adjvex=to;
        NewEdgeNode->weight=weight;
        NewEdgeNode->next=NULL;
        temp->next=NewEdgeNode;
        G->adjList[to].in++;

    }
}




/*建立图的邻接表结构(有向图)*/
void GreateALGraph(GraphAdjList * G)
{
    int i,j,k,w;
    printf("请输入%d个元素:\n",G->numVertexes);
    for(i=0;i<G->numVertexes;i++)   /*读入顶点信息,建立顶点表*/
    {
        scanf(" %c",&G->adjList[i].data);   /*输入顶点信息*/
        G->adjList[i].firstedge=NULL;   /*将边表置空表*/
    }
    for(k=0;k<G->numEdges;k++)  /*建立边表*/
    {
        printf("输入边(Vi,Vj)上的顶点序号和权重:\n");
        scanf("%d%d%d",&i,&j,&w);   /*输入(Vi,Vj)上的顶点序号*/
        Creat_Edge(G,i,j,w);
    }
}



Edge FirstEdge(GraphAdjList * G,int oneVertex)
{
    Edge firstEdge;
    firstEdge.from=oneVertex;
    EdgeNode * temp=G->adjList[oneVertex].firstedge;
    if(temp!=NULL)
    {
        firstEdge.to=temp->adjvex;
        firstEdge.weight=temp->weight;
    }
    else
    {
        firstEdge.to=-1;
        firstEdge.weight=-1;
    }
    return firstEdge;
}




//返回oneEdge的终点
int ToVertex(Edge oneEdge)
{
    return oneEdge.to;
}




//返回与perEdge相同顶点的下一条边
Edge NextEdge(GraphAdjList * G,Edge perEdge)
{
    Edge myEdge;
    myEdge.from=perEdge.from;
    EdgeNode * temp=G->adjList[perEdge.from].firstedge;
    while(temp!=NULL && temp->adjvex<=perEdge.to)
    {
        temp=temp->next;
    }
    if(temp!=NULL)
    {
        myEdge.to=temp->adjvex;
        myEdge.weight=temp->weight;
    }
    else
    {
        myEdge.to=-1;
        myEdge.weight=-1;
    }
    return myEdge;
}


//判断是否为边
bool IsEdge(Edge oneEdge)
{
    if(oneEdge.to==-1)
    {
        return false;
    }
    else
    {
        return true;
    }
}




//拓扑排序算法
Status ToPologicalSort(GraphAdjList * G)
{
    Edge e;
    int i,k,gettop;
    int top=0;      //用于栈指针下标
    int count=0;    //统计输出的顶点个数
    int * stack;    //建栈存储顶点个数
    stack=(int *)malloc(G->numVertexes * sizeof(int));
    for(i=0;i<G->numVertexes;i++)
    {
        if(G->adjList[i].in==0) //将入度为0的顶点元素的下标入栈
        {
            stack[++top]=i;
        }
    }
    while(top!=0)   //栈不为空
    {
        gettop=stack[top--];
        printf("%c ",G->adjList[gettop].data);
        count++;    //记录输出的顶点个数
        for(e=FirstEdge(G,gettop);IsEdge(e);e=NextEdge(G,e))
        {
            k=e.to; //记录当前邻接点
            if(!(--G->adjList[k].in))   //将k的顶点邻接点的入度减1,查看入度是否为0;如果为0,则入栈
            {
                stack[++top]=k;
            }
        }
    }
        if(count<G->numVertexes)    //输出的顶点个数小于顶点个数,说明有环
        {
            printf("此图有环!\n");
            return ERROR;
        }
        else
        {
            return OK;
        }
}


int main()
{

    GraphAdjList G;
    int numVer,numEd;
    int start;
    int choose;
    printf("请输入顶点元素个数和边数:\n");
    scanf("%d%d",&numVer,&numEd);
    InitGraphAdjList(&G,numVer,numEd);
    GreateALGraph(&G);
    ToPologicalSort(&G);
    printf("\n");
    return 0;
}

《用栈实现拓扑排序》《用栈实现拓扑排序》
《用栈实现拓扑排序》
《用栈实现拓扑排序》

    原文作者:拓扑排序
    原文地址: https://blog.csdn.net/cckevincyh/article/details/46379275
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞