php 有向图 的深度 优先遍历 以及 拓扑排序

<?php
class ToplogicGraph{
    protected $vertexArr = array();
    protected $arcArr = array();
    public $digraph = array();
    protected $time = 0;
    protected $detect = array();

    // 建立 有向图领接表 数组表示
    public function buildDigraph()
    {    
        foreach ($this->vertexArr as $key => $vertex) {
            $this->digraph[$vertex] = array('name'=>$vertex,'d'=>null,'f'=>null,'tails'=>array(),'color'=>'WHITE','PI'=>null);    
        }

        foreach ($this->arcArr as $key => $arc) {
            $this->digraph[$arc[0]]['tails'][] = $arc[1];
        }
    }

    public function setArcArr($arcArr)
    {
        $this->arcArr = $arcArr;
    }

    public function setVertexArr($vertexArr)
    {
        $this->vertexArr = $vertexArr;
    }

    public function DFS()
    {    
        //检测是否存在环 并输出环路径
        foreach ($this->vertexArr as $key => $vertex) {
            $graph = $this->digraph;
            $this->detect = array($vertex);
            $G = &$graph;
            $this->DFS_Visit_Detected($vertex,$graph);
        }
        $this->time = 0;

        //深度优先遍历图 
        foreach ($this->vertexArr as $key => $vertex) {
            if($this->digraph[$vertex]['color']=='WHITE'){
                $graph = &$this->digraph;
                $this->DFS_Visit($vertex,$graph);
            }
        }
    }

    protected function DFS_Visit($vertexKey,&$graph)
    {
        $this->time = ($this->time + 1);
        $graph[$vertexKey]['d'] = $this->time;
        foreach ($graph[$vertexKey]['tails'] as $key => $vertex) {
             if($graph[$vertex]['color']=='WHITE'){
                 $graph[$vertex]['PI'] = $vertexKey;
                 $this->DFS_Visit($vertex,$graph);
             }
        }
        $graph[$vertexKey]['color'] = 'BLACK';
        $this->time = ($this->time + 1);
        $graph[$vertexKey]['f'] = $this->time; 
    }

    protected function DFS_Visit_Detected($vertexKey,&$graph)
    {    
        $graph[$vertexKey]['color'] = 'GREY';
        foreach ($graph[$vertexKey]['tails'] as $key => $vertex) {
             $this->detect[] = $vertex;
             if($graph[$vertex]['color']=='WHITE'){
                 $graph[$vertex]['PI'] = $vertexKey;
                 $graph[$vertex]['color'] = 'GREY';
                 $this->DFS_Visit_Detected($vertex,$graph);
             } else {
                 echo 'there is a loop:';
                 var_dump($this->detect);
                 exit();
             }
        }
        $graph[$vertexKey]['color'] = 'BLACK';
        array_pop($this->detect); 
    }

    //拓扑排序
    public function toplogicSort()
    {
        $sort = array();
        foreach ($this->digraph as $key => $value) {
            $sort[$key] = $value['f'];
        }
        arsort($sort);
        return array_keys($sort);
    }

}

$Graph = new ToplogicGraph();
$arcArr = array(
        array('A','C'),
        array('A','B'),
        array('C','F'),
        array('B','G'),
        array('C','G'),
        array('M','N'),
        array('G','A'),       //测试 环 数据
    );

$vertexArr = array('A','B','C','D','E','F','G','M','N');

$Graph->setArcArr($arcArr);
$Graph->setVertexArr($vertexArr);
$Graph->buildDigraph();
$Graph->DFS();    
$sort = $Graph->toplogicSort();
var_dump($sort);      // 输出最后的拓扑排序结果


转载于:https://my.oschina.net/sylarxu462415/blog/306659

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值