蘇甦 發表於 2019-7-10 10:00:00

PHP实现链表

<p></p><div class="toc"><div class="toc-container-header">目录</div><ul><li>链表</li><li>php实现对链表的增删改查操作</li><li>利用链表实现栈</li><li>链表实现队列</li></ul></div><p></p>
<h1 id="链表">链表</h1>
<p>链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。</p>
<p>形式:单链表、双链表、跳表(redis 集合数据结构就是跳表实现,时间复杂度O(log N))</p>
<p>跳表了解:https://lotabout.me/2018/skip-list/</p>
<h1 id="php实现对链表的增删改查操作">php实现对链表的增删改查操作</h1>
<p>定义节点类:</p>
<pre><code class="language-PHP">&lt;?php
class Node
{
    public $val;
    public $next;



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


}
</code></pre>
<p>链表类:</p>
<pre><code class="language-php">&lt;?php
/**链表
* Class Linklist
* @package app\models
*/
class Linklist
{
    public $head;         //头节点(默认一个虚拟头节点)
    public $size;         //长度

    public function __construct()
    {
      $this-&gt;head = new Node();
      $this-&gt;size= 0;
    }

    //头插法
    public function addFirst( $value ){
//      $node = new Node($value);
//      $node-&gt;next = $this-&gt;head;
//      $this-&gt;head = $node;

      //简化
//      $this-&gt;head = new Node( $value, $this-&gt;head );
//      $this-&gt;size++;

      $this-&gt;add(0,$value);
    }

    /**指定索引位置插入
   * @param $index
   * @param $value
   * @throws Exception
   */
    public function add( $index, $value ){

      if( $index &gt; $this-&gt;size )
            throw new Exception('超过链表范围');

//      if( $index==0 ){
//            $this-&gt;addFirst($value);
//      }else{
            $prev = $this-&gt;head;
            for($i=0;$i&lt;$index;$i++){
                $prev = $prev-&gt;next;
            }

//            $node = new Node($value);
//            $node-&gt;next = $prev-&gt;next;
//            $prev-&gt;next = $node;

            $prev-&gt;next = new Node($value,$prev-&gt;next);
//      }

      $this-&gt;size++;
    }

    /**尾插法
   * @param $value
   */
    public function addLast( $value ){

      $this-&gt;add($this-&gt;size,$value);

    }


    /***
   * 编辑
   * @param $index
   * @param $value
   * @throws Exception
   */
    public function edit( $index, $value ){
      if( $index &gt; $this-&gt;size-1 )
            throw new Exception('超过链表范围');

      $prev = $this-&gt;head-&gt;next;
      for($i=0;$i&lt;=$index;$i++){
            if( $i==$index )
                $prev-&gt;val = $value;
            $prev = $prev-&gt;next;
      }

    }

    /**
   * 查询
   * @param $index
   * @return null
   * @throws Exception
   */
    public function select($index){
      if( $index &gt; $this-&gt;size-1 )
            throw new Exception('超过链表范围');

      $prev = $this-&gt;head-&gt;next;
      for($i=0;$i&lt;=$index;$i++){
            if( $i==$index )
                return $prev;
            $prev = $prev-&gt;next;
      }
    }


    /**删除
   * @param $index
   * @throws Exceptionr
   */
    public function delete( $index ){
      if( $index &gt; $this-&gt;size-1 )
            throw new Exception('超过链表范围');

      $prev = $this-&gt;head;
      for($i=0;$i&lt;=$index;$i++){
            if( $i==$index )
               $prev-&gt;next = $prev-&gt;next-&gt;next;
            $prev = $prev-&gt;next;
      }
      $this-&gt;size--;
    }

    /**检索值是否存在
   * @param $value
   * @return bool
   */
    public function iscontain( $value ){
      $prev = $this-&gt;head-&gt;next;
      while( $prev ){

            if( $prev-&gt;val==$value ){
                return true;
            }
            $prev = $prev-&gt;next;
      }

      return false;
    }

    /**转换为字符串
   * @return string
   */
    public function tostring(){

      $prev = $this-&gt;head-&gt;next;

      $r = [];
      while( $prev ){
            $r[] = $prev-&gt;val;
            $prev = $prev-&gt;next;
      }
      return implode('-&gt;',$r);

    }
   
   /**
      * 删除指定的节点值
      * @param $value
      */
      public function removeFileds( $value ){
         $prev = $this-&gt;head;
         while( $prev-&gt;next ){
               if( $prev-&gt;val == $value ){
                   $prev-&gt;val = $prev-&gt;next-&gt;val;
                   $prev-&gt;next = $prev-&gt;next-&gt;next;
               }else{
                   $prev = $prev-&gt;next;
               }
         }
      }
      
       /**
      * 通过递归方式删除指定的节点值
      * @param $value
      */
       public function removeFiledsByRecursion( $value ){
         $this-&gt;head = $this-&gt;removeByRecursion( $this-&gt;head ,$value);
         return $this-&gt;head;
       }
   
