龙行博客

走路看风景,经历看人生,岁月留痕迹,人生留轨迹,17的历史,18的豪情,时间的匆忙,人生的风景,放开心胸往前走,成功再远行,放开理想往前走,梦想再行动。
现在位置:首页 > 编程语言 > PHP > tp5预排序左右值算法超级详细篇

tp5预排序左右值算法超级详细篇

龙行    PHP    2018-9-20    822    1评论    本文已被百度收录点击查看详情

一个功能需要用到预排序左右值算法,网上找了很多,但是都不详细,主要的转移都没有,所以今天来分享个令人头疼的预排序

封装成了一个类,直接调用就可以了

<?php
namespace mptta;
/**
 * 预排序遍历树算法(modified preorder tree traversal algorithm)
 */
use think\Db;

class MPTTA
{
    public $options = [
        'table' => 'user',
        'pk' => 'id',
        'lft' => 'lft',
        'rgt' => 'rgt',
        'parent_id' => 'parent_id',
        'node_status' => 'node_status'
    ];

    /**
     * 添加节点
     * 我们选择在父节点尾部插入新节点
     * @param int $parent_node 父节点id
     * @param int $node_id        要插入的节点id
     */
    public function installNode($node_id, $parent_node_id)
    {
        $table = $this->options['table'];
        // 先取出父节点的信息
        if ($parent = Db::query("SELECT * FROM `$table` WHERE `{$this->options['pk']}`=$parent_node_id")) {
            $parent = $parent[0];
        }

        // 再取出子节点的信息
        if ($node = Db::query("SELECT * FROM `$table` WHERE `{$this->options['pk']}`=$node_id")) {
            $node = $node[0];
        }

        $num = $node[$this->options['rgt']] + 1 - $node[$this->options['lft']];
        Db::query("UPDATE `$table` SET `{$this->options['lft']}`=`{$this->options['lft']}`+$num WHERE `{$this->options['lft']}`>{$parent[$this->options['rgt']]} AND `{$this->options['node_status']}`=0");
        Db::query("UPDATE `$table` SET `{$this->options['rgt']}`=`{$this->options['rgt']}`+$num WHERE `{$this->options['rgt']}`>={$parent[$this->options['rgt']]} AND `{$this->options['node_status']}`=0");
        print_r(Db::getLastSql());

        $num2 = $parent['rgt'] - $node[$this->options['lft']];
        Db::query("UPDATE `$table` SET `{$this->options['lft']}`=`{$this->options['lft']}`+$num2, `{$this->options['rgt']}`=`{$this->options['rgt']}`+$num2, `{$this->options['node_status']}`=0 WHERE `{$this->options['lft']}`>={$node[$this->options['lft']]} AND `{$this->options['rgt']}`<={$node[$this->options['rgt']]} AND `{$this->options['node_status']}`=1");
        Db::query("UPDATE `$table` SET `{$this->options['parent_id']}`=$parent_node_id WHERE `{$this->options['pk']}`=$node_id");
    }

    /**
     * 删除节点
     */
    public function removeNode($node_id)
    {
        $table = $this->options['table'];
        $pk = $this->options['pk'];
        $rgt = $this->options['rgt'];
        $lft = $this->options['lft'];

        // 取出子节点的信息
        if ($node = Db::query("SELECT * FROM `$table` WHERE `$pk`=$node_id")) {
            $node = $node[0];
        }
        $num = $node[$rgt] + 1 - $node[$lft];

        //Db::query("DELETE FROM `$table` WHERE {$lft}>={$node[$lft]} AND {$rgt}<={$node[$rgt]}");
        Db::query("UPDATE `$table` SET `{$this->options['node_status']}`=1 WHERE {$lft}>={$node[$lft]} AND {$rgt}<={$node[$rgt]}");

        Db::query("UPDATE `$table` SET `{$this->options['rgt']}`=`{$this->options['rgt']}`-$num WHERE {$this->options['rgt']}>{$node[$this->options['rgt']]} AND `{$this->options['node_status']}`=0");
        Db::query("UPDATE `$table` SET `{$this->options['lft']}`=`{$this->options['lft']}`-$num WHERE {$this->options['lft']}>{$node[$this->options['lft']]} AND `{$this->options['node_status']}`=0");
    }

    /**
     * 移动节点
     */
    public function moveNode($parent_node_id, $node_id)
    {
        $this->removeNode($node_id);
        $this->installNode($node_id, $parent_node_id);
    }
}
上面的类删除使用的是软删除下面的是硬删除:使用上面的类需要几个字段lft默认值1,rgt默认值2,node_status默认值1
public function userLftRgtDelete($id)
    {
        $data = $this->where('id', $id)->field('lft,rgt')->find()->toArray();
        $middle = $data['rgt'] - $data['lft'] + 1;
        $this->where('lft', 'between', [$data['lft'], $data['rgt']])->delete();
        $this->execute("UPDATE `user` SET rgt = rgt-{$middle} WHERE rgt > {$data['rgt']}");
        $data = $this->execute("UPDATE `user` SET lft = lft-{$middle} WHERE lft > {$data['rgt']}");
        return $data;
    }
全是干货,网上的那些复制了一百遍的我真的被坑了


评论一下 分享本文 赞助站长

赞助站长X

扫码赞助站长
联系站长
龙行博客
  • 版权申明:此文如未标注转载均为本站原创,自由转载请表明出处《龙行博客》。
  • 本文网址:https://www.liaotaoo.cn/31.html
  • 上篇文章:CentOS 7上安装和配置Nagios
  • 下篇文章:git配置公钥免密登录
  • php左右值排序
挤眼 亲亲 咆哮 开心 想想 可怜 糗大了 委屈 哈哈 小声点 右哼哼 左哼哼 疑问 坏笑 赚钱啦 悲伤 耍酷 勾引 厉害 握手 耶 嘻嘻 害羞 鼓掌 馋嘴 抓狂 抱抱 围观 威武 给力
提交评论

清空信息
关闭评论
龙行
龙行2019-04-09 00:00回复
#1
看不懂的,我只能呵呵了,我自己看得懂就行
快捷导航
联系博主
在线壁纸
给我留言
光羽影视
音乐欣赏
返回顶部