首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PHP SkipList put方法总是返回null

PHP SkipList put方法总是返回null
EN

Stack Overflow用户
提问于 2015-12-26 11:26:14
回答 1查看 79关注 0票数 2

我正在尝试使用http://www.mathcs.emory.edu/~cheung/Courses/323/Syllabus/Map/skip-list-impl.html中的伪代码在PHP中实现一个跳过列表。我设法让它在java中工作得很好,但在PHP中却不行。我的put方法总是返回null,因此,get方法也返回null。

我不太明白我哪里出错了,所以我非常感谢任何人的帮助!

代码语言:javascript
复制
<?php
interface SkipListEntry {
public function getPrev(); 
public function getNext(); 
public function getAbove(); 
public function getBelow(); 

public function getKey();
public function getValue();    
public function setValue($v);

public function setPrev($v);
public function setNext($v);
public function setAbove($v);
public function setBelow($v);

public function hasPrev();
public function hasNext();
public function hasAbove();
public function hasBelow();
}

class SkipListNode implements SkipListEntry {
  private $prev;
  private $next;
  private $above;
  private $below;

  private $key;
  private $value;

  public static $posInf = "+oo";
  public static $negInf = "-oo"; 

  function __construct($a, $b) {
$this->key = $a;
$this->value = $b;
  }

  public function getPrev(){
return $this->prev;
  }
  public function getNext(){
return $this->next;
  }
  public function getAbove(){
return $this->above;
  }
  public function getBelow(){
return $this->below;
  }

  public function getKey(){
return $this->key;
  }
  public function getValue(){
return $this->value;
  }

  public function setValue($n){
$this->value = $n;
  }

  public function setPrev($n) {
$this->prev = $n;
  }
  public function setNext($n) {
$this->next = $n;
  }
  public function setAbove($n) {
$this->above = $n;
  }
  public function setBelow($n) {
$this->below = $n;
  }

  public function hasPrev(){
return !is_null($this->prev);
  }

  public function hasNext(){
return !is_null($this->next);
  }

  public function hasAbove(){
return !is_null($this->above);
  }

  public function hasBelow(){
return !is_null($this->below);
  }  
}

class SkipList{
  private $topLeft;
  private $topRight;

  private $height = 0;
  private $totalEntries = 0;

  private $head;

  function __construct(){  
  $this->topLeft = new SkipListNode(SkipListNode::$negInf, null);
  $this->topRight = new SkipListNode(SkipListNode::$posInf, null);

  $this->topLeft->setNext($this->topRight);    
  $this->topRight->setPrev($this->topLeft);     

  $this->head = $this->topLeft;   
  }

  public function size() {
return $this->totalEntries;
  }

  public function isEmpty(){
return $this->totalEntries == 0;
  }  

  public function search($key){
$p = $this->head; 
while (true) {
  while (!$p->getNext()->getKey() == SkipListNode::$posInf
    && strcmp($p->getNext()->getKey(), $key) <= 0) {
      $p = $p->getNext();
    }
    if ($p->hasBelow()){
      $p = $p->getBelow();
    }
    else {
      break;
    }      
}
return $p;
  }

  public function put($key, $value){ 
$searchElement = $this->search($key);  
if ($key == $searchElement->getKey()){
  $oldValue = $searchElement->getValue();
  $searchElement->setValue($value);
  return $oldValue;
}
$newEntry = new SkipListNode($key, $value);
$newEntry->setPrev($searchElement);
$newEntry->setNext($searchElement->getNext());


$searchElement->getNext()->setPrev($newEntry);
$searchElement->setNext($newEntry);

$currentHeight = 0;
for ($j = 1; $j <= $this->coinFlip(); $j ++){
  if ($currentHeight >= $this->height){
    $this->createAdditionalLayer();
  }
  while (is_null($searchElement->getAbove())){
    $searchElement = $searchElement->getprev();
  }
  $searchElement = $searchElement->getAbove();

  $aboveElement = new SkipListNode($key, null);
  $aboveElement->setPrev($searchElement);
  $aboveElement->setNext($searchElement->getNext());
  $aboveElement->setBelow($newEntry);

  $searchElement->getNext()->setPrev($aboveElement);
  $searchElement->setNext($aboveElement);
  $newEntry->setAbove($aboveElement);
  $newEntry = $aboveElement;
  $currentHeight ++;
}
$this->totalEntries ++;
return null;
  }

  public function get($key){
$p = $this->search($key); 
if ($p->getKey() == $key){
  return $p->getValue();
}
return null;
  }

  private function createAdditionalLayer(){  
  $newtopLeft = new SkipListNode(SkipListNode::$negInf, null);
  $newtopRight = new SkipListNode(SkipListNode::$posInf, null);

  $newtopLeft->setNext($newtopRight);
  $newtopLeft->setBelow($this->head);
  $newtopRight->setPrev($newtopLeft);
  $this->head->setAbove($newtopLeft);
  $this->head = $newtopLeft;
  $this->height ++;
  }

  private function coinFlip(){
$total = 0;
$current = -1;

while ($current != 1){
  $current = rand(0,1);
  $total ++;
}
return $total;
  }
}

// test

$a = new SkipList();
var_dump($a->put("a", "b")); 
var_dump($a->put("a", "c")); // should return c (returns null) 
var_dump($a->size()); // should return 1 (returns 2)
var_dump($a->get("a")); // should return c, (returns null)

谢谢!

EN

回答 1

Stack Overflow用户

发布于 2015-12-26 13:12:23

我在搜索函数中发现了一些问题:

请使用此代码更改您的代码,然后尝试:

代码语言:javascript
复制
public function search($key){
        $p = $this->head;
        while (true) {


            while ($p->getNext()->getKey() != SkipListNode::$posInf
                    && strcmp($p->getNext()->getKey(), $key) == 0) {
                        $p = $p->getNext();
                    }
                    if ($p->hasBelow()){
                        $p = $p->getBelow();
                    }
                    else {
                        break;
                    }
        }
        return $p;
    }

结果是:

代码语言:javascript
复制
var_dump($a->put("a", "b")); 
var_dump($a->put("a", "c")); string 'b',
var_dump($a->size()); int 1,
var_dump($a->get("a")); string 'c'
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34468242

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档