      public function removeByRecursion( $node , $value, $level=0 ){
               if( $node-&gt;next == null ){
                   $this-&gt;showDeeep($level,$node-&gt;val);
                   return $node-&gt;val == $value ? $node-&gt;next:$node;
               }
      
               $this-&gt;showDeeep($level,$node-&gt;val);
               $node-&gt;next = $this-&gt;removeByRecursion( $node-&gt;next,$value,++$level );
               $this-&gt;showDeeep($level,$node-&gt;val);
               return $node-&gt;val == $value ? $node-&gt;next:$node;
         }
      
      /**
      * 显示深度
      * 帮助理解递归执行过程,回调函数执行层序遵循系统栈
      * @param int $level 深度层级
      * @param $val
      * @return bool
      */
      public function showDeeep( $level=1,$val ){
             if( $level&lt;1 ){
               return false;
             }
   
             while($level--){
               echo '-';
             }
             echo "$val\n";
      }

}
</code></pre>
<p>调用操作如下:</p>
<pre><code class="language-php">&lt;?php
$node = new Linklist();
$node-&gt;addFirst(1);
$node-&gt;add(1,7);
$node-&gt;add(2,10);
$node-&gt;edit(1,8);
var_dump($node-&gt;select(1)) ;
$node-&gt;delete(1);
$node-&gt;addLast(99);
var_dump($node-&gt;iscontain(2));
var_export($node);
var_export($node-&gt;tostring());
</code></pre>
<p>分析下链表操作的时间复杂度:</p>
<pre><code>增: O(n)只对链表头操作:O(1)

删: O(n)只对链表头操作:O(1)

改:O(n)

查:O(n)   只对链表头操作:O(1)
</code></pre>
<h1 id="利用链表实现栈">利用链表实现栈</h1>
<pre><code class="language-php">&lt;?php
/**
* 链表实现栈
* Class LinklistStack
* @package app\models
*/
class LinklistStack extends Linklist
{
    /**
   * @param $value
   */
    public function push( $value ){
      $this-&gt;addFirst($value);
    }

    /**
   * @return mixed
   */
    public function pop(){
      $r = $this-&gt;head-&gt;next-&gt;val;
      $this-&gt;delete(0);
      return $r;
    }
}
</code></pre>
<pre><code class="language-php">&lt;?php
      $stack = new LinklistStack();
      $stack-&gt;push(1);
      $stack-&gt;push(3);
      $stack-&gt;push(6);
      $stack-&gt;push(9);

      print_r($stack-&gt;pop());
      print_r($stack-&gt;head);
</code></pre>
<h1 id="链表实现队列">链表实现队列</h1>
<p><img src="https://raw.githubusercontent.com/WalkingSun/WindBlog/gh-pages/images/blog/linklist_queue.png" alt="image" loading="lazy"></p>
<pre><code class="language-php">&lt;?php

/**
* 链表实现队列
* Class LinkListQueue
* @package app\models
*/
class LinkListQueue extends Linklist
{
    public $tail;    //尾节点

    /**
   * push
   * @param $value
   */
    public function push( $value ){

      if( $this-&gt;head-&gt;val==null ){
            $this-&gt;tail = new Node( $value );
            $this-&gt;head = $this-&gt;tail;
      }else{
            $this-&gt;tail-&gt;next =new Node( $value );
            $this-&gt;tail = $this-&gt;tail-&gt;next;
      }
      $this-&gt;size++;
    }

    /**
   * pop
   * @return null
   * @throws \Exception
   */
    public function pop(){
      if( $this-&gt;size&lt;=0 )
            throw new \Exception('超过链表范围');
      $val = $this-&gt;head-&gt;val;
      $this-&gt;head = $this-&gt;head-&gt;next;

      $this-&gt;size--;
      return $val;
    }

    /**
   * 查看队首
   */
    public function checkHead(){
      return $this-&gt;head-&gt;val;
    }

    /**
   * 查看队尾
   */
    public function checkEnd(){
      return $this-&gt;tail-&gt;val;
    }

    /**
   * toString
   */
    public function toString(){
      $r = [];
      while( $this-&gt;head ){
            $r[] = $this-&gt;head-&gt;val;
            $this-&gt;head = $this-&gt;head-&gt;next;
      }
      return implode('-&gt;',$r);
    }
}
</code></pre>
<p>测试</p>
<pre><code class="language-php">&lt;?php
$stack = new LinkListQueue();
      $stack-&gt;push(1);
      $stack-&gt;push(3);
      $stack-&gt;push(6);
      $stack-&gt;push(9);

      print_r($stack-&gt;pop());
      print_r($stack-&gt;head);
      print_r($stack-&gt;checkHead());
      print_r($stack-&gt;checkEnd());
      print_r($stack-&gt;toString());
/**      
1
app\models\Node Object
(
    =&gt; 3
    =&gt; app\models\Node Object
      (
             =&gt; 6
             =&gt; app\models\Node Object
                (
                   =&gt; 9
                   =&gt;
                )

      )

)
3
9
3-&gt;6-&gt;9
**/
</code></pre><br><br>
来源:https://www.cnblogs.com/followyou/p/11162030.html
頁: [1]
查看完整版本: PHP实现链表