美文网首页
php+redis实现二叉树的存储和遍历

php+redis实现二叉树的存储和遍历

作者: 不能吃的坚果j | 来源:发表于2019-08-21 16:36 被阅读0次

本文作者:陈进坚
博客地址:https://jian1098.github.io
CSDN博客:https://blog.csdn.net/c_jian
联系方式:jian1098@qq.com

github地址:https://github.com/jian1098/php-redis-binary-tree

二叉树是软件开发过程中很常见的数据结构,本文通过php进行二叉树的生成和遍历,通过redis将二叉树存储,也可以将redis换成其他的关系型数据库,但是读写速度嘛是差挺远的。代码中有足够的注释,应该不难懂,仅供参考和学习。

首先封装二叉树的生成和遍历算法

tree.php

<?php

// 节点类
Class BTNode
{
    public $data;
    public $lChild;
    public $rChild;

    public function __construct($data = null)
    {
        $this->data = $data;
    }
}

// 二叉树类
Class BinaryTree
{
    public $btData;

    public function __construct($data = null)
    {
        $this->btData = $data;
    }

    //创建二叉树
    public function CreateBT(&$root = null)
    {
        $elem = array_shift($this->btData);
        if ($elem == null) {
            return 0;
        } else if ($elem == '#') {
            $root = null;
        } else {
            $root = new BTNode();
            $root->data = $elem;
            $this->CreateBT($root->lChild);
            $this->CreateBT($root->rChild);
        }
        return $root;
    }

    //先序遍历二叉树
    public function PreOrder($root)
    {
        if ($root != null) {
            echo $root->data . " ";
            $this->PreOrder($root->lChild);
            $this->PreOrder($root->rChild);

        } else {
            return;
        }
    }

    //中序遍历二叉树
    public function InOrder($root)
    {
        if ($root != null) {
            $this->InOrder($root->lChild);
            echo $root->data . " ";
            $this->InOrder($root->rChild);

        } else {
            return;
        }
    }

    //后序遍历二叉树
    public function PosOrder($root)
    {
        if ($root != null) {
            $this->PosOrder($root->lChild);
            $this->PosOrder($root->rChild);
            echo $root->data . " ";

        } else {
            return;
        }
    }

    //层序(广度优先)遍历二叉树
    function LeverOrder($root)
    {
        $queue = new SplQueue();//双向链表
        if ($root == null){
            return;
        }else{
            $queue->enqueue($root);
        }

        while (!$queue->isEmpty()) {
            $node = $queue->bottom();
            $queue->dequeue();
            echo $node->data . " ";
            if ($node->lChild){
                $queue->enqueue($node->lChild);
            }else{
//                echo $node->data.'的左子树为空';
            }
            if ($node->rChild){
                $queue->enqueue($node->rChild);
            }else{
//                echo $node->data.'的右子树为空';
            }
        }
    }
}

接着封装操作redis的类

redis.php

<?php

class MyRedis {
    private $redis;
    private $host;  //redis ip
    private $port;  //redis 端口
    private $tree;

    public function __construct($host,$port){
        $this->host=$host;
        $this->port=$port;
        //连接redis
        if(class_exists('Redis')){
            $this->redis = new \Redis();
            if($this->redis->connect($this->host, $this->port)){
                $this->connect=true;
            }
        }else{
            exit('redis扩展不存在');
        }
    }

    //添加节点
    public function addNode($id,$data){
        if(!is_array($data)){
            return [];
        }
        $resOrder=$this->redis->hMSet($id,$data);
        return $resOrder;
    }

    //查找节点
    public function getNode($id){
        return $this->redis->hGetAll($id);
    }

    //修改指定节点的属性
    public function setNode($id,$field,$value){
        return $this->redis->hSet($id,$field,$value);
    }

    //获取redis所有键
    public function getKeys(){
        return $this->redis->keys('*');
    }

    //获取key的个数
    public function dbSize(){
        return $this->redis->dbSize();
    }

    //清空数据库
    public function flushDB(){
        return $this->redis->flushDB();
    }

