映射

映射,或者射影,在数学及相关的领域经常等同于函数。基于此,部分映射就相当于部分函数,而完全映射相当于完全函数。

映射(Map)是用于存取键值对的数据结构(key,value),一个键只能对应一个值且键不能重复。

实现

映射的实现方式可以使用链表或二叉树实现。

链表实现:

<?php
/**
* 接口 字典
* Interface Dict
* @package app\models
*/
Interface Dict
{ public function set( $key , $value ); public function get( $key ); public function isExist( $key ); public function delete($key); public function getSize(); } class DictLinkList implements Dict
{
protected $size=0;
public $key;
public $value;
public $next; public function __construct($key=null,$value=null,$next=null)
{
$this->key = $key;
$this->value = $value;
$this->next = $next;
} public function set($key,$value){
$node = $this;
while( $node && $node->next ){
if( $node->next->key==$key ){
$node->next->value = $value;
return $node->next;
}
$node = $node->next;
} $node->next = new self($key,$value,$node->next);
$this->size++;
return $node->next;
} public function get($key){
$node = $this;
while($node){
if( $node->key ==$key ){
return $node->value;
}
$node = $node->next;
} throw new \Exception('cannot found key');
} public function isExist($key)
{
$node = $this;
while($node){
if( $node->key ==$key ){
return true;
}
$node = $node->next;
}
return false;
} public function delete($key)
{
if( $this->size==0)
throw new \Exception('key is not exist'); $node = $this;
while($node->next){
if( $node->next->key == $key ){
$node->next = $node->next->next;
$this->size--;
break;
}
$node = $node->next;
} return $this;
} public function getSize()
{
return $this->size;
}
}

测试:

<?php
$dict = new DictLinkList();
$dict->set('sun',111); //O(n)
$dict->set('sun',222);
$dict->set('w',111);
$dict->set('k',111);
var_dump($dict->get('w')); //O(n)
var_dump($dict->isExist('v')); //O(n)
var_dump($dict->delete('sun')); //O(n)
var_dump($dict->getSize()); /******************************************/
//111
//false
//true
//2

二叉树实现

<?php
class DictBtree implements Dict
{
public $key;
public $value; public $left;
public $right;
private $size; public function __construct($key=null,$value=null)
{
$this->key = $key;
$this->value = $value;
$this->left = null;
$this->right = null;
$this->size = 0;
} public function set( $key , $value ){
if( $this->size ==0 ){
$node = new static( $key,$value );
$this->key = $node->key;
$this->value = $node->value;
$this->size++;
}else{
$node = $this;
while($node){
if( $node->key == $key ){
$node->value = $value;
break;
}
if($node->key>$key){
if($node->left==null){
$node->left = new static( $key,$value );
$this->size++;
break;
}
$node = $node->left;
}else{
if($node->right==null){
$node->right = new static( $key,$value );
$this->size++;
break;
}
$node = $node->right;
}
}
} return $this;
} public function get( $key ){
if( $this->size ==0 )
throw new \Exception('empty');
$node = $this;
while($node) {
if ($node->key == $key) {
return $node->value;
}
if ($node->key > $key) {
$node = $node->left;
} else {
$node = $node->right;
}
}
throw new \Exception('this key not exist');
} public function isExist( $key ){
if( $this->size ==0 )
return false;
$node = $this;
while($node) {
if ($node->key == $key) {
return true;
}
if ($node->key > $key) {
$node = $node->left;
} else {
$node = $node->right;
}
}
return false;
} public function delete($key){ //找到元素,寻找元素左边最小元素
$node = $this->select($key);
if( $node->right!=null ){
$node1 = $node->selectMin($node->right); //替换当前node
$node->key = $node1->key;
$node->value = $node1->value; //删除$node->right最小元素,获取最终元素赋给$node->right
$nodeMin = $this->deleteMin($node->right);
$node->right = $nodeMin;
}else{
$node1 = $node->selectMax($node->left); $node->key = $node1->key;
$node->value = $node1->value; $nodeMax = $this->deleteMax($node->left);
$node->left = $nodeMax;
} return $this; } protected function deleteMin( $node ){
// if( $this->size ==0 )
// throw new \Exception('empty'); // $prev = new static();
// $prev->left = $node;
// while($prev->left->left!=null){
//
// $prev = $prev->left;
// }
// $prev->left = $prev->left->right; if( $node->left==null ){
$rightNode = $node->right;
$node->right = null;
$this->size--;
return $rightNode;
} $node->left = $this->deleteMin($node->left); return $node;
} protected function deleteMax($node){ if( $node->right==null ){
$leftNode = $node->left;
$node->left = null;
$this->size--;
return $leftNode;
} $node->right = $this->deleteMax($node->right);
return $node; } public function getSize(){
return $this->size;
} public function select($key){
$node = $this; while($node){
if($node->key==$key){
return $node;
}
if ($node->key > $key) {
$node = $node->left;
} else {
$node = $node->right;
}
} throw new \Exception('this key not exist');
} public function selectMin( $node ){
while($node->left){ $node = $node->left;
}
return $node;
} public function selectMax( $node ){
while($node->right){ $node = $node->right;
}
return $node;
}
}

复杂度分析

链表 O(n)

二分搜索树 O(log n)

