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 操作excel文件的方法小结
Dec 31 PHP
php代码收集表单内容并写入文件的代码
Jan 29 PHP
php excel reader读取excel内容存入数据库实现代码
Dec 06 PHP
zend framework框架中url大小写问题解决方法
Aug 19 PHP
php解析json数据实例
Aug 19 PHP
PHP自定义函数实现格式化秒的方法
Sep 14 PHP
php获得文件夹下所有文件的递归算法的简单实例
Nov 01 PHP
PHP解耦的三重境界(浅谈服务容器)
Mar 13 PHP
PHP 布尔值的自增与自减的实现方法
May 03 PHP
微信推送功能实现方式图文详解
Jul 12 PHP
php快速导入大量数据的实例方法
Sep 23 PHP
PHP实现新型冠状病毒疫情实时图的实例
Feb 04 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 中的一些经验积累
2006/10/09 PHP
用PHP实现小型站点广告管理(修正版)
2006/10/09 PHP
php中smarty变量修饰用法实例分析
2015/06/11 PHP
使用PHP编写发红包程序
2015/07/22 PHP
PHP实现简单实用的验证码类
2015/07/29 PHP
初识通用数据库操作类――前端easyui-datagrid,form(php)
2015/07/31 PHP
Yii基于数组和对象的Model查询技巧实例详解
2015/12/28 PHP
PHP大文件分割分片上传实现代码
2020/12/09 PHP
为javascript添加String.Format方法
2020/08/11 Javascript
js中定义一个变量并判断其是否为空的方法
2014/05/13 Javascript
JS实现向表格中动态添加行的方法
2015/03/30 Javascript
JS实现仿微博可关闭弹出层效果
2015/09/21 Javascript
JS实现按比例缩放图片的方法(附C#版代码)
2015/12/08 Javascript
JavaScript实现弹出DIV层同时页面背景渐变成半透明效果
2016/03/25 Javascript
JS代码防止SQL注入的方法(超简单)
2016/04/12 Javascript
ReactNative页面跳转实例代码
2016/09/27 Javascript
jquery动态创建div与input的实例代码
2016/10/12 Javascript
Vue.js+Layer表格数据绑定与实现更新的实例
2018/03/07 Javascript
小程序组件之仿微信通讯录的实现代码
2018/09/12 Javascript
Vue实现导航栏菜单
2020/08/19 Javascript
如何搭建一个完整的Vue3.0+ts的项目步骤
2020/10/18 Javascript
用TensorFlow实现戴明回归算法的示例
2018/05/02 Python
Django 开发环境与生产环境的区分详解
2019/07/26 Python
Python使用selenium + headless chrome获取网页内容的方法示例
2019/10/16 Python
python 五子棋如何获得鼠标点击坐标
2019/11/04 Python
TENSORFLOW变量作用域(VARIABLE SCOPE)
2020/01/10 Python
Python3如何判断三角形的类型
2020/04/12 Python
使用matplotlib动态刷新指定曲线实例
2020/04/23 Python
Python中常见的数制转换有哪些
2020/05/27 Python
python编写一个会算账的脚本的示例代码
2020/06/02 Python
使用keras内置的模型进行图片预测实例
2020/06/17 Python
波兰在线香水店:Perfumy.pl
2019/08/12 全球购物
超市理货员岗位职责
2014/07/04 职场文书
2014年班务工作总结
2014/12/02 职场文书
昆虫记读书笔记
2015/06/26 职场文书
mysql字符串截取函数小结
2021/04/05 MySQL