当前位置:首页 > PHP教程 > php高级应用 > 列表

PHP双向链表定义与用法示例

发布:smiling 来源: PHP粉丝网  添加日期:2021-09-01 16:07:08 浏览: 评论:0 

本文实例讲述了PHP双向链表定义与用法,分享给大家供大家参考,具体如下:

由于需要对一组数据多次进行移动操作,所以写个双向链表,但对php实在不熟悉,虽然测试各个方法没啥问题,就是不知道php语言深层的这些指针和unset有什么注意的地方,贴出来让大家教育吧,效率没测试....求谅解~

  1. <?php 
  2. /** 
  3.  * **双向链表 
  4.  * @author zhiyuan12@ 
  5.  */ 
  6. /** 
  7.  * 链表元素结点类 
  8.  */ 
  9. class Node_Element { 
  10.   public $pre = NULL; // 前驱 
  11.   public $next = NULL; // 后继 
  12.   public $key = NULL; // 元素键值 
  13.   public $data = NULL; // 结点值 
  14.   function __Construct($key$data) { 
  15.     $this->key = $key
  16.     $this->data = $data
  17.   } 
  18. /** 
  19.  * 双向链表类 
  20.  */ 
  21. class DoubleLinkedList { 
  22.   private $head// 头指针 
  23.   private $tail// 尾指针 
  24.   private $current// 当前指针 
  25.   private $len// 链表长度 
  26.   function __Construct() { 
  27.     $this->head = self::_getNode ( null, null ); 
  28.     $this->curelement = $this->head; 
  29.     $this->tail = $this->head; 
  30.     $len = 0; 
  31.   } 
  32.   /** 
  33.    * @ desc: 读取链表全部结点 
  34.    */ 
  35.   public function readAll() { 
  36.     $tmp = $this->head; 
  37.     while ( $tmp->next !== null ) { 
  38.       $tmp = $tmp->next; 
  39.       var_dump ( $tmp->key, $tmp->data ); 
  40.     } 
  41.   } 
  42.   public function move($pos1$pos2) { 
  43.     $pos1Node = $this->findPosition ( $pos1 ); 
  44.     $pos2Node = $this->findPosition ( $pos2 ); 
  45.     if ($pos1Node !== null && $pos2Node !== null) { 
  46.       $tmpKey = $pos1Node->key; 
  47.       $tmpData = $pos1Node->data; 
  48.       $pos1Node->key = $pos2Node->key; 
  49.       $pos1Node->data = $pos2Node->data; 
  50.       $pos2Node->key = $tmpKey
  51.       $pos2Node->data = $tmpData
  52.       return true; 
  53.     } 
  54.     return false; 
  55.   } 
  56.   /** 
  57.    * @ desc: 在指定关键词删除结点 
  58.    * 
  59.    * @param : $key 
  60.    *     指定位置的链表元素key 
  61.    */ 
  62.   public function delete($key) { 
  63.     $pos = $this->find ( $key ); 
  64.     if ($pos !== null) { 
  65.       $tmp = $pos
  66.       $last = null; 
  67.       $first = true; 
  68.       while ( $tmp->next !== null && $tmp->next->key === $key ) { 
  69.         $tmp = $tmp->next; 
  70.         if (! $first) { 
  71.           $this->delNode ( $last ); 
  72.         } else { 
  73.           $first = false; 
  74.         } 
  75.         $last = $tmp
  76.       } 
  77.       if ($tmp->next !== null) { 
  78.         $pos->pre->next = $tmp->next; 
  79.         $tmp->next->pre = $pos->pre; 
  80.       } else { 
  81.         $pos->pre->next = null; 
  82.       } 
  83.       $this->delNode ( $pos ); 
  84.       $this->delNode ( $tmp ); 
  85.     } 
  86.   } 
  87.   /** 
  88.    * @ desc: 在指定位置删除结点 
  89.    * 
  90.    * @param : $key 
  91.    *     指定位置的链表元素key 
  92.    */ 
  93.   public function deletePosition($pos) { 
  94.     $tmp = $this->findPosition ( $pos ); 
  95.     if ($tmp === null) { 
  96.       return true; 
  97.     } 
  98.     if ($tmp === $this->getTail ()) { 
  99.       $tmp->pre->next = null; 
  100.       $this->delNode ( $tmp ); 
  101.       return true; 
  102.     } 
  103.     $tmp->pre->next = $tmp->next; 
  104.     $tmp->next->pre = $tmp->pre; 
  105.     $this->delNode ( $tmp ); 
  106.   } 
  107.   /** 
  108.    * @ desc: 在指定键值之前插入结点 
  109.    * 
  110.    * @param : $key 
  111.    *     //指定位置的链表元素key 
  112.    * @param : $data 
  113.    *     //要插入的链表元素数据 
  114.    * @param : $flag 
  115.    *     //是否顺序查找位置进行插入 
  116.    */ 
  117.   public function insert($key$data$flag = true) { 
  118.     $newNode = self::_getNode ( $key$data ); 
  119.     $tmp = $this->find ( $key$flag ); 
  120.     if ($tmp !== null) { 
  121.       $newNode->pre = $tmp->pre; 
  122.       $newNode->next = $tmp
  123.       $tmp->pre = $newNode
  124.       $newNode->pre->next = $newNode
  125.     } else { 
  126.       $newNode->pre = $this->tail; 
  127.       $this->tail->next = $newNode
  128.       $this->tail = $newNode
  129.     } 
  130.     $this->len ++; 
  131.   } 
  132.   /** 
  133.    * @ desc: 在指定位置之前插入结点 
  134.    * 
  135.    * @param : $pos 
  136.    *     指定插入链表的位置 
  137.    * @param : $key 
  138.    *     指定位置的链表元素key 
  139.    * @param : $data 
  140.    *     要插入的链表元素数据 
  141.    */ 
  142.   public function insertPosition($pos$key$data) { 
  143.     $newNode = self::_getNode ( $key$data ); 
  144.     $tmp = $this->findPosition ( $pos ); 
  145.     if ($tmp !== null) { 
  146.       $newNode->pre = $tmp->pre; 
  147.       $newNode->next = $tmp
  148.       $tmp->pre = $newNode
  149.       $newNode->pre->next = $newNode
  150.     } else { 
  151.       $newNode->pre = $this->tail; 
  152.       $this->tail->next = $newNode
  153.       $this->tail = $newNode
  154.     } 
  155.     $this->len ++; 
  156.     return true; 
  157.   } 
  158.   /** 
  159.    * @ desc: 根据key值查询指定位置数据 
  160.    * 
  161.    * @param : $key 
  162.    *     //指定位置的链表元素key 
  163.    * @param : $flag 
  164.    *     //是否顺序查找 
  165.    */ 
  166.   public function find($key$flag = true) { 
  167.     if ($flag) { 
  168.       $tmp = $this->head; 
  169.       while ( $tmp->next !== null ) { 
  170.         $tmp = $tmp->next; 
  171.         if ($tmp->key === $key) { 
  172.           return $tmp
  173.         } 
  174.       } 
  175.     } else { 
  176.       $tmp = $this->getTail (); 
  177.       while ( $tmp->pre !== null ) { 
  178.         if ($tmp->key === $key) { 
  179.           return $tmp
  180.         } 
  181.         $tmp = $tmp->pre; 
  182.       } 
  183.     } 
  184.     return null; 
  185.   } 
  186.   /** 
  187.    * @ desc: 根据位置查询指定位置数据 
  188.    * 
  189.    * @param : $pos 
  190.    *     //指定位置的链表元素key 
  191.    */ 
  192.   public function findPosition($pos) { 
  193.     if ($pos <= 0 || $pos > $this->len) 
  194.       return null; 
  195.     if ($pos < ($this->len / 2 + 1)) { 
  196.       $tmp = $this->head; 
  197.       $count = 0; 
  198.       while ( $tmp->next !== null ) { 
  199.         $tmp = $tmp->next; 
  200.         $count ++; 
  201.         if ($count === $pos) { 
  202.           return $tmp
  203.         } 
  204.       } 
  205.     } else { 
  206.       $tmp = $this->tail; 
  207.       $pos = $this->len - $pos + 1; 
  208.       $count = 1; 
  209.       while ( $tmp->pre !== null ) { 
  210.         if ($count === $pos) { 
  211.           return $tmp
  212.         } 
  213.         $tmp = $tmp->pre; 
  214.         $count ++; 
  215.       } 
  216.     } 
  217.     return null; 
  218.   } 
  219.   /** 
  220.    * @ desc: 返回链表头节点 
  221.    */ 
  222.   public function getHead() { 
  223.     return $this->head->next; 
  224.   } 
  225.   /** 
  226.    * @ desc: 返回链表尾节点 
  227.    */ 
  228.   public function getTail() { 
  229.     return $this->tail; 
  230.   } 
  231.   /** 
  232.    * @ desc: 查询链表节点个数 
  233.    */ 
  234.   public function getLength() { 
  235.     return $this->len; 
  236.   } 
  237.   private static function _getNode($key$data) { 
  238.     $newNode = new Node_Element ( $key$data ); 
  239.     if ($newNode === null) { 
  240.       echo "new node fail!"
  241.     } 
  242.     return $newNode
  243.   } 
  244.   private function delNode($node) { 
  245.     unset ( $node ); 
  246.     $this->len --; 
  247.   } 
  248. $myList = new DoubleLinkedList (); 
  249. $myList->insert ( 1, "test1" ); 
  250. $myList->insert ( 2, "test2" ); 
  251. $myList->insert ( "2b""test2-b" ); 
  252. $myList->insert ( 2, "test2-c" ); 
  253. $myList->insert ( 3, "test3" ); 
  254. $myList->insertPosition ( 5, "t""testt" ); 
  255. $myList->readAll (); 
  256. echo "+++"
  257. $myList->deletePosition(0); 
  258. $myList->readAll (); 
  259. echo "..." . $myList->getLength (); 
  260. var_dump ( $myList->findPosition ( 3 )->data ); 
  261. ?> 

运行结果:

  1. int(1) 
  2. string(5) "test1" 
  3. int(2) 
  4. string(7) "test2-c" 
  5. int(2) 
  6. string(5) "test2" 
  7. string(2) "2b" 
  8. string(7) "test2-b" 
  9. string(1) "t" 
  10. string(5) "testt" 
  11. int(3) 
  12. string(5) "test3" 
  13. +++int(1) 
  14. string(5) "test1" 
  15. int(2) 
  16. string(7) "test2-c" 
  17. int(2) 
  18. string(5) "test2" 
  19. string(2) "2b" 
  20. string(7) "test2-b" 
  21. string(1) "t" 
  22. string(5) "testt" 
  23. int(3) 
  24. string(5) "test3" 
  25. ...6string(5) "test2"

Tags: PHP双向链表

分享到:

相关文章