萬國兵 發表於 2019-8-21 15:15:00

php实现映射

<p></p><div class="toc"><div class="toc-container-header">目录</div><ul><li>映射</li><li>实现<ul><li>链表实现:</li><li>二叉树实现</li><li>复杂度分析</li></ul></li></ul></div><p></p>
<h1 id="映射">映射</h1>
<p>映射,或者射影,在数学及相关的领域经常等同于函数。基于此,部分映射就相当于部分函数,而完全映射相当于完全函数。</p>
<p>映射(Map)是用于存取键值对的数据结构(key,value),一个键只能对应一个值且键不能重复。</p>
<h1 id="实现">实现</h1>
<p>映射的实现方式可以使用链表或二叉树实现。</p>
<p><img src="https://raw.githubusercontent.com/WalkingSun/WindBlog/gh-pages/images/blog/WX20190815-164528@2x.png" alt="image" loading="lazy"></p>
<h2 id="链表实现">链表实现:</h2>
<pre><code class="language-php">&lt;?php
/**
* 接口 字典
* Interface Dict
* @package app\models
*/
Interface Dict
{

    public function set( $key , $value );

    public function get( $key );

    public function isExist( $key );

    public function delete($key);

    public function getSize();


}

class DictLinkList implements Dict
{
    protected $size=0;
    public $key;
    public $value;
    public $next;

    public function __construct($key=null,$value=null,$next=null)
    {
      $this-&gt;key = $key;
      $this-&gt;value = $value;
      $this-&gt;next = $next;
    }

    public function set($key,$value){
      $node = $this;
      while( $node &amp;&amp; $node-&gt;next ){
            if( $node-&gt;next-&gt;key==$key ){
                $node-&gt;next-&gt;value = $value;
                return $node-&gt;next;
            }
            $node = $node-&gt;next;
      }

      $node-&gt;next =new self($key,$value,$node-&gt;next);
      $this-&gt;size++;
      return$node-&gt;next;
    }


    public function get($key){
      $node = $this;
      while($node){
            if( $node-&gt;key ==$key){
                return $node-&gt;value;
            }
            $node = $node-&gt;next;
      }

      throw new \Exception('cannot found key');
    }


    public function isExist($key)
    {
      $node = $this;
      while($node){
            if( $node-&gt;key ==$key){
                return true;
            }
            $node = $node-&gt;next;
      }
      return false;
    }

    public function delete($key)
    {
      if( $this-&gt;size==0)
            throw new \Exception('key is not exist');

      $node = $this;
      while($node-&gt;next){
            if( $node-&gt;next-&gt;key == $key){
                $node-&gt;next = $node-&gt;next-&gt;next;
                $this-&gt;size--;
                break;
            }
            $node = $node-&gt;next;
      }

      return $this;
    }

    public function getSize()
    {
      return $this-&gt;size;
    }
}
</code></pre>
<p>测试:</p>
<pre><code class="language-php">&lt;?php
      $dict = new DictLinkList();
      $dict-&gt;set('sun',111); //O(n)
      $dict-&gt;set('sun',222);
      $dict-&gt;set('w',111);
      $dict-&gt;set('k',111);
      var_dump($dict-&gt;get('w'));   //O(n)
      var_dump($dict-&gt;isExist('v'));   //O(n)
      var_dump($dict-&gt;delete('sun'));    //O(n)
      var_dump($dict-&gt;getSize());
      
/******************************************/
//111
//false
//true
//2
</code></pre>
<h2 id="二叉树实现">二叉树实现</h2>
<pre><code class="language-php">&lt;?php
class DictBtree implements Dict
{
    public $key;
    public $value;

    public $left;
    public $right;
    private $size;

    public function __construct($key=null,$value=null)
    {
      $this-&gt;key = $key;
      $this-&gt;value = $value;
      $this-&gt;left = null;
      $this-&gt;right = null;
      $this-&gt;size = 0;
    }

