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 相关文章推荐
Smarty安装配置方法
Apr 10 PHP
php print EOF实现方法
May 21 PHP
dhtmlxTree目录树增加右键菜单以及拖拽排序的实现方法
Apr 26 PHP
解析php中的fopen()函数用打开文件模式说明
Jun 20 PHP
解析PHP获取当前网址及域名的实现代码
Jun 23 PHP
如何使用PHP获取指定日期所在月的开始日期与结束日期
Aug 01 PHP
PHP利用MySQL保存session的实现思路及示例代码
Sep 09 PHP
PHP中使用BigMap实例
Mar 30 PHP
php用户注册信息验证正则表达式
Nov 12 PHP
php微信开发自定义菜单
Aug 27 PHP
使用laravel的migrate创建数据表的方法
Sep 30 PHP
php 下 html5 XHR2 + FormData + File API 上传文件操作实例分析
Feb 28 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
Gregarius中文日期格式问题解决办法
2008/04/22 PHP
MySQL时间字段究竟使用INT还是DateTime的说明
2012/02/27 PHP
单点登录 Ucenter示例分析
2013/10/29 PHP
CentOS安装php v8js教程
2015/02/26 PHP
浅谈PHP拦截器之__set()与__get()的理解与使用方法
2016/10/18 PHP
Ext面向对象开发实践(续)
2008/11/18 Javascript
WordPress JQuery处理沙发头像
2009/06/22 Javascript
a标签click和href执行顺序探讨
2014/06/23 Javascript
jQuery知识点整理
2015/01/30 Javascript
jQuery实现列表内容的动态载入特效
2015/08/08 Javascript
JS组件Bootstrap Table表格行拖拽效果实现代码
2020/08/27 Javascript
由简入繁实现Jquery树状结构的方法(推荐)
2016/06/10 Javascript
js生成随机数(指定范围)的实例代码
2016/07/10 Javascript
js注入 黑客之路必备!
2016/09/14 Javascript
Vue发布项目实例讲解
2019/07/17 Javascript
Vue CLI4 Vue.config.js标准配置(最全注释)
2020/06/05 Javascript
vue 路由缓存 路由嵌套 路由守卫 监听物理返回操作
2020/08/06 Javascript
[00:32]2018DOTA2亚洲邀请赛OpTic出场
2018/04/03 DOTA
用Python代码来绘制彭罗斯点阵的教程
2015/04/03 Python
收藏整理的一些Python常用方法和技巧
2015/05/18 Python
深入源码解析Python中的对象与类型
2015/12/11 Python
Python的Django REST框架中的序列化及请求和返回
2016/04/11 Python
遍历python字典几种方法总结(推荐)
2016/09/11 Python
用Python shell简化开发
2018/08/08 Python
pandas 转换成行列表进行读取与Nan处理的方法
2018/10/30 Python
对python中词典的values值的修改或新增KEY详解
2019/01/20 Python
对python生成业务报表的实例详解
2019/02/03 Python
html5 input元素新特性_动力节点Java学院整理
2017/07/06 HTML / CSS
新浪网技术部笔试题
2016/08/26 面试题
面向对象编程OOP的优点
2013/01/22 面试题
别名指示符是什么
2012/10/08 面试题
毕业生物理教师求职信
2013/10/17 职场文书
校园十大歌手策划书
2014/02/01 职场文书
致运动员加油稿
2015/07/21 职场文书
导游词之阳朔遇龙河
2019/12/16 职场文书
python中的3种定义类方法
2021/11/27 Python