PHP数据结构(十三) ——动态查找表(二叉排序树)
PHP数据结构(十三)
——动态查找表(二叉排序树)
(原创内容,转载请注明来源,谢谢)
一、概念
1、动态查找表特点
当对动态查找表进行查找时,如果查找成功,会返回查找结果;如果查找失败,会对动态查找表插入查找结果,并且根据各类动态查找表的性质,对表进行动态调整。
2、二叉排序树(又称二叉查找树)
二叉排序树或者是一棵空树,或者满足以下特性:
1)若左子树非空,则左子树的所有节点小于根节点;
2)若右子树非空,则右子树的所有节点大于根节点;
3)左子树和右子树及其子树也都是二叉排序树。
二、二叉排序树
1、查找
二叉排序树的查找较为简单,从根节点开始查找,如果key大于根节点,则到其右子树进行查找,否则到其左子树进行查找。
根据二叉排序树的性质,对二叉排序树进行中序遍历,则可以得到一个从小到大的线性序列。
2、插入
二叉排序树的插入都是在叶子节点之后,当查找不成功时,会在遍历到的最后一个节点的左边或者右边插入节点。
3、删除
1)当删除的是叶子节点时,只需要改变父节点的指向(指为null)。
2)当删除的不是叶子节点时,如果其只有左子树或右子树的一边,则让子树接到父节点上(根据大小比较判断是父节点的左子树还是右子树)。
3)当删除的不是叶子节点,且同时有左子树和右子树,则根据中序遍历的结果,将左右子树分别接到其前驱或后继上。
4、二叉排序树图
5、二叉排序树生成与查询
二叉排序树属于动态查找表,因此生成的过程也就是查找和插入的过程。当一开始没有节点时,查找即插入节点,而后根据查找,逐步进行插入的过程。
二叉排序树的插入和遍历的结果如下:
源代码如下:
<?php
class Node{
public$index;
public$data;
public$left;
public$right;
public$parent;
}
class BinarySearchTree{
private$tree = null;
//构造二叉查找树
//arrNodes= array(array($index, $value), array($index2, $value2)...)
publicfunction generate($arrNodes){
if(empty($arrNodes)){
returnfalse;
}
$arrInsert= array();//记录插入的结果
$arrSearch= array();//记录查询的结果
foreach($arrNodesas $node){
$arr= $this->searchNode($node);
if($arr[0]){
array_push($arrSearch,array($arr[1], $arr[2]));
}else{
array_push($arrInsert,array($arr[1], $arr[2]));
}
}
returnarray($arrSearch, $arrInsert);
}
//查找结点,如果没有则插入
//返回array(bool,int,string)
//第一个参数如果是true表示查找到,如果是false表示没查到调用了插入函数
//第二个参数是index,第三个参数是data
publicfunction searchNode($node){
$index= $node[0];
$data= $node[1];
if(null== $this->tree){
$this->tree= new Node();
$this->tree->index= $index;
$this->tree->data= $data;
returnarray(false, $index, $data);
}
$curNode= $this->tree;
while(null!= $curNode){
if($index== $curNode->index){
//如果等于,则查到,返回查询结果
returnarray(true, $curNode->index, $curNode->data);
}
if($index> $curNode->index){
//如果查询的点比节点大,则往右边查,如果没有右子树,则插入,否则查右子树
if(null== $curNode->right){
$this->insertNode($curNode,$index, $data, 'right');
returnarray(false, $index, $data);
}else{
$curNode= $curNode->right;
continue;
}
}
if($index< $curNode->index){
//如果查询的点比节点小,则往左边查,如果没有左子树,则插入,否则查左子树
if(null== $curNode->left){
$this->insertNode($curNode,$index, $data, 'left');
returnarray(false, $index, $data);
}else{
$curNode= $curNode->left;
continue;
}
}
}
}
//插入节点
publicfunction insertNode(Node &$curNode, $index, $data, $pos){
if('left'== $pos){
$curNode->left= new Node();
$curNode->left->data= $data;
$curNode->left->index= $index;
}else{
$curNode->right= new Node();
$curNode->right->data= $data;
$curNode->right->index= $index;
}
}
//中序遍历二叉树
publicfunction centerSearch(){
if(null== $this->tree || !($this->tree instanceof Node)){
returnfalse;
}
$resultStack= array();
$nodeStack= array();
$centerNode= $this->tree;
while(!empty($nodeStack)|| null != $centerNode){
while(null!= $centerNode){
array_push($nodeStack,$centerNode);
$centerNode= $centerNode->left;
}
$centerNode= array_pop($nodeStack);
array_push($resultStack,array($centerNode->index, $centerNode->data));
$centerNode= $centerNode->right;
}
return$resultStack;
}
}
$binarySearchTree = new BinarySearchTree();
$arr =$binarySearchTree->generate(array(array(50, 'a'), array(40, 'b'), array(60,'c'), array(30, 'd'), array(45, 'e'), array(70, 'f'), array(65, 'g')));
echo '共计插入的节点:';
print_r($arr[1]);
echo '<br />共计查找到的节点:';
print_r($arr[0]);
echo '<br />';
$arr =$binarySearchTree->centerSearch();
echo '中序遍历的结果:';
print_r($arr);
——written by linhxx 2017.07.14
相关阅读:
PHP数据结构(十二) ——静态查找表
PHP数据结构(十一) ——图的连通性问题与最小生成树算法(2)
PHP数据结构(十一) ——图的连通性问题与最小生成树算法(1)
PHP数据结构(十) ——有向无环图与拓扑算法
PHP数据结构(九) ——图的定义、存储与两种方式遍历
PHP数据结构(八) ——赫夫曼树实现字符串编解码(实践2)
PHP数据结构(八) ——赫夫曼树实现字符串编解码(实践1)
PHP数据结构(八) ——赫夫曼树实现字符串编解码(理论)
PHP数据结构(七) ——串与实现KMP算法
PHP数据结构(六) ——树与二叉树之概念及存储结构
PHP数据结构(六) ——数组的相乘、广义表
PHP数据结构(五) ——数组的压缩与转置
PHP数据结构(四) ——队列
PHP数据结构(三)——运用栈实现括号匹配
PHP数据结构(二)——链式结构线性表
PHP数据结构(一)——顺序结构线性表
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- sklearn的predict_proba使用说明
- 如何使用python记录室友的抖音在线时间
- 使用keras实现BiLSTM+CNN+CRF文字标记NER
- 图解MyBatis的SQL执行流程
- Keras: model实现固定部分layer,训练部分layer操作
- 在Keras中CNN联合LSTM进行分类实例
- DeepWalk:图网络与NLP的巧妙融合
- PHP扩展mcrypt实现的AES加密功能示例
- PHP PDOStatement::bindColumn讲解
- PHP PDOStatement::fetchAll讲解
- PHP PDOStatement::bindParam讲解
- PHP date()格式MySQL中插入datetime方法
- Python sklearn中的.fit与.predict的用法说明
- 基于python实现ROC曲线绘制广场解析
- Python建造者模式案例运行原理解析