简易跳跃表 - php代码

栏目: PHP · 发布时间: 5年前

php代码 /** * 数据链表节点 * / class skipListNode { public $d = null; public $mem = null; public $pre = null; public $level = 0; public $levelNode = array(); } /** * 层链表节点 * / class skipListLevelNode { public $node = null; public $next = null; public $cur_level = 0; public $next_step = 0; } /** * 跳跃表 */ class skipList { private $max_level = 1; private $head = null; private $hash_table = array(); public function __construct($max_level = 10) { $this->max_level = (int)$max_level; $skipListNode = new skipListNode(); $skipListNode->level = $max_level; for ($i=0; $i < $this->max_level; $i++) { $skipListLevelNode = new skipListLevelNode(); $skipListLevelNode->cur_level = $i; $skipListLevelNode->node = $skipListNode; $skipListNode->levelNode[] = $skipListLevelNode; } $this->head = $skipListNode; } public function add(string $mem, $d) { $mem = strval($mem); $d = floatval($d); if (!$this->update($mem, $d)) { # 新加 $listNode = $this->getNodePos($d); $nextNode = isset($listNode->levelNode[0]->next) ? $listNode->levelNode[0]->next->node : null; $skipListNode = new skipListNode(); $skipListNode->pre = $listNode; $skipListNode->mem = $mem; $skipListNode->d = $d; $skipListNode->level = $this->node_level(); if ($nextNode) $nextNode->pre = $skipListNode; $pre_next_step = $next_step = 1; for ($i=0; $i < $this->max_level; $i++) { while ($i >= $listNode->level && $listNode->pre!==null) { $listNode = $listNode->pre; $pre_next_step++; } if (empty($listNode)) { break; } if (!empty($nextNode) && $i >= $nextNode->level) { $nextNode = isset($nextNode->levelNode[0]->next) ? $nextNode->levelNode[0]->next->node : null; if ($nextNode) $next_step++; } if ($i < $skipListNode->level) { $skipListLevelNode = new skipListLevelNode(); $skipListLevelNode->node = $skipListNode; $skipListLevelNode->cur_level = $i; $skipListLevelNode->next = null; $skipListLevelNode->next_step = $next_step; if ($nextNode && isset($nextNode->levelNode[$i]) && !empty($nextNode->levelNode[$i])) { $skipListLevelNode->next = $nextNode->levelNode[$i]; } $skipListNode->levelNode[] = $skipListLevelNode; $listNode->levelNode[$i]->next = $skipListLevelNode; $listNode->levelNode[$i]->next_step = $pre_next_step; }else{ $listNode->levelNode[$i]->next_step++ ; } } $this->hash_table[$mem] = $skipListNode; } return true; } public function update(string $mem, $d) { $mem = strval($mem); $d = floatval($d); $node = $this->getNodePosByMem($mem); if ($node) { if ($node->d === $d) { return true; } if ($this->del($mem)) { $this->add($mem, $d); return true; } return false; } return false; } public function del(string $mem) { $mem = strval($mem); $node = $this->getNodePosByMem($mem); if ($node) { $preNode = $node->pre; if (isset($node->levelNode[0]->next->node)) { $node->levelNode[0]->next->node->pre = $preNode; } for ($i=0; $i < $this->max_level; $i++) { while($i >= $preNode->level && $preNode->pre!==null) { $preNode = $preNode->pre; } if ($preNode->levelNode[$i]->next === null) { continue; } if ($i < $node->level) { $preNode->levelNode[$i]->next = $node->levelNode[$i]->next; $preNode->levelNode[$i]->next_step += $node->levelNode[$i]->next_step; $node->levelNode[$i] = null; } $preNode->levelNode[$i]->next_step--; } $node = null; $this->delNodePosByMem($mem); return true; } return false; } public function getByScore($s) { $s = intval($s); $node = $this->head; for ($i=$this->max_level-1; $i >= 0 && $s>0; $i--) { if (!isset($node->levelNode[$i]) || empty($node->levelNode[$i]->next) || $node->levelNode[$i]->next_step > $s) { continue; } do { if ($node->levelNode[$i]->next_step === $s) { $s=0; }else{ $s -= $node->levelNode[$i]->next_step; } $node = $node->levelNode[$i]->next->node; if ($s<=0) break; } while (isset($node->levelNode[$i]->next->node) && $node->levelNode[$i]->next->node && $node->levelNode[$i]->next_step <= $s); } return isset($node->mem) && $s<=0 ? $node->mem : null; } public function getRank($s, $e) { $s = intval($s); $e = intval($e); $ret = array(); if ($s > $e || $s <1 ) { return $ret; } $node = $this->head; $step = 0; for ($i=$this->max_level; $i >= 0; $i--) { while(isset($node->levelNode[$i]->next) && $node->levelNode[$i]->next && ($step + $node->levelNode[$i]->next_step) <= $s) { $step += $node->levelNode[$i]->next_step; $node = $node->levelNode[$i]->next->node; } if ($step === $s) { break; } } if ($step === $s) { do { if ($step > $e || empty($node)) { break; } $ret[] = $node->mem; $step += $node->levelNode[0]->next_step; $node = isset($node->levelNode[0]->next->node) ? $node->levelNode[0]->next->node : null; } while (true); } return $ret; } public function getScore($mem) { $mem = strval($mem); $node = $this->getNodePosByMem($mem); if ($node) { $step = 0; $preNode = $node; do { $preNode = $preNode->pre; if ($preNode === null) { break; } if ($preNode->level < $node->level) { continue; } $step += $preNode->levelNode[$node->level-1]->next_step; } while (true); return $step; } return null; } private function getNodePosByMem($mem) { return isset($this->hash_table[$mem]) ? $this->hash_table[$mem] : null; } private function delNodePosByMem($mem) { unset($this->hash_table[$mem]); } private function getNodePos($d) { $listNode = $this->head; $i = $listNode->level-1; do{ $node = isset($listNode->levelNode[$i]->next->node) ? $listNode->levelNode[$i]->next->node : null; if ($i>0) { if (empty($node)) { $i--; continue; } }else{ if (empty($node)) { break; } } if ($node->d > $d) { if ($i === 0) { break; }else{ while ($i>0 && $node->levelNode[$i]->next_step === $node->levelNode[--$i]->next_step) {}; } }elseif ($node->d === $d) { break; }else{ $listNode = $node; continue; } }while ($i>=0); return $listNode; } private function node_level() { $level = 1; do{ if (mt_rand(0,10000) > 1999) break; }while (++$level && $level < $this->max_level); if ($level === $this->max_level) { $skipListLevelNode = new skipListLevelNode(); $skipListLevelNode->cur_level = $level-1; $skipListLevelNode->node = $this->head; $this->head->levelNode[] = $skipListLevelNode; $this->max_level++; } return $level; } public function print_list() { $node = $this->head; do { if (!isset($node->levelNode[0]->next) || empty($node->levelNode[0]->next)) { break; } $node = $node->levelNode[0]->next->node; var_dump($node->mem . " = " . $node->d, $node->level, isset($node->pre) ? $node->pre->mem:'null'); for ($i=0; $i < $node->level; $i++) { echo "+++ {$i} +++"; var_dump($node->levelNode[$i]->next_step, isset($node->levelNode[$i]->next)); } echo "-----------------------
"; } while (1); echo "-----------head------------
"; foreach ($this->head->levelNode as $key => $n) { if (isset($n->next)) { $node = $n->next->node; var_dump($node->level . ":" . $node->mem . " = " . $node->d, $n->next_step); } } } }


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Java从入门到精通

Java从入门到精通

李钟尉、马文强、陈丹丹 / 清华大学出版社 / 2008-9 / 59.80元

《Java从入门到精通》(软件开发视频大讲堂)从初学者角度出发,通过通俗易懂的语言、丰富多彩的实例,详细介绍了使用Java语言进行程序开发应该掌握的各方面技术。全书共分28章,包括:初识Java,熟悉Eclipse开发工具,Java语言基础,流程控制,字符串,数组,类和对象,包装类,数字处理类,接口、继承与多态,类的高级特性,异常处理,Swing程序设计,集合类,I/O输入输出,反射,枚举类型与泛......一起来看看 《Java从入门到精通》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具