首页 > 编程语言 >php实现单链表

php实现单链表

时间:2022-11-11 16:47:11浏览次数:36  
标签:node head 单链 no 实现 next insertNode php 节点

今天记录下使用php实现单向链表的功能操作

先创建一个节点类用来生成节点对象

<?php
class node{
    public $name = null;
    public $no = null;
    public $next = null;
    public function __construct($name = '',$no = null,$next=null){
        $this->name = $name;
        $this->no = $no;
        $this->next = $next;
    }
}

此类对象有三个属性名称,编号,下一个节点的地址

创建链表操作类,实现了简单的添加,查找,展示,删除操作

<?php
class single{
    //查询
    public function findLinkOne($head,$no){
        $currentNode = $head;
        $findNode = null;

        while($currentNode->next != null){
            if($currentNode->no == $no){
                $findNode = $currentNode;
                break;
            }

            $currentNode = $currentNode->next;
        }

        if($findNode){
            return $findNode;
        }

        return -1;
    }
    
    //展示
    public function showAll($head){
        $cursor = $head;

        if(!$cursor->next){
            echo "Nothing to find! <br/>";
            return;
        }

        while($cursor->next != null){
            echo "No:{$cursor->next->no},Name:{$cursor->next->name} <br/>";
            $cursor = $cursor->next;
        }

        echo "Show all of this list <br/>";
        return;
    }

    //添加
    public function addLinkOne($head,$node){
        $insertNode = $head;
        $afterNode = null;

        while($insertNode->next != null){
            
            if($insertNode->next->no > $node->no){
                $afterNode = $insertNode->next;
                break;
            }else if($insertNode->next->no == $node->no){
                echo "This node in list !<br/>";
                return;
            }

            $insertNode = $insertNode->next;
        }

        if($afterNode){
            $node->next = $afterNode;
        }
        
        $insertNode->next = $node;
    }

    //删除
    public function delLinkOne($head,$no){
        $cursor = $head;
        $preNode = $head;

        while($cursor->next != null){
            $preNode = $cursor;
            $cursor = $cursor->next;
            if($cursor->no == $no){
                $preNode->next = $cursor->next;
            }
        }

        return true;
    }
}

下面开始调用测试

$singleObj = new single();
$head = new node();

实例化链表类和节点类生成一个头节点

$singleObj->addLinkOne($head,new node('赵不亮',1));
$singleObj->addLinkOne($head,new node('钱不够',2));
$singleObj->addLinkOne($head,new node('孙悟空',3));
$singleObj->addLinkOne($head,new node('王梓',8));
$singleObj->addLinkOne($head,new node('郑品',7));
$singleObj->addLinkOne($head,new node('周围',5));
$singleObj->addLinkOne($head,new node('吴发',6));
$singleObj->addLinkOne($head,new node('李四',4));

$singleObj->showAll($head);

调用链表添加方法加入8个顺序混乱的节点对象,最后调用展示方法查看生成的链表

 

 可以看到节点对象都存入链表并按no编号从小到大顺序保存好了

$singleObj->delLinkOne($head,3);
$singleObj->delLinkOne($head,5);
$singleObj->showAll($head);

调用删除方法按no编号删除指定节点

 

 可以看到编号3和编号5的节点已经从链表中移除了

 

在这个链表类中核心代码就是链表的添加和删除两个方法现在来具体分析下其思路

 

 在这个方法中,进入方法先定义了一个游标节点,并将其赋值为头节点(这就是为什么要创建一个空的头节点,没有这个我们不知道从哪里开始找)

在添加第一个节点时,$insertNode节点是头节点它的下一个节点的地址是空的,因此不会进入循环,$afterNode节点也是空的所以会直接走最后一行将传入的节点直接挂在头节点的后面,即将$node对象的地址存入$insertNode->next属性

在添加第二个节点时,仍然从头节点开始找起,但此时头结点next属性挂载了no 为1的节点因此会进入到循环体中执行,

  判断$insertNode->next->no > $node->no的结果,注意此时是添加节点2的首次循环,因此$insertNode当前是头节点,$insertNode->next->no即代表的是他挂载的下一个节点的no属性也就是节点1的no属性,他的值是1因此判断条件不成立

  而此时$insertNode->next->no == $node->no条件也不成立,所以本次循环只执行了循环体的最后一步将当前节点的下一个节点地址赋值给游标,即游标向前移动一步。

  所有的按从小到大顺序加入的节点都会是这个流程,无论其no属性是否连贯。

