• 算法笔记-经典链表操作案例


    • 单链表反转
    • 链表中环的检测
    • 两个有序的链表合并
    • 删除链表倒数第 n 个结点
    • 求链表的中间结点 
    <?php
    /**
     * User: lide01
     * Date: 2018/10/9 14:06
     * Desc:
     */
    
    namespace Algo_07;
    require_once '../vendor/autoload.php';
    
    use Algo_06SingleLinkedList;
    
    
    /**
     * 单链表相关算法
     *
     * Class SingleLinkedListAlgo
     *
     * reverse 单链表反转
     * checkCircle 链表中环的检测
     * mergerSortedList 两个有序的链表合并
     * deleteLastKth 删除链表倒数第n个结点
     * findMiddleNode 求链表的中间结点
     *
     * @package Algo_07
     */
    Class SingleLinkedListAlgo
    {
        /**
         * 单链表
         *
         * @var
         */
        public $list;
    
        /**
         * 构造函数设置$list
         *
         * SingleLinkedListAlgo constructor.
         *
         * @param SingleLinkedList $list
         */
        public function __construct(SingleLinkedList $list = null)
        {
            $this->list = $list;
        }
    
        /**
         * 设置单链表
         *
         * @param SingleLinkedList $list
         */
        public function setList(SingleLinkedList $list)
        {
            $this->list = $list;
        }
    
        /**
         * 单链表反转
         *
         * 三个指针反转
         * preNode 指向前一个结点
         * curNode 指向当前结点
         * remainNode 指向当前结点的下一个节点(保存未逆序的链表,为了在断开curNode的next指针后能找到后续节点)
         *
         * @return bool
         */
        public function reverse()
        {
            if (null == $this->list || null == $this->list->head || null == $this->list->head->next) {
                return false;
            }
    
            $preNode = null;
            $curNode = $this->list->head->next;
            $remainNode = null;
    
            // 保存头结点,稍后指向反转后的链表
            $headNode = $this->list->head;
            // 断开头结点的next指针
            $this->list->head->next = null;
    
            while ($curNode != null) {
                $remainNode = $curNode->next;
                $curNode->next = $preNode;
                $preNode = $curNode;
                $curNode = $remainNode;
            }
    
            // 头结点指向反转后的链表
            $headNode->next = $preNode;
    
            return true;
        }
    
        /**
         * 判断链表是否有环
         *
         * 快慢指针判断是否有环
         * @link http://t.cn/ROxpgQ1
         *
         * @return bool
         */
        public function checkCircle()
        {
            if (null == $this->list || null == $this->list->head || null == $this->list->head->next) {
                return false;
            }
    
            $slow = $this->list->head->next;
            $fast = $this->list->head->next;
    
            while ($fast != null && $fast->next != null) {
                $fast = $fast->next->next;
                $slow = $slow->next;
    
                // 如果慢指针跟快指针相遇了说明有环 解释在上面的链接中
                if ($slow === $fast) {
                    return true;
                }
            }
    
            return false;
        }
    
        /**
         * 合并两个有序链表
         *
         * @param SingleLinkedList $listA
         * @param SingleLinkedList $listB
         *
         * @return SingleLinkedList|Algo_06SingleLinkedListNode
         */
        public function mergerSortedList(SingleLinkedList $listA, SingleLinkedList $listB)
        {
            if (null == $listA) {
                return $listB;
            }
            if (null == $listB) {
                return $listA;
            }
    
            $pListA = $listA->head->next;
            $pListB = $listB->head->next;
            $newList = new SingleLinkedList();
            $newHead = $newList->head;
            $newRootNode = $newHead;
    
            while ($pListA != null && $pListB != null) {
                if ($pListA->data <= $pListB->data) {
                    $newRootNode->next = $pListA;
                    $pListA = $pListA->next;
                } else {
                    $newRootNode->next = $pListB;
                    $pListB = $pListB->next;
                }
    
                $newRootNode = $newRootNode->next;
            }
    
            // 如果第一个链表未处理完,拼接到新链表后面
            if ($pListA != null) {
                $newRootNode->next = $pListA;
            }
            // 如果第二个链表未处理完,拼接到新链表后面
            if ($pListB != null) {
                $newRootNode->next = $pListB;
            }
    
            return $newList;
        }
    
        /**
         * 删除链表倒数第n个结点
         *
         * @param $index
         *
         * @return bool
         */
        public function deleteLastKth($index)
        {
            if (null == $this->list || null == $this->list->head || null == $this->list->head->next) {
                return false;
            }
    
            $i = 1;
            $slow = $this->list->head;
            $fast = $this->list->head;
            while ($fast != null && $i < $index) {
                $fast = $fast->next;
                ++$i;
            }
    
            if ($fast == null) {
                return true;
            }
    
            $pre = null;
            while($fast->next != null) {
                $pre = $slow;
                $slow = $slow->next;
                $fast = $fast->next;
            }
    
            if (null == $pre) {
                $this->list->head->next = $slow->next;
            } else {
                $pre->next = $pre->next->next;
            }
    
            return true;
        }
    
        /**
         * 寻找中间节点
         *
         * 快慢指针遍历
         *
         * @return Algo_06SingleLinkedListNode|bool|null
         */
        public function findMiddleNode()
        {
            if (null == $this->list || null == $this->list->head || null == $this->list->head->next) {
                return false;
            }
    
            $slow = $this->list->head->next;
            $fast = $this->list->head->next;
    
            while ($fast != null && $fast->next != null) {
                $fast = $fast->next->next;
                $slow = $slow->next;
            }
    
            return $slow;
        }
    }
    
    
    $list = new SingleLinkedList();
    $list->insert(1);
    $list->insert(2);
    $list->insert(3);
    $list->insert(4);
    $list->insert(5);
    $list->insert(6);
    $list->insert(7);
    
    // 单链表反转
    echo "单链表反转 
    ";
    $listAlgo = new SingleLinkedListAlgo($list);
    $listAlgo->list->printList();
    $listAlgo->reverse();
    $listAlgo->list->printList();
    
    // 链表中环的检测
    echo "
    链表中环的检测 
    ";
    $listCircle = new SingleLinkedList();
    $listCircle->buildHasCircleList();
    $listAlgo->setList($listCircle);
    var_dump($listAlgo->checkCircle());
    
    // 两个有序的链表合并
    echo "
    两个有序的链表合并 
    ";
    $listA = new SingleLinkedList();
    $listA->insert(9);
    $listA->insert(7);
    $listA->insert(5);
    $listA->insert(3);
    $listA->insert(1);
    $listA->printList();
    
    $listB = new SingleLinkedList();
    $listB->insert(10);
    $listB->insert(8);
    $listB->insert(6);
    $listB->insert(4);
    $listB->insert(2);
    $listB->printList();
    
    $listAlgoMerge = new SingleLinkedListAlgo();
    $newList = $listAlgoMerge->mergerSortedList($listA, $listB);
    $newList->printListSimple();
    
    // 删除链表倒数第n个结点
    echo "
    删除链表倒数第n个结点 
    ";
    $listDelete = new SingleLinkedList();
    $listDelete->insert(1);
    $listDelete->insert(2);
    $listDelete->insert(3);
    $listDelete->insert(4);
    $listDelete->insert(5);
    $listDelete->insert(6);
    $listDelete->insert(7);
    $listDelete->printList();
    $listAlgo->setList($listDelete);
    $listAlgo->deleteLastKth(3);
    var_dump($listAlgo->list->printListSimple());
    
    // 求链表的中间结点
    echo "
    求链表的中间结点 
    ";
    $listAlgo->setList($list);
    $middleNode = $listAlgo->findMiddleNode();
    var_dump($middleNode->data);
    
    echo "
    ";

  • 相关阅读:
    最新第四套人民币冠号大全
    使用Java程序调用MatLab
    Android 横屏时禁止输入法全屏
    linux 从命令行自动识别文件并将其打开的命令
    deep learning 的java库
    重磅!神经网络浅讲:从神经元到深度学习
    开源的c语言人工神经网络计算库 FANN
    开源java神经网络组件Joone、Encog和Neuroph
    基于Storm 分布式BP神经网络,将神经网络做成实时分布式架构
    git:could not open a connection to your authentication agent
  • 原文地址:https://www.cnblogs.com/rxbook/p/10338737.html
Copyright © 2020-2023  润新知