    public function set( $key , $value ){
      if( $this-&gt;size ==0 ){
            $node = new static( $key,$value );
            $this-&gt;key = $node-&gt;key;
            $this-&gt;value = $node-&gt;value;
            $this-&gt;size++;
      }else{
            $node = $this;
            while($node){
                if( $node-&gt;key == $key ){
                  $node-&gt;value = $value;
                  break;
                }
                if($node-&gt;key&gt;$key){
                  if($node-&gt;left==null){
                        $node-&gt;left = new static( $key,$value );
                        $this-&gt;size++;
                        break;
                  }
                  $node = $node-&gt;left;
                }else{
                  if($node-&gt;right==null){
                        $node-&gt;right = new static( $key,$value );
                        $this-&gt;size++;
                        break;
                  }
                  $node = $node-&gt;right;
                }
            }
      }

      return $this;
    }

    public function get( $key ){
      if( $this-&gt;size ==0 )
            throw new \Exception('empty');
      $node = $this;
      while($node) {
            if ($node-&gt;key == $key) {
                return $node-&gt;value;
            }
            if ($node-&gt;key &gt; $key) {
                $node = $node-&gt;left;
            } else {
                $node = $node-&gt;right;
            }
      }
      throw new \Exception('this key not exist');
    }

    public function isExist( $key ){
      if( $this-&gt;size ==0 )
            return false;
      $node = $this;
      while($node) {
            if ($node-&gt;key == $key) {
                return true;
            }
            if ($node-&gt;key &gt; $key) {
                $node = $node-&gt;left;
            } else {
                $node = $node-&gt;right;
            }
      }
      return false;
    }

    public function delete($key){

      //找到元素,寻找元素左边最小元素
      $node = $this-&gt;select($key);
      if( $node-&gt;right!=null ){
            $node1 = $node-&gt;selectMin($node-&gt;right);

            //替换当前node
            $node-&gt;key = $node1-&gt;key;
            $node-&gt;value = $node1-&gt;value;

            //删除$node-&gt;right最小元素,获取最终元素赋给$node-&gt;right
            $nodeMin = $this-&gt;deleteMin($node-&gt;right);
            $node-&gt;right = $nodeMin;
      }else{
            $node1 = $node-&gt;selectMax($node-&gt;left);

            $node-&gt;key = $node1-&gt;key;
            $node-&gt;value = $node1-&gt;value;

            $nodeMax = $this-&gt;deleteMax($node-&gt;left);
            $node-&gt;left = $nodeMax;
      }

       return $this;

    }

    protected function deleteMin( $node ){
//      if( $this-&gt;size ==0 )
//            throw new \Exception('empty');

//      $prev = new static();
//      $prev-&gt;left = $node;
//      while($prev-&gt;left-&gt;left!=null){
//
//            $prev = $prev-&gt;left;
//      }
//      $prev-&gt;left = $prev-&gt;left-&gt;right;

      if( $node-&gt;left==null ){
            $rightNode = $node-&gt;right;
            $node-&gt;right = null;
            $this-&gt;size--;
            return $rightNode;
      }

       $node-&gt;left = $this-&gt;deleteMin($node-&gt;left);

      return $node;
    }

    protected function deleteMax($node){

      if( $node-&gt;right==null ){
            $leftNode = $node-&gt;left;
            $node-&gt;left = null;
            $this-&gt;size--;
            return $leftNode;
      }

      $node-&gt;right = $this-&gt;deleteMax($node-&gt;right);
      return $node;

    }

    public function getSize(){
      return $this-&gt;size;
    }


    public function select($key){
      $node = $this;

      while($node){
            if($node-&gt;key==$key){
                return $node;
            }
            if ($node-&gt;key &gt; $key) {
                $node = $node-&gt;left;
            } else {
                $node = $node-&gt;right;
            }
      }

      throw new \Exception('this key not exist');
    }

    public function selectMin( $node ){
      while($node-&gt;left){

            $node = $node-&gt;left;
      }
      return $node;
    }


    public function selectMax( $node ){
      while($node-&gt;right){

            $node = $node-&gt;right;
      }
      return $node;
    }
}
</code></pre>
<h2 id="复杂度分析">复杂度分析</h2>
<p>链表 O(n)</p>
<p>二分搜索树 O(log n)</p><br><br>
来源:https://www.cnblogs.com/followyou/p/11388922.html
頁: [1]
查看完整版本: php实现映射