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 return语句的另一个作用
Jul 30 PHP
PHP实现通过中文字符比率来判断垃圾评论的方法
Oct 20 PHP
php中substr()函数参数说明及用法实例
Nov 15 PHP
php支持中文字符串分割的函数
May 28 PHP
Yii2隐藏frontend/web和backend/web的方法
Dec 12 PHP
Symfony2之session与cookie用法小结
Mar 18 PHP
mysql查找删除重复数据并只保留一条实例详解
Sep 24 PHP
php安装php_rar扩展实现rar文件读取和解压的方法
Nov 17 PHP
详解PHP数据压缩、加解密(pack, unpack)
Dec 17 PHP
yii2实现分页,带搜索的分页功能示例
Jan 07 PHP
php+redis消息队列实现抢购功能
Feb 08 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中全局变量global的使用演示代码
2011/05/18 PHP
PHP实现微信小程序人脸识别刷脸登录功能
2018/05/24 PHP
Centos7安装swoole扩展操作示例
2020/03/26 PHP
用js获取电脑信息(是使用与IE浏览器)
2013/01/15 Javascript
Jquery Uploadify多文件上传带进度条且传递自己的参数
2013/08/28 Javascript
javascript中的__defineGetter__和__defineSetter__介绍
2014/08/15 Javascript
JS+CSS实现仿新浪微博搜索框的方法
2015/02/24 Javascript
基于Jquery实现表单验证
2020/07/20 Javascript
js闭包引起的事件注册问题介绍
2016/03/29 Javascript
JavaScript字符集编码与解码详谈
2017/02/02 Javascript
详谈js模块化规范
2017/07/07 Javascript
vue如何判断dom的class
2018/04/26 Javascript
Typescript3.9 常用新特性一览(推荐)
2020/05/14 Javascript
haskell实现多线程服务器实例代码
2013/11/26 Python
Python Tkinter GUI编程入门介绍
2015/03/10 Python
python使用range函数计算一组数和的方法
2015/05/07 Python
python 统计代码行数简单实例
2017/05/04 Python
Python面向对象基础入门之设置对象属性
2018/12/11 Python
Python编程中flask的简介与简单使用
2018/12/28 Python
Python并发:多线程与多进程的详解
2019/01/24 Python
Python应用实现双指数函数及拟合代码实例
2020/06/19 Python
Python中Selenium库使用教程详解
2020/07/23 Python
新闻记者实习自我鉴定
2013/09/19 职场文书
大学三年的自我评价
2013/12/25 职场文书
养殖人员的创业计划书范文
2013/12/26 职场文书
自我评价的写作规则
2014/01/06 职场文书
给民警的表扬信
2014/01/08 职场文书
项目考察欢迎辞
2014/01/17 职场文书
授权委托书
2014/07/31 职场文书
民事授权委托书范文
2014/08/02 职场文书
社区党员志愿服务活动方案
2014/08/18 职场文书
银行开户授权委托书格式
2014/10/10 职场文书
大学生读书笔记范文
2015/07/01 职场文书
导游词之介休绵山
2019/12/31 职场文书
Java中CyclicBarrier和CountDownLatch的用法与区别
2021/08/23 Java/Android
Python中Schedule模块使用详解 周期任务神器
2022/04/19 Python