但是直到添加节点7时情况发生了变化。此时游标移动到节点3时,判断$insertNode->next->no > $node->no的结果此时结果成立会进入if分支执行

  此时我们找到了节点7的插入点,他应是在3之后8之前

  这里我们会先将3节点的下一个节点,即no=8的节点地址记录到$afterNode,此时$insertNode代表的是节点3因此获取节点8的地址要使用next属性获取

  找到插入点,记录好需要向后移动的节点8地址后,我们就可以跳出循环体了(循环体的作用就是找到插入点并记录向后移动的节点地址)

  最后我们只需要把$afterNode(节点8)挂载到$node->next属性,将$node(节点7)挂载到$insertNode(节点3)的next属性即可完成节点插入

删除操作和添加相反,这里我们要记录的是游标的上一个节点,当游标的no属性与传入的参数$no相等时我们找到了要删除的节点,此时我们要把游标节点的地址赋值给游标上级节点的next属性,即在遍历链表时找不到此时的游标节点即认为其被删除。

查找和展示没什么逻辑上的难点,只需要注意遍历完一个节点后向后移动游标即可。

标签:node,head,单链,no,实现,next,insertNode,php,节点
From: https://www.cnblogs.com/python-gulp-php/p/16880963.html

相关文章

  • Promise 的模拟实现
    1.为什么会有Promise当我们多次进行有依赖的网络请求或者文件请求时,很可能会造成代码的层层嵌套,导致回调地狱的出现:$.ajax({url:"xxx",success:function(......
  • 小程序逆向 换Otoken实现登录
    最近做小程序逆向,拿到微信开发工具打开虽然没有报错,但是登录的时候一直提示登录身份过期。最终找到解决办法,在这分享一下。手机微信登录小程序,抓包找到Otoken参数然后......
  • PHP垃圾回收机制
    PHP5.3的新的垃圾回收机制(也就是GC)的特点。 引用计数基本知识每个php变量存在一个叫"zval"的变量容器中。一个zval变量容器,除了包含变量的类型和值,还包括两个字节的额外信......
  • 【JSR269实战】之编译时操作AST,修改字节码文件,以实现和lombok类似的功能
    参考:https://blog.csdn.net/justry_deng/article/details/106176181maven编译不成功。笔者日常****:兄弟姐妹们,还是尽量少熬夜啊。我感觉我记性有所下降,难受。需求说......
  • PHP中获取不到自定义header参数解决方案
    一、概述今天在通过PHP中获取自定义header参数时候,一直获取不到。比如,获取header中USER_NAME参数,如下:123$curUser = isset($_SERVER['USER_NAME']) ? $_SERVER['USE......
  • 利用无线物联网控制器实现土壤温湿度的在线测量
    现如今物联网技术深入千家万户,带动各行各业的发展。比如快递分拣机器人,送餐机器人,智慧农业,智慧养殖等。物联网技术提供了更加快捷方便的生活,协助工人与工程师完成生产制造......
  • Android实战简易教程-第二十五枪(基于Baas的数据表查询下拉刷新和上拉加载实现!)
    上一节我们实现了数据表的加载,但是,当数据表数据很多时,我们就要考虑数据的分页,这里我们选用了PullToRefreshListView控件,先看一下该控件的说明:效果图:        ......
  • PHP构造验证码
    代码如下:<?phpheader('Content-type:image/jpeg');$width=120;$height=40;$element=array('a','b','c','d','e','f','g','h','i','j','k','m......
  • 百度富文本编辑器UEditor配置及功能实现详解
    ​ 当前功能基于PHP,其它语言流程大抵相同。大概流程:1.将docx文件上传到服务器中2.使用PHPoffice/PHPword实现将word转换为HTML3.将HTML代码返回并赋值到编辑器中......
  • 用(Atomic原子类 使用)实现自增
    //静态变量存储最大值privatestaticfinalAtomicIntegeratomicNum=newAtomicInteger();privatestaticfinalIntegerINIT_CODE_NUM=0;publicStringgetCode......