php实现链表基本操作:push、pop、update

php实现单链表的基本操作:push、pop、update

链表:

  • 内存中非连续存储(线性表是连续存储的,比如数组)
  • 每个节点,包含值(data),和前后节点信息(next 或 pre)
  • 对链表的操作,内存中执行的步骤比较少,比线性链表少很多

以下是php实现链表的pop、push、update基本操作:

<?php
/**
 * Created by PhpStorm.
 * User: wkk
 * Time: 2021/7/10 - 18:43
 * Desc: <php实现单链表>
 */

/**
 * 节点类:
 * data: 存放数据
 * next: 指向下个节点
 *
 * Class Node
 */
class Node
{
    public $data;
    public $next;

    public function __construct($data = null, $next = null)
    {
        // 每个节点有 data 和 next,初始第一个都是空
        $this->data = $data;
        $this->next = $next;
    }
}

class Link
{
    public $size; // 大小
    public $head; // 头节点

    public function __construct()
    {
        $this->head = new Node();
        $this->size = 0;
    }

    /**
     * push 操作
     * 链表结尾 插入元素
     *
     * @throws Exception
     */
    public function push($value): Link
    {
        // head 没有值,放在head节点
        if ($this->head->data === null) {
            $this->head->data = $value;
            $this->size++;
            return $this;
        }

        // head 有值时,追加到后边
        $currentNode = $this->head;
        while ($currentNode->next !== null) {
            $currentNode = $currentNode->next;
        }
        // 最后的节点 插入新的节点=
        $currentNode->next = new Node($value, null);
        $this->size++;
        return $this;
    }

    /**
     * 更新index位置的数据,第一个元素 下标 为 0
     *
     * @param $index
     * @param $value
     * @return $this|false
     */
    public function update($index, $value)
    {
        if ($this->size === 0) {
            return false;
        }

        $i       = 0;
        $current = $this->head;
        while ($i !== $index) {
            $current = $current->next;
            $i++;
        }

        $current->data = $value;
        return $this;
    }

    /**
     * pop操作
     * 从链表的首部取出元素,长度—1
     */
    public function pop()
    {
        // 空链表,无数据
        if ($this->size === 0) {
            return null;
        }

        // 移出去head,则head->next 为 新的head
        $data = $this->head->data;
        $this->head = $this->head->next;
        $this->size --;
        return $data;
    }

    /**
     * 取出index位置的数据
     * @param $index
     * @return null
     */
    public function get($index)
    {
        if ($this->size === 0) {
            return null;
        }

        $i       = 0;
        $current = $this->head->next;
        while ($i !== $index) {
            $current = $current->next;
            $i++;
        }

        // 最后的$current就是当前的index位置节点
        return $current->data;
    }

    /**
     * @return int
     */
    public function getSize(): int
    {
        return $this->size;
    }

    /**
     * 删除圣墟排列的列表中 有序链表中重复出现的元素
     * 输入: 1->2->3->3->4->4->5
     * 输出: 1->2->5
     */
    public function deleteDuplicates(): ?Node
    {
        if ($this->size === 0) {
            return null;
        }

        // 思路:如果当前节点的值 === 下个节点的值,需要删除这两个节点
        if ($this->head->next !== null && $this->head->data === $this->head->next->data) {
            // 循环一直找到当前节点和下个节点值不一样的情况
            while($this->head->next !== null && $this->head->data === $this->head->next->data) {
                // 往前移动一个节点
                $this->head = $this->head->next;
            }

            return $this->deleteDuplicates();
        }

        // $this->head->next = $this->deleteDuplicates();

        return $this->head;
    }
}

$link = new Link();
try {

    // push 两个数
    $link->push(1);
    $link->push(2);
    $link->push(3);
    $link->push(4);
    $link->push(5);
    $link->push(6);

    // pop 一个数,
    var_dump($link->pop());
    var_dump($link);die;

    // 删除重复的
    // $link->deleteDuplicates();
} catch (Exception $e) {
    wkk('异常信息:' . $e->getMessage());
}
wkk($link);


function wkk($data)
{
    echo '<pre>';
    var_dump($data);
}

posted @ 2021-07-11 16:31  alisleepy  阅读(600)  评论(0编辑  收藏  举报