由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给你走指针,自己处理处理数据就可以,简单化了操作,复杂了理解,不确定是否理解正确,如果有问题请反馈

 

转载于:https://www.cnblogs.com/zx-admin/p/10430782.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值