实现一个拓扑排序算法。

PHP 算法面试题
0
0
分享
推荐答案
展示答案

<?php $graph = [ //图的顶点个数 'count' => 9, //图的顶点列表 'vertexs' => [ //['name' => "活动名称", 'days' => 完成活动所需时间, 'sTime' => 活动最早开始时间, 'inCount' => 活动的前驱节点个数, 'adjacentNode' => 相邻活动列表(节点索引), 'adjacent' => 相邻活动的个数] ['name' => "P1", 'days' => 8, 'sTime' => 0, 'inCount' => 0, 'adjacentNode' => [2, 6], 'adjacent' => 2], ['name' => "P2", 'days' => 5, 'sTime' => 0, 'inCount' => 0, 'adjacentNode' => [2, 4], 'adjacent' => 2], ['name' => "P3", 'days' => 6, 'sTime' => 8, 'inCount' => 2, 'adjacentNode' => [3], 'adjacent' => 1], ['name' => "P4", 'days' => 4, 'sTime' => 14, 'inCount' => 2, 'adjacentNode' => [5, 8], 'adjacent' => 2], ['name' => "P5", 'days' => 7, 'sTime' => 5, 'inCount' => 1, 'adjacentNode' => [3, 5], 'adjacent' => 2], ['name' => "P6", 'days' => 7, 'sTime' => 18, 'inCount' => 2, 'adjacentNode' => [], 'adjacent' => 0], ['name' => "P7", 'days' => 4, 'sTime' => 8, 'inCount' => 1, 'adjacentNode' => [7], 'adjacent' => 1], ['name' => "P8", 'days' => 3, 'sTime' => 12, 'inCount' => 1, 'adjacentNode' => [8], 'adjacent' => 1], ['name' => "P9", 'days' => 4, 'sTime' => 18, 'inCount' => 2, 'adjacentNode' => [], 'adjacent' => 0], ] ]; function sortQueue(&$q){ $sTime = []; foreach($q as $k => $v){ $sTime[$k] = $v['sTime']; } uasort($q, function($a, $b) { if ($a['sTime'] == $b['sTime']) { return 0; } return ($a['sTime'] < $b['sTime']) ? -1 : 1; }); } function EnQueue(&$q, $node, $sTime){ $item = ['node' => $node, 'sTime' => $sTime]; array_push($q, $item); //优先级队列 sortQueue($q); } function DeQueue(&$q){ $element = array_shift($q); $node = $element['node']; return $node; } function TopologicalSorting($g, &$sortedNode){ $nodeQueue = []; for($i = 0; $i < $g['count']; $i++){ if($g['vertexs'][$i]['inCount'] == 0){ EnQueue($nodeQueue, $i, $g['vertexs'][$i]['sTime']); } } while(!empty($nodeQueue)){ $node = DeQueue($nodeQueue); //按照开始时间优先级出队 array_push($sortedNode, $node); //遍历节点node的所有邻接点,将表示有向边inCount值减1 for($j = 0; $j < $g['vertexs'][$node]['adjacent']; $j++){ $adjNode = $g['vertexs'][$node]['adjacentNode'][$j]; $g['vertexs'][$adjNode]['inCount']--; //如果inCount值为0,则该节点入队列 if($g['vertexs'][$adjNode]['inCount'] == 0){ EnQueue($nodeQueue, $adjNode, $g['vertexs'][$adjNode]['sTime']); } } } return count($sortedNode) == $g['count']; } function PrintSorting($g, $sortedNode){ foreach($sortedNode as $v){ echo $g['vertexs'][$v]['name'].' '; } echo PHP_EOL; } function main(){ global $graph; $sortedNode = []; if(!TopologicalSorting($graph, $sortedNode)) { echo "Graph has circle!".PHP_EOL; } PrintSorting($graph, $sortedNode); } main();

答案已隐藏