PHP 映射(Map)实现

本文介绍了如何在PHP中使用链表和二分搜索树实现映射数据结构。详细阐述了节点定义、LinkedListMap及BinarySearchTreeMap类,并通过Map接口确保实现一致性。同时提供了输出演示文件以展示操作效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

数据结构-PHP 映射(Map)实现

这篇文章主要介绍如何使用链表实现 映射(Map),映射是一个存储(键,值)数据对的数据结构(key-value),它的特点是根据键(key)去寻找值(value),下面主要介绍如何使用 链表 去实现 映射(Map)和使用 二分搜索树(Binary Search Tree) 去实现 映射(Map)

1.基于链表的映射(Map)实现

1.1 节点定义
/**
 * 映射节点定义
 * Class Node
 */
class Node
{
    public $key;
    public $value;
    public $next;

    public function __construct($key, $value, $next)
    {
        $this->key = $key;
        $this->value = $value;
        $this->next = $next;
    }
}
1.2 LinkedListMap 类

这是一个基于链表实现的映射(Map)类,里面有 add($key,$value)方法向链表添加 key-value 键值对,contains($key)方法判断映射(Map)中是否包含 $key 对应的 key-value 键值对,set($key, $value)方法可以更新 key-value 键值对中的 value值,remove($key)方法可以删除 key 等于 $key 对应的 key-value 键值对。

<?php
require 'Map.php';

/**
 * 基于链表的映射(Map)实现
 * Class LinkedListMap
 */
class LinkedListMap implements Map
{
    public $dummyHead;
    public $size;

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

    /**
     * 向链表添加数据
     * @param $key
     * @param $value
     */
    public function add($key, $value): void
    {
        $node = $this->getNode($key);
        if ($node == null) {
            $this->dummyHead->next = new Node($key, $value, $this->dummyHead->next);
            $this->size++;
        } else {
            $node->value = $value;
        }
    }

    /**
     * 判断 Map 是否包含 key
     * @param $key
     * @return bool
     */
    public function contains($key): bool
    {
        $node = $this->getNode($key);
        if ($node == null) {
            return false;
        }
        return true;
    }

    public function get($key)
    {
        $node = $this->getNode($key);
        return $node ?? null;
    }

    public function set($key, $value)
    {
        $node = $this->getNode($key);
        if ($node == null) {
            echo "不存在 key:" . $key;
            exit;
        }
        $node->value = $value;
    }

    public function remove($key)
    {
        $value = null;
        for ($node = $this->dummyHead; $node != null; $node = $node->next) {
            if ($node->next != null && $node->next->key == $key) {
                $reNode = $node->next->value;
                $node->next = $node->next->next;
                $this->size--;
                break;
            }
        }

        return $value;
    }

    /**
     * 遍历链表获取某个key=$key的节点
     * @param $key
     * @return |null
     */
    private function getNode($key)
    {
        for ($node = $this->dummyHead->next; $node != null; $node = $node->next) {
            if ($node->key == $key) {
                return $node;
            }
        }
        return null;
    }

    public function getSize(): int
    {

    }

}

/**
 * 映射节点定义
 * Class Node
 */
class Node
{
    public $key;
    public $value;
    public $next;

    public function __construct($key, $value, $next)
    {
        $this->key = $key;
        $this->value = $value;
        $this->next = $next;
    }
}
1.3 interface Map 接口

这里是 映射(Map) 一个实现接口,里面定义了一些函数,这样 LinkedListMap 继承它之后,必须重构里面的所有方法:

<?php


interface Map
{
    //添加 key-value 数据
    public function add($key, $value): void;

    public function contains($key): bool;

    public function get($key);
    //修改 key-value 数据
    public function set($key, $value);

    public function getSize(): int;
}
1.4 output_map.php 输出演示文件
<?php
require 'LinkedListMap.php';

$map = new LinkedListMap();
$map->add("name","秦诗贤");
$map->add("age",22);
$map->add("weight",65);
$map->remove("age");

print_r($map);

输入结果如下图:
在这里插入图片描述

2.基于二分搜索树的映射(Map)实现

2.1 节点定义
class Node
{
    public $key;
    public $value;
    public $left = null;
    public $right = null;

    public function __construct($key, $value)
    {
        $this->key = $key;
        $this->value = $value;
    }
}
2.2 BinarySearchTreeMap 类

这是一个基于二分搜索树实现的映射(Map)类,里面有 add($key,$value)方法向链表添加 key-value 键值对,添加使用的是递归思想,contains($key)方法判断映射(Map)中是否包含 $key 对应的 key-value 键值对,set($key, $value)方法可以更新 key-value 键值对中的 value值,remove($key)方法可以删除 key 等于 $key 对应的 key-value 键值对。

<?php
require 'Map.php';

