拓扑排序算法之php实现

      在一个表示工程的有向图中,用顶点表示活动,用弧表示活动之间的优先关系,这样的有向图为顶点表示活动的网,成为AOV网(Activity On Vertex Network)。所谓拓扑排序,就是对一个有向图构造拓扑序列的过程。

      对AOV网进行拓扑排序的基本思路是:从AOV网中选择一个入度为0的顶点输出,然后删去此顶点,并删除以此顶点为尾的弧,继续重复此步骤,直到输出全部顶点或者AOV网中不存在入度为0的顶点为止。

     应用场景:各种各样的工程或项目的流程图中,满足各种应用场景的需要。

     首先准备所需有向图的数据结构:

     class EdgeNode
    {
        public $adjvex;
        public $weight;
        public $next;

        public function __construct($adjvex, $next = null, $weight = 0)
        {
            $this->adjvex = $adjvex;
            $this->next = $next;
            $this->weight = $weight;
        }
    }

    class VertexNode
    {
        public $in;
        public $data;
        public $firstedge = null;

        public function __construct($in, $data, $firstedge)
        {
            $this->in = $in;
            $this->data = $data;
            $this->firstedge = $firstedge;
        }
    }

    class Graph
    {
        public $adjList;
        public $num;

        public function __construct($adjList, $num)
        {
            $this->adjList = $adjList;
            $this->num = $num;
        }
    }

     然后准备数据:

    $EdgeNode0 = new EdgeNode(11, new EdgeNode(5, new EdgeNode(4)));
    $EdgeNode1 = new EdgeNode(8, new EdgeNode(4, new EdgeNode(2)));
    $EdgeNode2 = new EdgeNode(9, new EdgeNode(6, new EdgeNode(5)));
    $EdgeNode3 = new EdgeNode(13, new EdgeNode(2));
    $EdgeNode4 = new EdgeNode(7);
    $EdgeNode5 = new EdgeNode(12, new EdgeNode(8));
    $EdgeNode6 = new EdgeNode(5);
    $EdgeNode7 = null;
    $EdgeNode8 = new EdgeNode(7);
    $EdgeNode9 = new EdgeNode(11, new EdgeNode(10));
    $EdgeNode10 = new EdgeNode(13);
    $EdgeNode11 = null;
    $EdgeNode12 = new EdgeNode(9);
    $EdgeNode13 = null;

    $adjList = array(
        new VertexNode(0, 'V0',  $EdgeNode0),
        new VertexNode(0, 'V1',  $EdgeNode1),
        new VertexNode(2, 'V2',  $EdgeNode2),
        new VertexNode(0, 'V3',  $EdgeNode3),
        new VertexNode(2, 'V4',  $EdgeNode4),
        new VertexNode(3, 'V5',  $EdgeNode5),
        new VertexNode(1, 'V6',  $EdgeNode6),
        new VertexNode(2, 'V7',  $EdgeNode7),
        new VertexNode(2, 'V8',  $EdgeNode8),
        new VertexNode(2, 'V9',  $EdgeNode9),
        new VertexNode(1, 'V10', $EdgeNode10),
        new VertexNode(2, 'V11', $EdgeNode11),
        new VertexNode(1, 'V12', $EdgeNode12),
        new VertexNode(2, 'V13', $EdgeNode13),
    );

    $graph = new Graph($adjList, 14);

     然后,实现算法:

     -----------------------------   第一种  --------------------------

    $stackTop = -1;
    $count = 0;
    $stack = array();
    foreach ($graph->adjList as $adjKey => $adjItem) {
        if ($adjItem->in == 0) {
            $stack[++$stackTop] = $adjKey;
        }
    }

    while ($stackTop != -1) {
        $getTop = $stack[$stackTop--];
        printf("%s -> ", $graph->adjList[$getTop]->data);
        $count += 1;


        for ($e = $graph->adjList[$getTop]->firstedge; !empty($e); $e = $e->next) { 
            $k = $e->adjvex;
            $graph->adjList[$k]->in -= 1;
            if (!$graph->adjList[$k]->in) {
                $stack[++$stackTop] = $k;
            }
        }
    }

    if ($count < $graph->num) {
        exit('不是AOV网');
    } else {
        exit('是的');
    }

    -------------------  第二种  ---------------------------------

$stackTop = -1;
    $count = 0;
    $stack = array();
    foreach ($graph->adjList as $adjKey => $adjItem) {
        if ($adjItem->in == 0) {
            $stackTop += 1;
            $stack[$stackTop] = $adjKey;
        }
    }

    while ($stackTop != -1) {
        $stackTop -= 1;
        $getTop = array_pop($stack);
        printf("%s -> ", $graph->adjList[$getTop]->data);
        $count += 1;

        for ($e = $graph->adjList[$getTop]->firstedge; !empty($e); $e = $e->next) { 
            $k = $e->adjvex;
            $graph->adjList[$k]->in -= 1;
            if (!$graph->adjList[$k]->in) {
                array_push($stack, $k);
                $stackTop += 1;
            }
        }
    }

    if ($count < $graph->num) {
        exit('不是AOV网');
    } else {
        exit('是的');
    }

    到这里,整个实现就基本结束了,算法实现第一种和第二种只有些微差别。

    此文参考《大话数据结构》这本书,如果问题,请评论指正~

发布了151 篇原创文章 · 获赞 107 · 访问量 133万+

猜你喜欢

转载自blog.csdn.net/sanbingyutuoniao123/article/details/82314208
今日推荐