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 相关文章推荐
mysql下创建字段并设置主键的php代码
May 16 PHP
PHP代码网站如何防范SQL注入漏洞攻击建议分享
Mar 01 PHP
PHP中使用break跳出多重循环代码实例
Jan 21 PHP
laravel安装zend opcache加速器教程
Mar 02 PHP
YiiFramework入门知识点总结(图文教程)
Dec 28 PHP
PHP5.5.15+Apache2.4.10+MySQL5.6.20配置方法分享
May 06 PHP
Centos PHP 扩展Xchche的安装教程
Jul 09 PHP
php可变长参数处理函数详解
Feb 22 PHP
详解PHP处理字符串类似indexof的方法函数
Jun 11 PHP
PHP递归实现汉诺塔问题的方法示例
Nov 25 PHP
PHP中的self关键字详解
Jun 23 PHP
PHP保存Base64图片base64_decode的问题整理
Nov 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中传统验证与thinkphp框架(必看篇)
2017/06/10 PHP
PHP实现二叉树深度优先遍历(前序、中序、后序)和广度优先遍历(层次)实例详解
2018/04/20 PHP
PHP的重载使用魔术方法代码实例详解
2021/02/26 PHP
jquery 常用操作方法
2010/01/28 Javascript
JavaScript的类型转换(字符转数字 数字转字符)
2010/08/30 Javascript
js Form.elements[i]的使用实例
2011/11/13 Javascript
关于extjs treepanel复选框选中父节点与子节点的问题
2013/04/02 Javascript
JavaScript中实现PHP的打乱数组函数shuffle实例
2014/10/11 Javascript
javascript获取文档坐标和视口坐标
2015/05/26 Javascript
Javascript之BOM(window对象)详解
2016/05/25 Javascript
Jquery获取第一个子元素简单实例
2016/06/02 Javascript
Boostrap栅格系统与自己额外定义的媒体查询的冲突问题
2017/02/19 Javascript
如何利用node转发请求详解
2020/09/17 Javascript
Python中的对象,方法,类,实例,函数用法分析
2015/01/15 Python
python引用DLL文件的方法
2015/05/11 Python
黑科技 Python脚本帮你找出微信上删除你好友的人
2016/01/07 Python
运行django项目指定IP和端口的方法
2018/05/14 Python
Python计算时间间隔(精确到微妙)的代码实例
2019/02/26 Python
Python递归函数 二分查找算法实现解析
2019/08/12 Python
PyQt+socket实现远程操作服务器的方法示例
2019/08/22 Python
python 如何对logging日志封装
2020/12/02 Python
意大利奢侈品多品牌集合店:TheDoubleF
2019/08/24 全球购物
网游商务专员求职信
2013/10/15 职场文书
教师队伍管理制度
2014/01/14 职场文书
大学生创业感言
2014/01/25 职场文书
节约能源标语
2014/06/17 职场文书
村创先争优活动总结
2014/08/28 职场文书
干部作风整顿自我剖析材料和整改措施
2014/09/18 职场文书
群众路线个人整改措施
2014/10/24 职场文书
群众路线教育实践活动学习笔记内容
2014/11/06 职场文书
大学生学年个人总结
2015/02/15 职场文书
财务个人年度总结范文
2015/02/26 职场文书
大学生自我评价范文
2015/03/03 职场文书
2015年端午节国旗下演讲稿
2015/03/19 职场文书
承诺书应该怎么写?
2019/09/10 职场文书
Django操作cookie的实现
2021/05/26 Python