算法笔记-判断链表保存的字符串是否是回文
生活随笔
收集整理的這篇文章主要介紹了
算法笔记-判断链表保存的字符串是否是回文
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
<?php/*** 單鏈表節點** Class SingleLinkedListNode** @package Algo_06*/
class SingleLinkedListNode
{/*** 節點中的數據域** @var null*/public $data;/*** 節點中的指針域,指向下一個節點** @var SingleLinkedListNode*/public $next;/*** SingleLinkedListNode constructor.** @param null $data*/public function __construct($data = null){$this->data = $data;$this->next = null;}
} /*** 單鏈表** Class SingleLinkedList** @package Algo_06*/
class SingleLinkedList
{/*** 單鏈表頭結點(哨兵節點)** @var SingleLinkedListNode*/public $head;/*** 單鏈表長度** @var*/private $length;/*** 初始化單鏈表** SingleLinkedList constructor.** @param null $head*/public function __construct($head = null){if (null == $head) {$this->head = new SingleLinkedListNode();} else {$this->head = $head;}$this->length = 0;}/*** 獲取鏈表長度** @return int*/public function getLength(){return $this->length;}/*** 插入數據 采用頭插法 插入新數據** @param $data** @return SingleLinkedListNode|bool*/public function insert($data){return $this->insertDataAfter($this->head, $data);}/*** 刪除節點** @param SingleLinkedListNode $node** @return bool*/public function delete(SingleLinkedListNode $node){if (null == $node) {return false;}// 獲取待刪除節點的前置節點$preNode = $this->getPreNode($node);// 修改指針指向$preNode->next = $node->next;unset($node);$this->length--;return true;}/*** 通過索引獲取節點** @param int $index** @return SingleLinkedListNode|null*/public function getNodeByIndex($index){if ($index >= $this->length) {return null;}$cur = $this->head->next;for ($i = 0; $i < $index; ++$i) {$cur = $cur->next;}return $cur;}/*** 獲取某個節點的前置節點** @param SingleLinkedListNode $node** @return SingleLinkedListNode|bool*/public function getPreNode(SingleLinkedListNode $node){if (null == $node) {return false;}$curNode = $this->head;$preNode = $this->head;// 遍歷找到前置節點 要用全等判斷是否是同一個對象// http://php.net/manual/zh/language.oop5.object-comparison.phpwhile ($curNode !== $node && $curNode != null) {$preNode = $curNode;$curNode = $curNode->next;}return $preNode;}/*** 輸出單鏈表 當data的數據為可輸出類型** @return bool*/public function printList(){if (null == $this->head->next) {return false;}$curNode = $this->head;// 防止鏈表帶環,控制遍歷次數$listLength = $this->getLength();while ($curNode->next != null && $listLength--) {echo $curNode->next->data . ' -> ';$curNode = $curNode->next;}echo 'NULL' . PHP_EOL;return true;}/*** 輸出單鏈表 當data的數據為可輸出類型** @return bool*/public function printListSimple(){if (null == $this->head->next) {return false;}$curNode = $this->head;while ($curNode->next != null) {echo $curNode->next->data . ' -> ';$curNode = $curNode->next;}echo 'NULL' . PHP_EOL;return true;}/*** 在某個節點后插入新的節點 (直接插入數據)** @param SingleLinkedListNode $originNode* @param $data** @return SingleLinkedListNode|bool*/public function insertDataAfter(SingleLinkedListNode $originNode, $data){// 如果originNode為空,插入失敗if (null == $originNode) {return false;}// 新建單鏈表節點$newNode = new SingleLinkedListNode();// 新節點的數據$newNode->data = $data;// 新節點的下一個節點為源節點的下一個節點$newNode->next = $originNode->next;// 在originNode后插入newNode$originNode->next = $newNode;// 鏈表長度++$this->length++;return $newNode;}/*** 在某個節點前插入新的節點(很少使用)** @param SingleLinkedListNode $originNode* @param $data** @return SingleLinkedListNode|bool*/public function insertDataBefore(SingleLinkedListNode $originNode, $data){// 如果originNode為空,插入失敗if (null == $originNode) {return false;}// 先找到originNode的前置節點,然后通過insertDataAfter插入$preNode = $this->getPreNode($originNode);return $this->insertDataAfter($preNode, $data);}/*** 在某個節點后插入新的節點** @param SingleLinkedListNode $originNode* @param SingleLinkedListNode $node** @return SingleLinkedListNode|bool*/public function insertNodeAfter(SingleLinkedListNode $originNode, SingleLinkedListNode $node){// 如果originNode為空,插入失敗if (null == $originNode) {return false;}$node->next = $originNode->next;$originNode->next = $node;$this->length++;return $node;}/*** 構造一個有環的鏈表*/public function buildHasCircleList(){$data = [1, 2, 3, 4, 5, 6, 7, 8];$node0 = new SingleLinkedListNode($data[0]);$node1 = new SingleLinkedListNode($data[1]);$node2 = new SingleLinkedListNode($data[2]);$node3 = new SingleLinkedListNode($data[3]);$node4 = new SingleLinkedListNode($data[4]);$node5 = new SingleLinkedListNode($data[5]);$node6 = new SingleLinkedListNode($data[6]);$node7 = new SingleLinkedListNode($data[7]);$this->insertNodeAfter($this->head, $node0);$this->insertNodeAfter($node0, $node1);$this->insertNodeAfter($node1, $node2);$this->insertNodeAfter($node2, $node3);$this->insertNodeAfter($node3, $node4);$this->insertNodeAfter($node4, $node5);$this->insertNodeAfter($node5, $node6);$this->insertNodeAfter($node6, $node7);$node7->next = $node4;}
} /*** 判斷鏈表保存的字符串是否是回文** @param SingleLinkedList $list** @return bool*/
function isPalindrome(SingleLinkedList $list)
{if ($list->getLength() <= 1) {return true;}$pre = null;$slow = $list->head->next;$fast = $list->head->next;$remainNode = null;// 找單鏈表中點 以及 反轉前半部分鏈表while ($fast != null && $fast->next != null) {$fast = $fast->next->next;// 單鏈表反轉關鍵代碼 三個指針$remainNode = $slow->next;$slow->next = $pre;$pre = $slow;$slow = $remainNode;}// 鏈表長度為偶數的情況if ($fast != null) {$slow = $slow->next;}// 開始逐個比較while ($slow != null) {if ($slow->data != $pre->data) {return false;}$slow = $slow->next;$pre = $pre->next;}return true;
}$list = new SingleLinkedList();
$list->insert('a');
$list->insert('b');
$list->insert('c');
$list->insert('c');
$list->insert('b');
$list->insert('a');var_dump(isPalindrome($list));
?
轉載于:https://www.cnblogs.com/rxbook/p/10338763.html
總結
以上是生活随笔為你收集整理的算法笔记-判断链表保存的字符串是否是回文的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: NEO从源码分析看nep2与nep6
- 下一篇: OpenSSL常用命令快速上手