`
swincle
  • 浏览: 79147 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

PHP实现双向链表

    博客分类:
  • PHP
 
阅读更多

 

<?php
/**
 * **双向链表
 * @author zhiyuan12@
 * @modified 2012-10-25
 */
/**
 * 链表元素结点类
 */
class Node_Element {
	public $pre = NULL; // 前驱
	public $next = NULL; // 后继
	public $key = NULL; // 元素键值
	public $data = NULL; // 结点值
	function __Construct($key, $data) {
		$this->key = $key;
		$this->data = $data;
	}
}
/**
 * 双向链表类
 */
class DoubleLinkedList {
	private $head; // 头指针
	private $tail; // 尾指针
	private $current; // 当前指针
	private $len; // 链表长度
	function __Construct() {
		$this->head = self::_getNode ( null, null );
		$this->curelement = $this->head;
		$this->tail = $this->head;
		$len = 0;
	}
	/**
	 * @ desc: 读取链表全部结点
	 */
	public function readAll() {
		$tmp = $this->head;
		while ( $tmp->next !== null ) {
			$tmp = $tmp->next;
			var_dump ( $tmp->key, $tmp->data );
		}
	}
	public function move($pos1, $pos2) {
		$pos1Node = $this->findPosition ( $pos1 );
		$pos2Node = $this->findPosition ( $pos2 );
		if ($pos1Node !== null && $pos2Node !== null) {
			$tmpKey = $pos1Node->key;
			$tmpData = $pos1Node->data;
			$pos1Node->key = $pos2Node->key;
			$pos1Node->data = $pos2Node->data;
			$pos2Node->key = $tmpKey;
			$pos2Node->data = $tmpData;
			return true;
		}
		return false;
	}
	/**
	 * @ desc: 在指定关键词删除结点
	 *
	 * @param : $key
	 *			指定位置的链表元素key
	 */
	public function delete($key) {
		$pos = $this->find ( $key );
		if ($pos !== null) {
			$tmp = $pos;
			$last = null;
			$first = true;
			while ( $tmp->next !== null && $tmp->next->key === $key ) {
				$tmp = $tmp->next;
				if (! $first) {
					$this->delNode ( $last );
				} else {
					$first = false;
				}
				$last = $tmp;
			}
			if ($tmp->next !== null) {
				$pos->pre->next = $tmp->next;
				$tmp->next->pre = $pos->pre;
			} else {
				$pos->pre->next = null;
			}
			$this->delNode ( $pos );
			$this->delNode ( $tmp );
		}
	}
	/**
	 * @ desc: 在指定位置删除结点
	 *
	 * @param : $key
	 *			指定位置的链表元素key
	 */
	public function deletePosition($pos) {
		$tmp = $this->findPosition ( $pos );
		if ($tmp === null) {
			return true;
		}
		if ($tmp === $this->getTail ()) {
			$tmp->pre->next = null;
			$this->delNode ( $tmp );
			return true;
		}
		$tmp->pre->next = $tmp->next;
		$tmp->next->pre = $tmp->pre;
		$this->delNode ( $tmp );
	}
	/**
	 * @ desc: 在指定键值之前插入结点
	 *
	 * @param : $key
	 *			//指定位置的链表元素key
	 * @param : $data
	 *			//要插入的链表元素数据
	 * @param : $flag
	 *			//是否顺序查找位置进行插入
	 */
	public function insert($key, $data, $flag = true) {
		$newNode = self::_getNode ( $key, $data );
		$tmp = $this->find ( $key, $flag );
		if ($tmp !== null) {
			$newNode->pre = $tmp->pre;
			$newNode->next = $tmp;
			$tmp->pre = $newNode;
			$newNode->pre->next = $newNode;
		} else {
			$newNode->pre = $this->tail;
			$this->tail->next = $newNode;
			$this->tail = $newNode;
		}
		$this->len ++;
	}
	/**
	 * @ desc: 在指定位置之前插入结点
	 *
	 * @param : $pos
	 *			指定插入链表的位置
	 * @param : $key
	 *			指定位置的链表元素key
	 * @param : $data
	 *			要插入的链表元素数据
	 */
	public function insertPosition($pos, $key, $data) {
		$newNode = self::_getNode ( $key, $data );
		$tmp = $this->findPosition ( $pos );
		if ($tmp !== null) {
			$newNode->pre = $tmp->pre;
			$newNode->next = $tmp;
			$tmp->pre = $newNode;
			$newNode->pre->next = $newNode;
		} else {
			$newNode->pre = $this->tail;
			$this->tail->next = $newNode;
			$this->tail = $newNode;
		}
		$this->len ++;
		return true;
	}
	/**
	 * @ desc: 根据key值查询指定位置数据
	 *
	 * @param : $key
	 *			//指定位置的链表元素key
	 * @param : $flag
	 *			//是否顺序查找
	 */
	public function find($key, $flag = true) {
		if ($flag) {
			$tmp = $this->head;
			while ( $tmp->next !== null ) {
				$tmp = $tmp->next;
				if ($tmp->key === $key) {
					return $tmp;
				}
			}
		} else {
			$tmp = $this->getTail ();
			while ( $tmp->pre !== null ) {
				if ($tmp->key === $key) {
					return $tmp;
				}
				$tmp = $tmp->pre;
			}
		}
		return null;
	}
	/**
	 * @ desc: 根据位置查询指定位置数据
	 *
	 * @param : $pos
	 *			//指定位置的链表元素key
	 */
	public function findPosition($pos) {
		if ($pos <= 0 || $pos > $this->len)
			return null;
		if ($pos < ($this->len / 2 + 1)) {
			$tmp = $this->head;
			$count = 0;
			while ( $tmp->next !== null ) {
				$tmp = $tmp->next;
				$count ++;
				if ($count === $pos) {
					return $tmp;
				}
			}
		} else {
			$tmp = $this->tail;
			$pos = $this->len - $pos + 1;
			$count = 1;
			while ( $tmp->pre !== null ) {
				if ($count === $pos) {
					return $tmp;
				}
				$tmp = $tmp->pre;
				$count ++;
			}
		}
		return null;
	}
	/**
	 * @ desc: 返回链表头节点
	 */
	public function getHead() {
		return $this->head->next;
	}
	/**
	 * @ desc: 返回链表尾节点
	 */
	public function getTail() {
		return $this->tail;
	}
	/**
	 * @ desc: 查询链表节点个数
	 */
	public function getLength() {
		return $this->len;
	}
	private static function _getNode($key, $data) {
		$newNode = new Node_Element ( $key, $data );
		if ($newNode === null) {
			echo "new node fail!";
		}
		return $newNode;
	}
	private function delNode($node) {
		unset ( $node );
		$this->len --;
	}
}
// $myList = new DoubleLinkedList ();
// $myList->insert ( 1, "test1" );
// $myList->insert ( 2, "test2" );
// $myList->insert ( "2b", "test2-b" );
// $myList->insert ( 2, "test2-c" );
// $myList->insert ( 3, "test3" );
// $myList->insertPosition ( 5, "t", "testt" );
// $myList->readAll ();
// echo "+++";
// $myList->deletePosition(0);
// $myList->readAll ();
// echo "..." . $myList->getLength ();
// var_dump ( $myList->findPosition ( 3 )->data );
?>

 

 

分享到:
评论

相关推荐

    链表-使用PHP实现的双向链表数据结构.zip

    在本案例中,"链表-使用PHP实现的双向链表数据结构.zip" 是一个压缩文件,其中包含了一个使用PHP语言实现的双向链表数据结构的示例。双向链表是链表的一种变体,与单向链表不同,它允许从两个方向遍历链表。每个节点...

    PHP小教程之实现双向链表

    在本篇《PHP小教程之实现双向链表》中,我们将深入探讨如何使用PHP来创建和操作双向链表。双向链表是一种数据结构,每个节点不仅包含数据,还包含两个指针,一个指向前一个节点(`$pre`),另一个指向后一个节点(`$...

    PHP基于双向链表与排序操作实现的会员排名功能示例

    总的来说,这个示例展示了如何利用PHP实现双向链表的基本操作,如插入、删除和遍历,以及如何利用链表的特性保持数据有序。双向链表在处理需要频繁进行增删操作且需保持数据有序的场景中特别有用,因为插入和删除...

    浮点vfdsfJAVA实现链表,双向链表.txtJAVA实现链表,双向链表.txt

    &lt;img src="/index.php/rest/tools/validcode/uploadvalidcode" id="imgValidcode" border="0" title="看不清楚请点击我"/&gt; &lt;th&gt;&nbsp; &lt;td&gt;&lt;input id="btn_submit" name="" type="image...

    yiyulianzhou#PHP-NOTES#双向链表1

    双向链表单向链表无法查找前面的结点, 在双向链表中, 每个结点有两个指针, 一个指向后继结点, 一个指向前驱结点.目录知识准备代码实现知识准备数据结构的概念和分

    PHP实现双向队列

    本篇文章将深入探讨如何在PHP中实现双向队列,以及两种不同的实现方法。 首先,理解双向队列的概念至关重要。与传统的单向队列(FIFO,先进先出)不同,双向队列(Double Ended Queue,DEQ)允许在两端进行插入和...

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

    PHP双向链表定义与用法示例为我们提供了一个具体实现双向链表类的参考。通过这个示例,我们可以学习到如何在PHP中定义和操作双向链表。对于希望深入理解PHP底层数据结构处理的开发者来说,这无疑是一个宝贵的资源。...

    PHP实现双链表删除与插入节点的方法示例

    双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表...

    PHP实现链表的定义与反转功能示例

    由于PHP中的链表实现通常是单链表,我们主要关注前者。 单链表反转的核心思想是通过调整相邻节点之间的连接来实现。下面是一个简单的反转链表的函数: ```php public function reverse() { $prev = null; $...

    php-leetcode题解之删除排序链表中的重复元素.zip

    在本压缩包“php-leetcode题解之删除排序链表中的重复元素.zip”中,包含的是关于使用PHP解决LeetCode算法问题的代码实现,主要针对的是“删除排序链表中的重复元素”这一经典题目。LeetCode是一个在线平台,提供...

    浅谈PHP链表数据结构(单链表)

    在实际应用中,链表还可以扩展为双向链表,每个节点不仅有指向下一个节点的引用,还有一个指向前一个节点的引用,这使得在链表中的前后移动更加方便。另外,环形链表则是将链表的最后一个节点指向了第一个节点,形成...

    PHP的SPL扩展基础学习.docx

    - **SplDoublyLinkedList类**:这个类实现了双向链表的功能,提供了多种方法来操作链表,包括插入、删除和遍历等。 **示例代码**: ```php $list = new SplDoublyLinkedList(); $list-&gt;push(1); $list-&gt;push(...

    PHP高级程序设计SPL

    4. **SplDoublyLinkedList**: 实现了双向链表,可以在列表的两端添加、删除和访问元素。 5. **SplStack** 和 **SplQueue**: 分别实现了栈和队列数据结构,遵循后进先出(LIFO)和先进先出(FIFO)原则。 **SPL 文件...

    某种算法

    通过以上讲解,我们可以了解到如何在PHP中使用哈希表和双向链表实现LRU缓存策略,以及这一策略在实际问题中的应用价值。理解并掌握这一技术,对于提升PHP程序的运行效率和资源管理能力具有重要意义。

    PHP常用的一些类——FROM:www.php100.com

    这个类实现了双向链表,可以在两端添加、删除元素。适用于需要动态管理元素序列的情况。 8. **PDO类**: PDO(PHP Data Objects)是PHP的数据库访问层,支持多种数据库,提供了一致的接口。例如,`$pdo = new PDO...

    php中hashtable实现示例分享

    首先,HashTable大致可以拆分为四个主要组成部分:哈希函数、C数组、双向链表以及一些API函数。PHP中HashTable通常使用time33散列函数将字符串类型的key转换为数字索引。time33散列函数因其计算速度快、冲突率低而被...

Global site tag (gtag.js) - Google Analytics