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 相关文章推荐
一个php作的文本留言本的例子(五)
Oct 09 PHP
PHP常用代码
Nov 23 PHP
PHP函数spl_autoload_register()用法和__autoload()介绍
Feb 04 PHP
json的键名为数字时的调用方式(示例代码)
Nov 15 PHP
根据中文裁减字符串函数的php代码
Dec 03 PHP
PHP实现简单爬虫的方法
Jul 29 PHP
jQuery+Ajax+PHP“喜欢”评级功能实现代码
Oct 08 PHP
PHP如何通过传引用的思想实现无限分类(代码简单)
Oct 13 PHP
Yii2 GridView实现列表页直接修改数据的方法
May 16 PHP
laravel dingo API返回自定义错误信息的实例
Sep 29 PHP
laravel中的fillable和guarded属性详解
Oct 23 PHP
php的对象传值与引用传值代码实例讲解
Feb 26 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
在项目中寻找代码的坏命名
2012/07/14 PHP
深入探讨:Nginx 502 Bad Gateway错误的解决方法
2013/06/03 PHP
WordPress中缩略图的使用以及相关技巧
2015/11/24 PHP
Symfony2创建基于域名的路由相关示例
2016/11/14 PHP
php 与 nginx 的处理方式及nginx与php-fpm通信的两种方式
2018/09/28 PHP
yii2.0框架多模型操作示例【添加/修改/删除】
2020/04/13 PHP
TopList标签和JavaScript结合两例
2007/08/12 Javascript
jquery.ui.progressbar 中文文档
2009/11/26 Javascript
基于Jquery+Ajax+Json的高效分页实现代码
2011/10/29 Javascript
JavaScript实现在数组中查找不同顺序排列的字符串
2014/09/26 Javascript
javascript实现按回车键切换焦点
2015/02/09 Javascript
简介JavaScript中toUpperCase()方法的使用
2015/06/06 Javascript
js简单正则验证汉字英文及下划线的方法
2016/11/28 Javascript
详解webpack3编译兼容IE8的正确姿势
2017/12/21 Javascript
vue之将echart封装为组件
2018/06/02 Javascript
typescript配置alias的详细步骤
2020/08/12 Javascript
[05:31]干嘛呢兄弟!DOTA2 TI9语音轮盘部分出处
2019/05/14 DOTA
Python中列表、字典、元组、集合数据结构整理
2014/11/20 Python
Python 中PyQt5 点击主窗口弹出另一个窗口的实现方法
2019/07/04 Python
python groupby 函数 as_index详解
2019/12/16 Python
美国知名运动产品零售商:Foot Locker
2016/07/23 全球购物
阿玛尼意大利官网:Armani意大利
2018/10/30 全球购物
测绘工程专业个人自我评价
2013/12/01 职场文书
美容院考勤制度
2014/01/30 职场文书
团日活动策划书
2014/02/01 职场文书
运动会通讯稿500字
2014/02/20 职场文书
财务总监管理职责范文
2014/03/09 职场文书
2014年党员公开承诺书范文
2014/03/28 职场文书
离婚协议书包括哪些内容
2014/10/16 职场文书
2014年学生会主席工作总结
2014/11/07 职场文书
大三学生英语考试作弊检讨书
2015/01/01 职场文书
晚会开幕词范文
2016/03/04 职场文书
应届毕业生的自我评价
2019/06/21 职场文书
学校就业保障协议书
2019/06/24 职场文书
iPhone13将有八大升级
2021/04/15 数码科技
js前端面试常见浏览器缓存强缓存及协商缓存实例
2022/06/21 Javascript