zoukankan      html  css  js  c++  java
  • 由PHP实现单向链表引发的对象赋值,对象传参,链表操作引发的一系列问题

    2019年2月25日14:21:13

    测试版本php 5.4 ,5.6,7.0,7.2

    代码请看: https://www.cnblogs.com/zx-admin/p/10373866.html

    1,对象赋值

    final class Node {
    
        public $data;
        public $next = null;
    
        public function __construct($data) {
            $this->data = $data;
        }
    
    }
    
    $a = new Node(['a']);
    p($a->data);
    $b = $a;
    //修改$a的data看是否影响
    $a->data = 'sssss';
    p($b->data);
    Array
    (
        [0] => a
    )
    sssss

    会影响$a的数据

    $b = &$a;
    $b = $a;

    对于对象来说就是取地址符,但是注意PHP的&不是取地址符,是别名,注意这个是官方解释,但是注意下面的 对象传参,又是另一种写法

    $b = clone $a;

    会裂变成连个完全独立的内存地址指向

    2,对象传参,或者对象传值,对象数据内部遍历指针的问题

    代码

    final class Node {
    
        public $data;
        public $next = null;
    
        public function __construct($data) {
            $this->data = $data;
        }
    
    }
    
    final class LinkedList {
    
    //    //从链表尾部压入一个节点,节点自动维护,不需要要像main方法那样自己维护
        public function push(Node $head, Node $Node) {
            $current = $head; //让$current指向$head;
            while ($current->next != null) {
                $current = $current->next;
            }
            $current->next = $Node->next;
            $current->next = $Node;
        }
    
        //从链表尾压出一个节点
        public function pop(Node $head) {
            $current = $head; //让$current指向$head;
            while ($current->next != null) {
                //提前查找链表尾部是否为空,为空就是尾部,吧当前节点的next复制问NULL,就是尾部元素干掉
                if ($current->next->next == null) {
                    break;
                }
                $current = $current->next;
            }
            $current->next = null;
        }
    
    }
    
    $head = new Node([]);
    $a = new Node(['a']);
    $b = new Node(['b']);
    $c = new Node(['c']);
    $d = new Node(['d']);
    
    $LinkedList = new LinkedList();
    $LinkedList->push($head, $a);
    $LinkedList->push($head, $b);
    $LinkedList->push($head, $c);
    $LinkedList->push($head, $d);
    $LinkedList->pop($head);
    pp($head);

    结果

    Node Object
    (
        [data] => Array
            (
            )
    
        [next] => Node Object
            (
                [data] => Array
                    (
                        [0] => a
                    )
    
                [next] => Node Object
                    (
                        [data] => Array
                            (
                                [0] => b
                            )
    
                        [next] => Node Object
                            (
                                [data] => Array
                                    (
                                        [0] => c
                                    )
    
                                [next] => 
                            )
    
                    )
    
            )
    
    )

    现阶段从结果反推的是对象传参,会自动变成引用对象传参,就是我们平常的写法

    function functionName(&$param) {
        
    }

    类似这种的效果

    但是,这个还不是关键

    这段代码才是关键

      public function push(Node $head, Node $Node) {
            $current = $head; //让$current指向$head;
            while ($current->next != null) {
                $current = $current->next;
            }
            $current->next = $Node->next;
            $current->next = $Node;
        }

    还可以写成这样的

        public function push(Node $head, Node $Node) {
    
            while ($head->next != null) {
                $head = $head->next;
            }
            $head->next = $Node->next;
            $head->next = $Node;
        }

    按照我们正常的理解,遍历一个对象  $head 被再次复制,那么遍历到最后$head->next = $Node;应该只剩一个对象元素才对

    但是打印 pp($head);依然是没有问题是一个完整的链表

    因为无法理解这个遍历过程  pop方法我写了两天无法完成,后来是通过画出链表结构才写出来的了,同时参考了

    https://blog.csdn.net/wenximalong/article/details/8296061 

    但是依然无法理解遍历对象的为什么不管有没有指向$head 的变量使用while遍历的时候发生了什么,这种结构的树状的对象数据,for或者foreach 当然不好使

    请参看

    https://www.cnblogs.com/zx-admin/p/9820866.html

    如果硬要解释的话,不管for foreach while  key next 等方法,在使用的时候都独立维护这一套指针,为了完成复杂的指针,指针移动完成不会影响传入的变量或者变量对象

    画了个示意图,不保证完全正确,不具备给他们语言的参考性,注意!

    就相当于while给你走指针,自己处理处理数据就可以,简单化了操作,复杂了理解,不确定是否理解正确,如果有问题请反馈

  • 相关阅读:
    Linq聚合操作之Aggregate,Count,Sum,Distinct源码分析
    Linq分区操作之Skip,SkipWhile,Take,TakeWhile源码分析
    Linq生成操作之DefautIfEmpty,Empty,Range,Repeat源码分析
    Linq基础操作之Select,Where,OrderBy,ThenBy源码分析
    PAT 1152 Google Recruitment
    PAT 1092 To Buy or Not to Buy
    PAT 1081 Rational Sum
    PAT 1084 Broken Keyboard
    PAT 1077 Kuchiguse
    PAT 1073 Scientific Notation
  • 原文地址:https://www.cnblogs.com/zx-admin/p/10430782.html
Copyright © 2011-2022 走看看