PHP实现双向链表的插入删除和遍历

网上找的代码,发现如果插入的数据有重复,会因为链表值域里的key值重复输入,导致无限插入,自己更改了一下代码,仅供参考。欢迎大家提出BUG

<?php

    /**
     * 实现双向链表
     *
     * Class Node
     */
    class Node{
        public $pre; //前驱
        public $key; //键
        public $val; //值
        public $next; //后继

        /**
         * Node constructor.
         * @param string $key
         * @param string $val
         */
        public function __construct($key = "", $val = ""){
            $this->key = $key;
            $this->val = $val;
        }

        /**
         * 插入到指定键的节点后边
         *
         * @param $head
         * @param $node
         * @param $key
         */
        static public function add($head , $node, $key = ""){
            $cur = $head;
            $isFind = false;

            //判断插入的key是否存在
            while($cur != null){
                if($cur->key == $node->key){
                    echo '键值' . $node->key . '已存在' . '<br>';
                    return false;
                }
                $cur = $cur->next;
            }
            $cur = $head;

            //判断目前这个链表是否为空
            if($cur->next == null){
                //如果为空,直接添加到头后边
                $cur->next = $node;
                $node->pre = $cur;
            } else{
                //如果不是空链表,添加到指定位置
                while($cur != null){
                    //如果key等于当前节点的key,跳出
                    if($cur->key == $key){
                        $isFind = true;
                        break;
                    }
                    $cur = $cur->next;
                }
                if($isFind){
                    //如果目标节点的后继为空
                    if($cur->next != null){
                        $node->next = $cur->next;//新插入节点的后继指向当前节点的后继
                        $node->pre = $cur;//新插入节点的前驱指向当前节点
                        $cur->next->pre = $node;//当前节点的下一节点的前驱指向新插入节点
                        $cur->next = $node;//当前节点的后继指向新插入节点
                    }else{
                        $node->next = null;
                        $node->pre = $cur;
                        $cur->next = $node;
                    }
                }else{
                    echo '没有找到该节点';
                }


            }

        }

        /**
         *遍历
         *
         * @param $head
         */
        static public function showLink($head){
            $cur = $head;
            while($cur->next != null){
                echo '键:' . $cur->next->key . "值:" . $cur->next->val . '<br>';
                $cur = $cur->next;
            }

        }

        /**
         * 根据key删除某个节点
         *
         * @param $head
         * @param $key
         */
        static public function del($head, $key){
            $cur = $head;
            $isFind = false;
            while($cur != null){
                if($cur->key == $key){
                    $isFind = true;
                    break;
                }
                $cur = $cur->next;
            }
            if($isFind){
                if($cur->next == null){
                     $cur->pre->next = null;
                }else{
                    $cur->pre->next = $cur->next;
                }
            }else{
                echo '没有该节点,删除失败' . '<br>';
            }
        }



    }

    header("Content-type:text/html;charset=utf-8");
    $head = new Node();
    $node1 = new Node(1,'111');
    $node2 = new Node(2,'222');
    $node3 = new Node(3,'333');
    Node::add($head, $node1);
    Node::add($head, $node2, 1);
    Node::add($head, $node3, 2);
    Node::showLink($head);
    echo '<br>';
    Node::del($head,1);
    Node::showLink($head);

?>

猜你喜欢

转载自blog.csdn.net/why444216978/article/details/80698275