圖的相關概念名詞:
子圖:圖中的某幾個頂點和邊或弧構成該圖的子圖。
相應的還有連通圖,稀疏圖,完全圖,連通分量圖
連線圖就是從某個頂點開始,能繞一圈回到原點。
圖形結構一般用於多對多的關係場景中,而線性表用於一對一,樹用於一對多。
<?php
/**
* 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;$i<$graph->vertexNum;$i++){
fwrite(STDOUT,"請輸入頂點資料:\n");
$data = fgets(STDIN,10);
$vertex = clone $vertexObj;
$vertex['key'] = $data;
$graph->vertex[] = $vertex;
}
$adj = new AdjMatric();
for($i=0;$i<$graph->vertexNum;$i++){
for($j=0;$j<$graph->vertexNum;$j++){
$obj = clone $adj;
$obj->adj=0;
$obj->info='';
$graph->arcs[$i][$j] = $obj;
}
}
for($i=0;$i<$graph->arcNum;$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;$i<$graph->vertexNum;$i++){
fwrite(STDOUT,"請輸入頂點資料:\n");
$data = fgets(STDIN,10);
$vertex = clone $vertexObj;
$vertex['key'] = $data;
$graph->vertex[] = $vertex;
}
$adj = new AdjMatric();
for($i=0;$i<$graph->vertexNum;$i++){
for($j=0;$j<$graph->vertexNum;$j++){
$obj = clone $adj;
$obj->adj=0;
$obj->info='';
$graph->arcs[$i][$j] = $obj;
}
}
for($i=0;$i<$graph->arcNum;$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;$i<$graph->vertexNum;$i++){
fwrite(STDOUT,"請輸入頂點資料:\n");
$data = fgets(STDIN,10);
$vertex = clone $vertexObj;
$vertex['key'] = $data;
$graph->vertex[] = $vertex;
}
$adj = new AdjMatric();
for($i=0;$i<$graph->vertexNum;$i++){
for($j=0;$j<$graph->vertexNum;$j++){
$obj = clone $adj;
$obj->adj=0;
$obj->info='';
$graph->arcs[$i][$j] = $obj;
}
}
for($i=0;$i<$graph->arcNum;$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;$i<$graph->vertexNum;$i++){
fwrite(STDOUT,"請輸入頂點資料:\n");
$data = fgets(STDIN,10);
$vertex = clone $vertexObj;
$vertex['key'] = $data;
$graph->vertex[] = $vertex;
}
$adj = new AdjMatric();
for($i=0;$i<$graph->vertexNum;$i++){
for($j=0;$j<$graph->vertexNum;$j++){
$obj = clone $adj;
$obj->adj=0;
$obj->info='';
$graph->arcs[$i][$j] = $obj;
}
}
for($i=0;$i<$graph->arcNum;$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(;$i<$this->Graph->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;$i<$this->Graph->vertexNum;$i++){
for($j=0;$j<$this->Graph->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;$i<$this->Graph->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();