php实现映射操作实例详解


Posted in PHP onOctober 02, 2019

本文实例讲述了php实现映射操作。分享给大家供大家参考,具体如下:

映射

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

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

实现

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

php实现映射操作实例详解

链表实现:

<?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程序设计有所帮助。

PHP 相关文章推荐
搜索引擎技术核心揭密
Oct 09 PHP
PHP中$_FILES的使用方法及注意事项说明
Feb 14 PHP
从零开始学YII2框架(二)通过 Composer 安装扩展插件
Aug 20 PHP
php中使用PHPExcel读写excel(xls)文件的方法
Sep 15 PHP
PHP调用Linux命令权限不足问题解决方法
Feb 07 PHP
PHP常用处理静态操作类
Apr 03 PHP
php备份数据库类分享
Apr 14 PHP
PHP获取当前日期和时间及格式化方法参数
May 11 PHP
详解PHP中foreach的用法和实例
Oct 25 PHP
浅析PHP类的反射来实现依赖注入过程
Feb 06 PHP
php将从数据库中获得的数据转换成json格式并输出的方法
Aug 21 PHP
PHP防止sql注入小技巧之sql预处理原理与实现方法分析
Dec 13 PHP
PHP-FPM 设置多pool及配置文件重写操作示例
Oct 02 #PHP
php实现大文件断点续传下载实例代码
Oct 01 #PHP
使用composer安装使用thinkphp6.0框架问题【视频教程】
Oct 01 #PHP
基于Laravel-admin 后台的自定义页面用法详解
Sep 30 #PHP
Laravel-admin之修改操作日志的方法
Sep 30 #PHP
laravel 字段格式化 modle 字段类型转换方法
Sep 30 #PHP
laravel-admin解决表单select联动时,编辑默认没选上的问题
Sep 30 #PHP
You might like
聊天室php&amp;mysql(二)
2006/10/09 PHP
PHP文件打开、关闭、写入的判断与执行代码
2011/05/24 PHP
PHP Directory 函数的详解
2013/03/07 PHP
php实现mysql数据库操作类分享
2014/02/14 PHP
ThinkPHP中的关联模型注意点
2014/06/16 PHP
php版微信公众号自定义分享内容实现方法
2016/09/22 PHP
js 判断一个元素是否在页面中存在
2012/12/27 Javascript
javascript跨域的4种方法和原理详解
2014/04/08 Javascript
通过JQuery将DIV的滚动条滚动到指定的位置方便自动定位
2014/05/05 Javascript
jQuery中data()方法用法实例
2014/12/27 Javascript
JavaScrip调试技巧之断点调试
2015/10/22 Javascript
javascript常用经典算法实例详解
2015/11/25 Javascript
js简单判断移动端系统的方法
2016/02/25 Javascript
前端弹出对话框 js实现ajax交互
2016/09/09 Javascript
JavaScript与java语言有什么不同
2016/09/22 Javascript
Vue.js常用指令汇总(v-if、v-for等)
2016/11/03 Javascript
Vue精简版风格概述
2018/01/30 Javascript
JS实现select选中option触发事件操作示例
2018/07/13 Javascript
Vue.js中使用iView日期选择器并设置开始时间结束时间校验功能
2018/08/12 Javascript
vue视图不更新情况详解
2019/05/16 Javascript
vue 实现用户登录方式的切换功能
2020/04/14 Javascript
[43:58]DOTA2上海特级锦标赛C组败者赛 Newbee VS Archon第二局
2016/02/27 DOTA
[02:21]2018完美盛典章节片——初心
2018/12/17 DOTA
opencv resize图片为正方形尺寸的实现方法
2019/12/26 Python
html5使用canvas实现图片下载功能的示例代码
2017/08/26 HTML / CSS
英国知名的皮手套品牌:Dents
2016/11/13 全球购物
俄罗斯的精英皮具:Wittchen
2018/01/29 全球购物
西班牙电子产品购物网站:Electronicamente
2018/07/26 全球购物
考试不及格检讨书
2014/01/09 职场文书
大学生违纪检讨书300字
2014/10/25 职场文书
小学教育见习总结
2015/06/23 职场文书
环境卫生整治简报
2015/07/20 职场文书
学校远程教育工作总结
2015/08/11 职场文书
Java如何实现树的同构?
2021/06/22 Java/Android
Python接口自动化之文件上传/下载接口详解
2022/04/05 Python
Java获取字符串编码格式实现思路
2022/09/23 Java/Android