欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  php教程

PHP实现图的邻接表

程序员文章站 2022-06-15 22:30:18
...
  1. //调用
  2. require 'alGraph.php';
  3. $a = array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j');
  4. $b = array('ab', 'bc', 'be', 'cd', 'df', 'fg', 'gh', 'ga', 'hj', 'gi');
  5. $test = new ALGraph($a, $b);
  6. print_r($test->bfs());
  7. ?>
  8. alGraph.php
  9. //顶点类
  10. class Vex{
  11. private $data;
  12. private $headLink;
  13. public function Vex($data, $headLink = NULL){
  14. $this->data = $data;
  15. $this->headLink = $headLink;
  16. }
  17. public function getData(){
  18. return $this->data;
  19. }
  20. public function getHeadLink(){
  21. return $this->headLink;
  22. }
  23. public function setHeadLink(& $link){
  24. $this->headLink = $link;
  25. }
  26. }
  27. //边类
  28. class Arc{
  29. private $key;
  30. private $next;
  31. public function Arc($key, $next = NULL){
  32. $this->key= $key;
  33. $this->next = $next;
  34. }
  35. public function getKey(){
  36. return $this->key;
  37. }
  38. public function getNext(){
  39. return $this->next;
  40. }
  41. public function setNext($next){
  42. $this->next = $next;
  43. }
  44. }
  45. //邻接表类
  46. class ALGraph{
  47. private $vexsData;
  48. private $vexs;
  49. private $arcData;
  50. private $excuteDfsResult;//深度优先遍历后的字符串结果
  51. private $hasList; //遍历时储存遍历过的结点下标
  52. private $queue; //广度优先遍历时的存储队列
  53. public function ALGraph($vexsData, $arcData){
  54. $this->vexsData = $vexsData;
  55. $this->arcData = $arcData;
  56. $this->createHeadList();
  57. $this->createArc();
  58. }
  59. //创建顶点数组
  60. private function createHeadList(){
  61. foreach($this->vexsData as $value){
  62. $this->vexs[] = new Vex($value);
  63. }
  64. }
  65. //创建边表
  66. private function createArc(){
  67. foreach($this->arcData as $value){
  68. $str = str_split($value);
  69. $this->createConnect($str[0], $str[1]);
  70. $this->createConnect($str[1], $str[0]);
  71. }
  72. }
  73. //依附于边的俩顶点建立关系
  74. private function createConnect($first, $last){
  75. $firstNode = & $this->vexs[$this->getVexByValue($first)];
  76. $lastNode = new Arc($this->getVexByValue($last));
  77. $lastNode->setNext($firstNode->getHeadLink());
  78. $firstNode->setHeadLink(& $lastNode);
  79. }
  80. //根据顶点的值返回顶点在顶点数组中的下标
  81. private function getVexByValue($value){
  82. foreach($this->vexs as $k=>$v){
  83. if($v->getData() == $value){
  84. return $k;
  85. }
  86. }
  87. }
  88. //广度优先遍历
  89. public function bfs(){
  90. $this->hasList = array();
  91. $this->queue = array();
  92. foreach($this->vexs as $key=>$value){
  93. if(!in_array($value->getData(), $this->hasList)){
  94. $this->hasList[] = $value->getData();
  95. $this->queue[] = $value->getHeadLink();
  96. while(!emptyempty($this->queue)){
  97. $node = array_shift($this->queue);
  98. while($node){
  99. if(!in_array($this->vexs[$node->getKey()]->getData(), $this->hasList)){
  100. $info = $this->vexs[$node->getKey()];
  101. $this->hasList[] = $info->getData();
  102. $this->queue[] = $info->getHeadLink();
  103. }
  104. $node = $node->getNext();
  105. }
  106. }
  107. }
  108. }
  109. return implode($this->hasList);
  110. }
  111. //深度优先遍历入口
  112. public function dfs(){
  113. $this->hasList = array();
  114. foreach($this->vexs as $key=>$value){
  115. if(!in_array($key, $this->hasList)){
  116. $this->hasList[] = $key;
  117. $this->excuteDfs($this->vexs[$key]->getHeadLink());
  118. }
  119. }
  120. foreach($this->hasList as $key=>$value){
  121. $this->hasList[$key] = $this->vexs[$value]->getData();
  122. }
  123. return implode($this->hasList);
  124. }
  125. //执行深度遍历
  126. private function excuteDfs($arc){
  127. if(!$arc in_array($arc->getKey(), $this->hasList)){
  128. return false;
  129. }
  130. $this->hasList[] = $arc->getKey();
  131. $next = $this->vexs[$arc->getKey()]->getHeadLink();
  132. while($next){
  133. $this->excuteDfs($next);
  134. $next = $next->getNext();
  135. }
  136. }
  137. public function getVexs(){
  138. return $this->vexs;
  139. }
  140. }
  141. ?>