    //前序遍历的顺序取出二叉树
    public function tree($root_id){
        $rootNode=$this->getNode($root_id);
        $this->tree[]=$root_id;
        if (isset($rootNode['left'])){
            $this->tree($rootNode['left']);
        }
        if (isset($rootNode['right'])){
            $this->tree($rootNode['right']);
        }
        return $this->tree;
    }
}

最后调用两个类进行二叉树的存取和遍历

index.php

<?php
require_once 'redis.php';
require_once 'tree.php';

$myredis=new MyRedis('127.0.0.1','6379');

/*
    假设我构造一颗如下的二叉树
            1
        2       3
      #   4   #   #
        #   #
*/

//添加节点
//$data=[
//    'left'      =>      '2',
//    'right'     =>      '3',
//];
//$res=$myredis->addNode(1,$data);
//
//$data=[
//    'left'      =>      '#',
//    'right'     =>      '4',
//];
//$res=$myredis->addNode(2,$data);
//
//$data=[
//    'left'      =>      '#',
//    'right'     =>      '#',
//];
//$res=$myredis->addNode(3,$data);
//
//$data=[
//    'left'      =>      '#',
//    'right'     =>      '#',
//];
//$res=$myredis->addNode(4,$data);
//print_r($res);

//修改节点信息
//$res=$myredis->setNode(1,'left',2);
//print_r($res);

//查询指定节点
//$res=$myredis->getNode(1);
//print_r($res);

//清空数据
//$res=$myredis->flushDB();
//获取redis所有键
//$res=$myredis->getKeys();
//print_r($res);

//前序遍历的顺序从redis读取节点
$data=$myredis->tree(1);//$data = array(1,2,'#',4,'#','#',3,'#','#');

//生成二叉树
$tree = new BinaryTree($data);
$root = $tree->CreateBT();

//遍历二叉树
echo '前序:';
$tree->PreOrder($root);
echo '<br>中序:';
$tree->InOrder($root);
echo '<br>后序:';
$tree->PosOrder($root);
echo '<br>层序:';
$tree->LeverOrder($root);

执行结果

前序:1 2 4 3 
中序:2 4 1 3 
后序:4 2 3 1 
层序:1 2 3 4

相关文章

  • php+redis实现二叉树的存储和遍历

    本文作者:陈进坚博客地址:https://jian1098.github.ioCSDN博客:https://blo...

  • Java二叉树的遍历

    Java二叉树的遍历 利用递归和非递归实现二叉树的先序,中序,后序遍历以及使用队列实现二叉树的层次遍历

  • 数据结构:树的实现和遍历(c++)

    (一)二叉树的遍历——递归实现 二叉树常见的遍历方式分为前序遍历、中序遍历和后序遍历。 1 前序遍历 前序遍历也叫...

  • 二叉树操作

    树节点 逐行顺序解析二叉树 前序遍历二叉树 中序遍历二叉树 后序遍历二叉树 删除指定数值的节点 前序遍历顺序存储的...

  • 二叉树遍历

    二叉树 二叉树的存储结构 前序遍历 中序遍历 后序遍历 遍历代码 反转二叉树 深入学习二叉树 二叉树-你必须要懂!...

  • 数据结构基础学习之(树与二叉树)

    主要知识点: 树的定义及常用术语 树的存储表示 二叉树、满二叉树和完成二叉树的定义 二叉树的遍历此操作实现 哈夫曼...

  • java中如何实现重建二叉树

    java中如何实现重建二叉树 题目:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和...

  • 算法之二叉树

    二叉树之C++实现 创建二叉树 复制二叉树 先序遍历 递归实现 非递归实现 中序遍历 递归实现 非递归实现 后序遍...

  • 二叉树遍历(递归算法和非递归算法)

    实验三 二叉树遍历(递归算法和非递归算法) 一.实验目的 1.掌握二叉树的存储结构与基本操作 2.掌握二叉树的遍历...

  • 数据结构题目42:二叉树的前序遍历(非递归)

    题目:若二叉树为二叉链表存储结构,写出二叉树的前序遍历的非递归算法。 解题思路:和中序遍历很相似,只是遍历到结点要...

网友评论

      本文标题:php+redis实现二叉树的存储和遍历

      本文链接:https://www.haomeiwen.com/subject/tudisctx.html