class BinarySearchTreeMap implements Map
{
    public $root;
    public $size;

    public function __construct()
    {
        $this->root = null;
        $this->size = 0;
    }

    /**
     * 获取映射(Map)中某个key对应的value
     * @param $key
     * @return |null
     */
    public function get($key)
    {
        return $this->recursionGet($key, $this->root);
    }

    /**
     * 递归获取 key 对应的节点
     * @param $key
     * @param $root
     * @return |null
     */
    private function recursionGet($key, $root)
    {
        if ($root == null) {
            return null;
        } elseif ($key == $root->key) {
            return $root;
        } elseif ($key < $root->key) {
            return $this->recursionGet($key, $root->left);
        } else {
            return $this->recursionGet($key, $root->right);
        }
    }

    /**
     * 添加 key-value 数据
     * @param $key
     * @param $value
     */
    public function add($key, $value): void
    {
        $this->root = $this->recursionAdd($key, $value, $this->root);
    }

    /**
     * 递归添加数据
     * @param $key
     * @param $value
     * @param $root
     */
    private function recursionAdd($key, $value, $root)
    {
        if ($root == null) {
            $root = new Node($key, $value);
            $this->size++;
        } elseif ($key == $root->key) {
            $root->value = $value;
        } elseif ($key < $root->key) {
            $root->left = $this->recursionAdd($key, $value, $root->left);
        } else {
            $root->right = $this->recursionAdd($key, $value, $root->right);
        }
        return $root;
    }

    /**
     * 查看map是否包含某个key
     * @param $key
     * @return bool
     */
    public function contains($key): bool
    {
        $node = $this->recursionGet($key, $this->root);
        return $node != null;
    }


    /**
     * 递归查看map是否存在某个 key
     * @param $key
     * @param $root
     * @return bool
     */
    private function recursionContains($key, $root)
    {
        if ($root == null) {
            return false;
        } elseif ($key == $root->key) {
            return true;
        } elseif ($key < $root->key) {
            return $this->recursionContains($key, $root->left);
        } else {
            return $this->recursionContains($key, $root->right);
        }
    }

    /**
     * 修改 key 对应的 value
     * @param $key
     * @param $value
     */
    function set($key, $value)
    {
        $node = $this->recursionGet($key, $this->root);
        if ($node == null) {
            echo "不存在该节点";
            exit;
        }

        $node->value = $value;
    }

    /**
     * 获取映射 Map 中 key-value 数量
     * @return int
     */
    public function getSize(): int
    {
        return $this->size;
    }
}

class Node
{
    public $key;
    public $value;
    public $left = null;
    public $right = null;

    public function __construct($key, $value)
    {
        $this->key = $key;
        $this->value = $value;
    }
}

Tips:contains($key) 方法可以先调用 recursionGet($key) 递归获取 key 对应的节点,若不为 null,这返回 true,否则返回 false,set($key) 也可以复用 recursionGet($key) 现获取节点信息。

2.3 interface Map 接口

这里是 映射(Map) 一个实现接口,里面定义了一些函数,这样 LinkedListMap 继承它之后,必须重构里面的所有方法:

<?php


interface Map
{
    //添加 key-value 数据
    public function add($key, $value): void;

    public function contains($key): bool;

    public function get($key);
    //修改 key-value 数据
    public function set($key, $value);

    public function getSize(): int;
}
2.4 output_map.php 输出演示文件
<?php
require 'BinarySearchTreeMap.php';

$map = new BinarySearchTreeMap();
$map->add(45,"45value");
$map->add(30,"30value");
$map->add(55,"55value");
$map->add(25,"25value");
$map->add(35,"35value");
$map->add(50,"50value");
$map->add(65,"65value");
$map->set(65,6666);
print_r($map);

输出结果如下:

BinarySearchTreeMap Object
(
    [root] => Node Object
        (
            [key] => 45
            [value] => 45value
            [left] => Node Object
                (
                    [key] => 30
                    [value] => 30value
                    [left] => Node Object
                        (
                            [key] => 25
                            [value] => 25value
                            [left] =>
                            [right] =>
                        )

                    [right] => Node Object
                        (
                            [key] => 35
                            [value] => 35value
                            [left] =>
                            [right] =>
                        )

                )

            [right] => Node Object
                (
                    [key] => 55
                    [value] => 55value
                    [left] => Node Object
                        (
                            [key] => 50
                            [value] => 50value
                            [left] =>
                            [right] =>
                        )

                    [right] => Node Object
                        (
                            [key] => 65
                            [value] => 6666
                            [left] =>
                            [right] =>
                        )

                )

        )

    [size] => 7
)

代码仓库 :https://gitee.com/love-for-poetry/data-structure

扫码关注爱因诗贤
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值