資料結構複雜圖形儲存 PHP 版

勺顛顛發表於2019-07-27

圖的相關概念名詞:
資料結構圖形儲存【有向圖和無向圖及有向網和無向網儲存】

資料結構複雜圖形儲存 PHP 版

子圖:圖中的某幾個頂點和邊或弧構成該圖的子圖。
相應的還有連通圖,稀疏圖,完全圖,連通分量圖
連線圖就是從某個頂點開始,能繞一圈回到原點。

圖形結構一般用於多對多的關係場景中,而線性表用於一對一,樹用於一對多。

<?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();

相關文章