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 相关文章推荐
GD输出汉字的函数的分析
Oct 09 PHP
关于svn冲突的解决方法
Jun 21 PHP
如何利用PHP执行.SQL文件
Jul 05 PHP
Drupal读取Excel并导入数据库实例
Mar 02 PHP
php学习笔记之基础知识
Nov 08 PHP
PHP的Socket通信之UDP通信实例
Jul 02 PHP
android上传图片到PHP的过程详解
Aug 03 PHP
WordPress中访客登陆实现邮件提醒的PHP脚本实例分享
Dec 14 PHP
php简单统计在线人数的方法
May 10 PHP
thinkPHP多语言切换设置方法详解
Nov 11 PHP
PHP实现的mysql读写分离操作示例
May 22 PHP
php5.5使用PHPMailer-5.2发送邮件的完整步骤
Oct 14 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 数据库树的遍历方法
2009/02/06 PHP
php 来访国内外IP判断代码并实现页面跳转
2009/12/18 PHP
php对图像的各种处理函数代码小结
2013/07/08 PHP
php curl_init函数用法
2014/01/31 PHP
PHP搭建大文件切割分块上传功能示例
2017/01/04 PHP
php及codeigniter使用session-cookie的方法(详解)
2017/04/06 PHP
php实现获取近几日、月时间示例
2019/07/06 PHP
laravel框架使用FormRequest进行表单验证,验证异常返回JSON操作示例
2020/02/18 PHP
Javascript 判断客户端浏览器类型代码
2010/03/01 Javascript
JS返回iframe中frameBorder属性值的方法
2015/04/01 Javascript
浅析Node.js:DNS模块的使用
2016/11/23 Javascript
概述如何实现一个简单的浏览器端js模块加载器
2016/12/07 Javascript
nodejs接入阿里大鱼短信验证码的方法
2017/07/10 NodeJs
layer弹出层 iframe层去掉滚动条的实例代码
2018/08/17 Javascript
基于Vue和Element-Ui搭建项目的方法
2019/09/06 Javascript
原生js实现随机点名功能
2019/11/05 Javascript
Python中的pprint折腾记
2015/01/21 Python
Python中如何优雅的合并两个字典(dict)方法示例
2017/08/09 Python
对Python中DataFrame按照行遍历的方法
2018/04/08 Python
PyQt5 对图片进行缩放的实例
2019/06/18 Python
在交互式环境中执行Python程序过程详解
2019/07/12 Python
python实现美团订单推送到测试环境,提供便利操作示例
2019/08/09 Python
详解Python绘图Turtle库
2019/10/12 Python
python 视频逐帧保存为图片的完整实例
2019/12/10 Python
django API 中接口的互相调用实例
2020/04/01 Python
Pygame框架实现飞机大战
2020/08/07 Python
HTML5 在canvas中绘制矩形附效果图
2014/06/23 HTML / CSS
澳大利亚波西米亚风情网上商店:Czarina
2019/03/18 全球购物
网络工程系信息安全技术专业大学生求职信
2013/10/22 职场文书
跳蚤市场口号
2014/06/13 职场文书
乡镇爱国卫生月活动总结
2014/06/25 职场文书
风雨哈佛路观后感
2015/06/03 职场文书
沂蒙六姐妹观后感
2015/06/08 职场文书
红与黑读书笔记
2015/06/29 职场文书
pytorch锁死在dataloader(训练时卡死)
2021/05/28 Python
Vue OpenLayer测距功能的实现
2022/04/20 Vue.js