这篇文章主要介绍如何实现 映射(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);

输入结果如下图:

java使用for循环插入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