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 相关文章推荐
ThinkPHP 防止表单重复提交的方法
Aug 08 PHP
PHP连接局域网MYSQL数据库的简单实例
Aug 26 PHP
destoon二次开发常用数据库操作
Jun 21 PHP
thinkphp中html:list标签传递多个参数实例
Oct 30 PHP
php实现的SESSION类
Dec 02 PHP
通过PHP自带的服务器来查看正则匹配结果的方法
Dec 24 PHP
Symfony2学习笔记之系统路由详解
Mar 17 PHP
PHP发送AT指令实例代码
May 26 PHP
Laravel 5.3 学习笔记之 安装
Aug 28 PHP
PHP的反射机制实例详解
Mar 29 PHP
PHP从零开始打造自己的MVC框架之类的自动加载实现方法详解
Jun 03 PHP
Yii框架小部件(Widgets)用法实例详解
May 15 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操作XML作为数据库的类
2010/12/19 PHP
浅析php中常量,变量的作用域和生存周期
2013/08/10 PHP
一个PHP二维数组排序的函数分享
2014/01/17 PHP
ThinkPHP框架搭建及常见问题(XAMPP安装失败、Apache/MySQL启动失败)
2016/04/15 PHP
PHP互换两个变量值的方法(不用第三变量)
2016/11/14 PHP
PHP中字符串长度的截取用法示例
2017/01/12 PHP
购物车实现的几种方式优缺点对比
2018/05/02 PHP
基于javascript html5实现多文件上传
2016/03/03 Javascript
JavaScript实现垂直滚动条效果
2017/01/18 Javascript
JS验证全角与半角及相互转化的介绍
2017/05/18 Javascript
vue-quill-editor富文本编辑器简单使用方法
2018/09/21 Javascript
实例讲解v-if和v-show的区别
2019/01/31 Javascript
JavaScript中的各种宽高属性的实现
2020/05/08 Javascript
Python中每次处理一个字符的5种方法
2015/05/21 Python
微信跳一跳python辅助脚本(总结)
2018/01/11 Python
Python线程创建和终止实例代码
2018/01/20 Python
Tensorflow实现AlexNet卷积神经网络及运算时间评测
2018/05/24 Python
python 使用re.search()筛选后 选取部分结果的方法
2018/11/28 Python
python之拟合的实现
2019/07/19 Python
Python通过cv2读取多个USB摄像头
2019/08/28 Python
python如何安装下载后的模块
2020/07/03 Python
Python 高效编程技巧分享
2020/09/10 Python
用python查找统一局域网下ip对应的mac地址
2021/01/13 Python
一文读懂python Scrapy爬虫框架
2021/02/24 Python
什么是接口(Interface)?
2013/02/01 面试题
学生爱国演讲稿
2014/01/14 职场文书
党员干部廉洁承诺书
2014/05/28 职场文书
六查六看六改心得体会
2014/10/14 职场文书
党员年终个人总结
2015/02/14 职场文书
中学生自我评价2015
2015/03/03 职场文书
战友聚会致辞
2015/07/28 职场文书
家属联谊会致辞
2015/07/31 职场文书
2016年学校党支部公开承诺书
2016/03/25 职场文书
比较几种Redis集群方案
2021/06/21 Redis
搞笑Gif:这么白这么长的腿像极了一楼的女朋友
2022/03/21 杂记
Mac电脑OS系统下安装Nginx的详细教程
2022/04/14 Servers