php实现图数据结构,学习猿地-数据结构复杂图形存储 PHP 版

图的相关概念名词:

0be54ca26c84a4484272358053e1780c.png

e51b73f3f392d32ccb64a3dbda9e571a.png

子图:图中的某几个顶点和边或弧构成该图的子图。

相应的还有连通图,稀疏图,完全图,连通分量图

连接图就是从某个顶点开始,能绕一圈回到原点。

图形结构一般用于多对多的关系场景中,而线性表用于一对一,树用于一对多。

/**

* Created by PhpStorm.

* User: 1655664358@qq.com

* Date: 2019/2/27

* Time: 10:47

*/

class AdjMatric

{

public $adj;

public $info;

}

class Vertex implements ArrayAccess,IteratorAggregate

{

public $data = [];

public function offsetExists($offset)

{

// TODO: Implement offsetExists() method.

return isset($this->data[$offset])?true:false;

}

public function offsetGet($offset)

{

// TODO: Implement offsetGet() method.

if ($this->offsetExists($offset)){

return $this->data[$offset];

}else{

return $this->data;

}

}

public function offsetSet($offset, $value)

{

// TODO: Implement offsetSet() method.

if (!$this->offsetExists($offset)){

$this->data[$offset] = $value;

}

}

public function offsetUnset($offset)

{

// TODO: Implement offsetUnset() method.

if (isset($this->data[$offset])){

unset($this->data[$offset]);

}

}

public function getIterator()

{

// TODO: Implement getIterator() method.

return new IteratorIterator($this->data);

}

}

class MGraph

{

public $arcs = [];

public $vertex = [];

public $arcNum = 0;

public $vertexNum = 0;

public $kind;

}

class Graph

