拓扑排序

拓扑排序只存在于有向无环图中

实际意义是:衡量任务的优先级,即任务2在做之前,要确保任务1已经完成,也就是工作的流程图,这也是为什么只存在于无环图里面

每次寻找只有出度的任务(顶点)

代码实现也主要借助两个东西,一个是一维数组用来存放某个顶点的入度,另一个就是栈,如果某个顶点入度等于0,就把它入栈,入栈之后把链结表中与这个顶点有联系的所有顶点入度减一,再次判断所有顶点是否入度等于零,重复上面操作。

还有一点就是因为连接表的顺序不同,导致入栈的顺序不同,将会导致出现不同的拓扑排序,但是这没问题哈。。。

 

/*
拓扑排序
*/
//建立邻接表图
#include  <iostream>
#include  <malloc.h>
#include  <cstdio>
using  namespace  std;
#define   MAX_SIZE   20
#define   increase   10
typedef   bool       status;
typedef  struct  link
{
    int data;//下标
    int weiget;//权重
    struct  link* next;
}*enode;//表结点
typedef  struct  head_node
{
    char data;
    struct  link* next;
}Head,*head;//头节点
typedef  struct  graph
{
    int vexnum,arcnum;
    Head vex[MAX_SIZE];
}*Graph;
typedef  struct  my_stack
{
    int *base;
    int *top;
    int stack_size;
}*tyust;
//获取位置
int get_pos(Graph pit,char c)
{
    for(int i=0;i<pit->vexnum;i++)
    {
        if(c==pit->vex[i].data)
        {
            return i;
        }
    }
    return -1;
}
void link_last(enode &father,enode son)
{
   while(father->next)
        father=father->next;
   father->next=son;
}
//创建邻接图
Graph  creat_graph()
{
    int    vexnum,arcnum;
    char  in1,in2;
    int p1,p2;
    Graph  pit=(Graph)malloc(sizeof(graph));
    cout<<"请输入顶点数和边数:"<<endl;
    cin>>vexnum>>arcnum;

    pit->arcnum=arcnum;
    pit->vexnum=vexnum;
    cout<<"请输入所有顶点"<<endl;
    for(int i=0;i<vexnum;i++)
    {
        cin>>pit->vex[i].data;
        pit->vex[i].next=NULL;
    }
    for(int j=0;j<arcnum;j++)
    {
        cout<<"请输入弧边"<<j+1<<endl;
        cin>>in1>>in2;
        p1=get_pos(pit,in1);
        p2=get_pos(pit,in2);

        enode  my_side=(enode)malloc(sizeof(link));
        if(!my_side)cout<<"节点分配错误!!";
        my_side->data=p2;
        my_side->next=NULL;

        //把新的表结点连上去
        if(pit->vex[p1].next==NULL)
            pit->vex[p1].next=my_side;
        else
            link_last(pit->vex[p1].next,my_side);

    }
    return pit;
}
status isempty(tyust &S)//判断是否为空,空的话返回true
{
    if(S->base==S->top)return true;
    else return false;
}
void stack_init(tyust &S)//栈初始化
{
    S=(tyust)malloc(MAX_SIZE*sizeof(my_stack));
    if(!S->base)cout<<"分配栈出错"<<endl;
    S->top=S->base;
    S->stack_size=MAX_SIZE;
}
void stack_push(tyust &S,int e)
{
    if((S->top-S->base)==S->stack_size)//
    {
        S->base=(int *)realloc(S->base,(increase+S->stack_size)*sizeof(int));
        if(!S->base)cout<<"栈重新分配错误!!"<<endl;
        S->top=S->base+S->stack_size;
        S->stack_size+=increase;
    }
    *S->top=e;
    S->top++;
}
void stack_pop(tyust &S,int &e)
{
    if(S->base==S->top)cout<<"pop Error!!"<<endl;
    e=*(--S->top);
}
void find_indegree(Graph pit,int *indegree)
{
    enode p;
    for(int i=0;i<pit->vexnum;i++)//入度初始化为零
    {
        indegree[i]=0;
    }
    for(int j=0;j<pit->vexnum;j++)
    {
        p=pit->vex[j].next;
        while(p)//指针非空
        {
            indegree[p->data]++;
            p=p->next;
        }
    }
}
/*
利用一个一维数组和栈
寻找入度等于零的
*/
void topology(Graph pit)//拓扑排序
{
    int indegree[MAX_SIZE];//入度数组
    int e,k;
    tyust S;
    enode p;
    find_indegree(pit,indegree);//初始化入度
    stack_init(S);//初始化栈//这里其实错了,详情看下一篇关键路径,但是在这里却可用,不建议使用
    for(int i=0;i<pit->vexnum;i++)
    {
        if(!indegree[i])//如果入度等于零,入栈
        {
            stack_push(S,i);
        }

    }
    while(!isempty(S))//如果非空
    {
        stack_pop(S,e);
        cout<<pit->vex[e].data<<" ";
        for(p=pit->vex[e].next;p;p=p->next)
        {
            k=p->data;
            if(!(--indegree[k]))//入度减一,若为0,则入栈
            {
                stack_push(S,k);
            }

        }
    }

}
int main()
{
    Graph pit=creat_graph();
    topology(pit);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值