映射

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

映射(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. 史上最全java pdf精品书籍整理

    算法,多线程,spring,数据库,大数据,面试题等等.喜欢的小伙伴加群获取 QQ群号825199617 (非广告培训技术群,纯java知识交流,请自重)

  2. tecplot三维模型绘制二维切片流线

    原视频下载地址链接: https://pan.baidu.com/s/1csugHK 密码: xrni

  3. Qualcomm Audio HAL 音频通路设置【转】

    本文转载自:https://blog.csdn.net/azloong/article/details/79383323 1. 音频框图概述| Front End PCMs | SoC DSP | B ...

  4. 自定义alert弹框,title不显示域名(重写alert)

    问题: 系统默认的alert弹框的title会默认显示网页域名 解决办法: (修改弹框样式) (function() { window.alert = function(name) { $(" ...

  5. Wamp 本地访问特别慢,原因在这

      Wamp 本地访问特别慢.打开空的页面都要400ms,彻底疯了     什么localhost改为127.0.0.1 什么 清理日志缓存,都不好使, 重点在Xdebug,安装了Xdebug之后变慢 ...

  6. idea 如何新建一个Maven项目并且写第一个servlet

    使用idea已经有段时间了,但是一直没有自己亲自新建一个项目,从头开始写一个Servlet,今天就来学习一下,并且记一个笔记. 一. 1.首先,打开idea new-->Project 2.选择 ...

  7. ntpd服务

    yum -y install ntp 服务器端 [root@ip-172-31-6-148~]# vim /etc/ntp.conf ...# Use public servers from thep ...

  8. Springmvc & Report: FineReport vs BIRT vs Jasperreport

    Springmvc与jasperreport结合生成报表的一种方法 - OneThin的个人空间 - OSCHINAhttps://my.oschina.net/onethin/blog/14360 ...

  9. Windows系统CPU和内存状态实时查询(Java)

    一.背景 需要查询Windows服务器的CPU和内存状态. Linux系统查询CPU和内存状态很简单,一个top命令搞定,Windows就稍微麻烦一些了. 经过资料查找,发现jdk目前不能直接查询系统 ...

  10. Docs-.NET-C#-指南-语言参考-关键字-值类型:char

    ylbtech-Docs-.NET-C#-指南-语言参考-关键字-值类型:char 1.返回顶部 1. char(C# 参考) 2019/10/22 char 类型关键字是 .NET System.C ...