{

const DG = 1;

const DN = 2;

const UDG = 3;

const UDN = 4;

private $kind;

private $Graph;

function createDG(MGraph &$graph)

{

printf("创建有向图:\n");

printf("请输入图顶点数量:\n");

$graph->vertexNum = fgets(STDIN,10);

printf("请输入图弧数量:\n");

$graph->arcNum = fgets(STDIN,10);

$vertexObj = new Vertex();

for($i=0;$ivertexNum;$i++){

fwrite(STDOUT,"请输入顶点数据:\n");

$data = fgets(STDIN,10);

$vertex = clone $vertexObj;

$vertex['key'] = $data;

$graph->vertex[] = $vertex;

}

$adj = new AdjMatric();

for($i=0;$ivertexNum;$i++){

for($j=0;$jvertexNum;$j++){

$obj = clone $adj;

$obj->adj=0;

$obj->info='';

$graph->arcs[$i][$j] = $obj;

}

}

for($i=0;$iarcNum;$i++){

fwrite(STDOUT,"请输入第一个顶点值:\n");

$x = fgets(STDIN,10);

fwrite(STDOUT,"请输入第二个顶点值:\n");

$y = fgets(STDIN,10);

$m = $this->getLocation($x);

$n = $this->getLocation($y);

if ($m==-1||$n==-1){

fwrite(STDERR,"没有找到顶点数据\n");

break;

}

$graph->arcs[$m][$n]->adj = 1;

}

}

function createDN(MGraph &$graph)

{

printf("创建无向图:\n");

printf("请输入图顶点数量:\n");

$graph->vertexNum = fgets(STDIN,10);

printf("请输入图边数量:\n");

$graph->arcNum = fgets(STDIN,10);

$vertexObj = new Vertex();

for($i=0;$ivertexNum;$i++){

fwrite(STDOUT,"请输入顶点数据:\n");

$data = fgets(STDIN,10);

$vertex = clone $vertexObj;

$vertex['key'] = $data;

$graph->vertex[] = $vertex;

}

$adj = new AdjMatric();

for($i=0;$ivertexNum;$i++){

for($j=0;$jvertexNum;$j++){

$obj = clone $adj;

$obj->adj=0;

$obj->info='';

$graph->arcs[$i][$j] = $obj;

}

}

for($i=0;$iarcNum;$i++){

fwrite(STDOUT,"请输入第一个顶点值:\n");

$x = fgets(STDIN,10);

fwrite(STDOUT,"请输入第二个顶点值:\n");

$y = fgets(STDIN,10);

$m = $this->getLocation($x);

$n = $this->getLocation($y);

if ($m==-1||$n==-1){

fwrite(STDERR,"没有找到顶点数据\n");

break;

}

$graph->arcs[$m][$n]->adj = 1;

$graph->arcs[$n][$m]->adj = 1;

}

}

function createUDG(MGraph &$graph)

{

printf("创建有向网:\n");

printf("请输入图顶点数量:\n");

$graph->vertexNum = fgets(STDIN,10);

printf("请输入网弧权数量:\n");

$graph->arcNum = fgets(STDIN,10);

$vertexObj = new Vertex();

for($i=0;$ivertexNum;$i++){

fwrite(STDOUT,"请输入顶点数据:\n");

$data = fgets(STDIN,10);

$vertex = clone $vertexObj;

$vertex['key'] = $data;

$graph->vertex[] = $vertex;

}

$adj = new AdjMatric();

for($i=0;$ivertexNum;$i++){

for($j=0;$jvertexNum;$j++){

$obj = clone $adj;

$obj->adj=0;

$obj->info='';

$graph->arcs[$i][$j] = $obj;

}

}

for($i=0;$iarcNum;$i++){

fwrite(STDOUT,"请输入第一个顶点权值:\n");

$x = fgets(STDIN,10);

fwrite(STDOUT,"请输入第二个顶点权值:\n");

$y = fgets(STDIN,10);

fwrite(STDOUT,"请输入两者间的权值:\n");

$z = fgets(STDIN,10);

$m = $this->getLocation($x);

$n = $this->getLocation($y);

if ($m==-1||$n==-1){

fwrite(STDERR,"没有找到顶点数据\n");

break;

}

$graph->arcs[$m][$n]->adj = $z;

}

}

function createUDN(MGraph &$graph)

{

printf("创建无向网:\n");

printf("请输入图顶点数量:\n");

$graph->vertexNum = fgets(STDIN,10);

printf("请输入网边权数量:\n");

$graph->arcNum = fgets(STDIN,10);

$vertexObj = new Vertex();

for($i=0;$ivertexNum;$i++){

fwrite(STDOUT,"请输入顶点数据:\n");

$data = fgets(STDIN,10);

$vertex = clone $vertexObj;

$vertex['key'] = $data;

$graph->vertex[] = $vertex;

}

$adj = new AdjMatric();

for($i=0;$ivertexNum;$i++){

for($j=0;$jvertexNum;$j++){

$obj = clone $adj;

$obj->adj=0;

$obj->info='';

$graph->arcs[$i][$j] = $obj;

}

}

for($i=0;$iarcNum;$i++){

fwrite(STDOUT,"请输入第一个顶点权值:\n");

$x = fgets(STDIN,10);

fwrite(STDOUT,"请输入第二个顶点权值:\n");

$y = fgets(STDIN,10);

fwrite(STDOUT,"请输入两者间的权值:\n");

$z = fgets(STDIN,10);

$m = $this->getLocation($x);

$n = $this->getLocation($y);

if ($m==-1||$n==-1){

fwrite(STDERR,"没有找到顶点数据\n");

break;

}

$graph->arcs[$m][$n]->adj = $z;

$graph->arcs[$n][$m]->adj = $z;

}

}

function getLocation($x)

{

$i = 0;

for(;$iGraph->vertexNum;$i++)

{

if($this->Graph->vertex[$i]['key']==$x){

break;

}

}

if ($i>=$this->Graph->vertexNum){

fwrite(STDERR,"未找到顶点\n");

$i=-1;

}

return $i;

}

function showGraph()

{

$temp = [];

for($i=0;$iGraph->vertexNum;$i++){

for($j=0;$jGraph->vertexNum;$j++){

fwrite(STDOUT,$this->Graph->arcs[$i][$j]->adj);

$temp[$i][$j] = $this->Graph->arcs[$i][$j]->adj;

}

fwrite(STDOUT,"\n");

}

}

function createGraph()

{

fwrite(STDOUT,"请输入图类型:\n");

$this->kind = fgets(STDIN,10);

if ($this->kind){

switch ($this->kind){

case self::DG:

$this->createDG($this->Graph);

break;

case self::DN:

$this->createDN($this->Graph);

break;

case self::UDG:

$this->createUDG($this->Graph);

break;

case self::UDN:

$this->createUDN($this->Graph);

break;

}

}

}

function showVertex()

{

for($i=0;$iGraph->vertexNum;$i++){

echo $this->Graph->vertex[$i]['key'];

}

}

function run()

{

$this->Graph = new MGraph();

$this->createGraph();

$this->showGraph();

fwrite(STDOUT,"***********************\n");

$this->showVertex();

}

}

(new Graph())->run();

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值