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正则走开
Mar 15 PHP
php 5.3.5安装memcache注意事项小结
Apr 12 PHP
ThinkPHP使用UTFWry地址库进行IP定位实例
Apr 01 PHP
php中Y2K38的漏洞解决方法实例分析
Sep 22 PHP
PHP中定义数组常量(array常量)的方法
Nov 17 PHP
PHP编写登录验证码功能 附调用方法
May 19 PHP
Yii基于CActiveForm的Ajax数据验证用法示例
Jul 14 PHP
PHP实现链式操作的原理详解
Sep 16 PHP
php生出随机字符串
Jul 06 PHP
php微信开发之图片回复功能
Jun 14 PHP
Laravel 5+ .env环境配置文件详解
Apr 06 PHP
PHP标准库 (SPL)――Countable用法示例
Jun 05 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实现字符串翻转的方法
2015/03/27 PHP
php过滤输入操作之htmlentities与htmlspecialchars用法分析
2017/02/17 PHP
php头像上传预览实例代码
2017/05/02 PHP
GreyBox技术总结(转)
2010/11/23 Javascript
HTML DOM的nodeType值介绍
2011/03/31 Javascript
js控制CSS样式属性语法对照表
2012/12/11 Javascript
js实现从数组里随机获取元素
2015/01/12 Javascript
基于js实现微信发送好友如何分享到朋友圈、微博
2015/11/30 Javascript
javascript针对不确定函数的执行方法
2015/12/16 Javascript
深入浅出ES6之let和const命令
2016/08/25 Javascript
JS高级运动实例分析
2016/12/20 Javascript
JS/jquery实现一个网页内同时调用多个倒计时的方法
2017/04/27 jQuery
原生JS实现获取及修改CSS样式的方法
2018/09/04 Javascript
基于js判断浏览器是否支持webGL
2020/04/18 Javascript
浅谈Python 集合(set)类型的操作——并交差
2016/06/30 Python
遗传算法之Python实现代码
2017/10/10 Python
python里使用正则表达式的组嵌套实例详解
2017/10/24 Python
Python unittest 简单实现参数化的方法
2018/11/30 Python
Python对excel文档的操作方法详解
2018/12/10 Python
pandas把所有大于0的数设置为1的方法
2019/01/26 Python
python2与python3爬虫中get与post对比解析
2019/09/18 Python
python:动态路由的Flask程序代码
2019/11/22 Python
使用TensorFlow搭建一个全连接神经网络教程
2020/02/06 Python
拿来就用!Python批量合并PDF的示例代码
2020/08/10 Python
详解HTML5中的元素与元素
2015/08/17 HTML / CSS
英国汽车和货车租赁网站:Hertz英国
2016/09/02 全球购物
一份软件工程师的面试试题
2016/02/01 面试题
教育实习生的自我评价分享
2013/11/21 职场文书
教师通用专业自荐书范文
2014/02/11 职场文书
十八届三中全会感言
2014/03/10 职场文书
诚信承诺书范文
2014/03/27 职场文书
学生保证书范文
2014/04/28 职场文书
社区志愿者活动方案
2014/08/18 职场文书
幼儿园小班见习报告
2014/10/31 职场文书
消防演习通知
2015/04/25 职场文书
运动会开幕式主持词
2015/07/01 职场文书