php实现映射的更多相关文章

  1. Hibernatel框架关联映射

    Hibernatel框架关联映射 Hibernate程序执行流程: 1.集合映射 需求:网络购物时,用户购买商品,填写地址 每个用户会有不确定的地址数目,或者只有一个或者有很多.这个时候不能把每条地址 ...

  2. hibernate多对多关联映射

    关联是类(类的实例)之间的关系,表示有意义和值得关注的连接. 本系列将介绍Hibernate中主要的几种关联映射 Hibernate一对一主键单向关联Hibernate一对一主键双向关联Hiberna ...

  3. Dapper逆天入门~强类型,动态类型,多映射,多返回值,增删改查+存储过程+事物案例演示

    Dapper的牛逼就不扯蛋了,答应群友做个入门Demo的,现有园友需要,那么公开分享一下: 完整Demo:http://pan.baidu.com/s/1i3TcEzj 注 意 事 项:http:// ...

  4. ElasticSearch 5学习(9)——映射和分析(string类型废弃)

    在ElasticSearch中,存入文档的内容类似于传统数据每个字段一样,都会有一个指定的属性,为了能够把日期字段处理成日期,把数字字段处理成数字,把字符串字段处理成字符串值,Elasticsearc ...

  5. .NET平台开源项目速览(14)最快的对象映射组件Tiny Mapper

    好久没有写文章,工作甚忙,但每日还是关注.NET领域的开源项目.五一休息,放松了一下之后,今天就给大家介绍一个轻量级的对象映射工具Tiny Mapper:号称是.NET平台最快的对象映射组件.那就一起 ...

  6. ASP.NET Core的路由[1]:注册URL模式与HttpHandler的映射关系

    ASP.NET Core的路由是通过一个类型为RouterMiddleware的中间件来实现的.如果我们将最终处理HTTP请求的组件称为HttpHandler,那么RouterMiddleware中间 ...

  7. mybatis_映射查询

    一.一对一映射查询: 第一种方式(手动映射):借助resultType属性,定义专门的pojo类作为输出类型,其中该po类中封装了查询结果集中所有的字段.此方法较为简单,企业中使用普遍. <!- ...

  8. 问题记录:EntityFramework 一对一关系映射

    EntityFramework 一对一关系映射有很多种,比如主键作为关联,配置比较简单,示例代码: public class Teacher { public int Id { get; set; } ...

  9. 内存映射文件MemoryMappedFile使用

    参考资料: http://blog.csdn.net/bitfan/article/details/4438458 所谓内存映射文件,其实就是在内存中开辟出一块存放数据的专用区域,这区域往往与硬盘上特 ...

  10. MyBatis3:SQL映射

    前言 前面学习了config.xml,下面就要进入MyBatis的核心SQL映射了,第一篇文章的时候,student.xml里面是这么写的: <?xml version="1.0&qu ...

随机推荐

  1. 谈谈对Spring的理解

    转载自:  https://blog.csdn.net/qq_41701956/article/details/90453716 Spring 框架是 Java 应用最广的框架,它的成功来源于理念,而 ...

  2. 【TensorFlow官方文档】MNIST机器学习入门

    MNIST是一个入门级的计算机视觉数据集,它包含各种手写数字图片:它也包含每一张图片对应的标签,告诉我们这个是数字几.比如,下面这四张图片的标签分别是5,0,4,1. 从一个很简单的数学模型开始:训练 ...

  3. ubuntu之路——day11.3 不匹配数据划分的偏差和方差

    在11.2中,我们提到了一种数据划分的方法,那么怎么衡量这种数据划分方法中的误差呢? 来看一个例子:有20w条各种领域的语音识别数据,2w条汽车语音定位数据 train+dev+test,其中trai ...

  4. Flutter扫码识别二维码内容

    前面一篇写了生成二维码图片,这篇来写使用相机扫描识别二维码 识别二维码需要用到插件 barcode_scan 首先在 pubspec.yaml 文件中添加以下依赖,添加依赖后在 pubspec.yam ...

  5. PHP如何解决网站大流量与高并发的问题(三)

    七层负载均衡的实现 基于URL等应用层信息的负载均衡 Nginx的proxy是一个很强大的功能,实现了7层负载均衡 功能强大.性能卓越,运行稳定 配置简单灵活 能自动提出工作不正常的后端服务器 上传文 ...

  6. JavaScript data types and data structures

    JavaScript data types and data structures Programming languages all have built-in data structures, b ...

  7. Android.mk文件LOCAL_MODULE_TAGS 说明

    在移植wireless_tools驱动的时候发现居然没去编译咱的代码,奇怪,后来发现只有LOCAL_MODULE_TAGS 选项这个最有可疑,后来发现有这个说法 LOCAL_MODULE_TAGS : ...

  8. Qt Resource System Qt资源体系(qrc rcc)

    Qt资源体系采用平台独立机制来存储应用程序执行时的二进制文件.这种机制在应用程序需要一些确定的文件(图标.翻译文件等等)而且又不想冒丢失文件的风险时是有用的. 资源体系依赖于 qmake, rcc ( ...

  9. 前端通用下载文件方法(兼容IE)

    之前在网上看到一个博主写的前端通用的下载文件的方法,个人觉得很实用,所以mark一下,方便以后查阅 源文地址(源文还有上传/下载excel文件方法) 因为项目要求要兼容IE浏览器,所以完善了一下之前博 ...

  10. Nginx http -> https 跳转后 POST 丢失

    在 nginx.conf 配置文件中添加如下配置进行 http -> https 跳转 server { listen ; server_name example.org; https://$s ...