使用 PHP/MySQL 从头开始​​创建树遍历层次结构

发布于 2024-10-20 11:36:22 字数 1278 浏览 1 评论 0原文

我目前正在开发一个类别层次结构,我认为我得到了创建树遍历的要点。但我需要使用 PHP 函数向该层次结构添加一个新节点。

问题是rebuild_tree函数就足够好了(换句话说,对于大树来说效率很高)。

示例查询:

 CREATE TABLE `t_categories`(
   `id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
   `title` VARCHAR(45) NOT NULL,
   `lft` INTEGER UNSIGNED NOT NULL,
   `rght` INTEGER UNSIGNED NOT NULL,
   PRIMARY KEY (`id`)
 );

 INSERT INTO t_categories (title, lft, rght) VALUES ('Cat 1',1,16);
 INSERT INTO t_categories (title, lft, rght) VALUES ('Cat 2',2,3);
 INSERT INTO t_categories (title, lft, rght) VALUES ('Cat 3',4,7);
 INSERT INTO t_categories (title, lft, rght) VALUES ('Cat 4',5,6);
 INSERT INTO t_categories (title, lft, rght) VALUES ('Cat 5',8,13);
 INSERT INTO t_categories (title, lft, rght) VALUES ('Cat 6',9,12);
 INSERT INTO t_categories (title, lft, rght) VALUES ('Cat 7',10,11);
 INSERT INTO t_categories (title, lft, rght) VALUES ('Cat 8',14,15);

表结果如下所示:

 ID    TITLE   LFT    RGHT
 1     Cat1    1      16
 2     Cat2    2      3
 3     Cat3    4      7
 4     Cat4    5      6
 5     Cat5    8      13
 6     Cat6    9      12
 7     Cat7    10     11
 8     Cat8    14     15

我在上面提供了示例数据,但我还需要从头开始创建全新的节点。

那么,如何使用 PHP 函数将新节点添加到这棵树中,以提高大型树的效率?

I am currently developing a category hierarchy, and I got the point of creating tree treversal i think. But I need to add a new node into this hierarchy usign PHP function.

The problem is rebuild_tree function would be good enough (in other words, efficient with large trees).

Sample query:

 CREATE TABLE `t_categories`(
   `id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
   `title` VARCHAR(45) NOT NULL,
   `lft` INTEGER UNSIGNED NOT NULL,
   `rght` INTEGER UNSIGNED NOT NULL,
   PRIMARY KEY (`id`)
 );

 INSERT INTO t_categories (title, lft, rght) VALUES ('Cat 1',1,16);
 INSERT INTO t_categories (title, lft, rght) VALUES ('Cat 2',2,3);
 INSERT INTO t_categories (title, lft, rght) VALUES ('Cat 3',4,7);
 INSERT INTO t_categories (title, lft, rght) VALUES ('Cat 4',5,6);
 INSERT INTO t_categories (title, lft, rght) VALUES ('Cat 5',8,13);
 INSERT INTO t_categories (title, lft, rght) VALUES ('Cat 6',9,12);
 INSERT INTO t_categories (title, lft, rght) VALUES ('Cat 7',10,11);
 INSERT INTO t_categories (title, lft, rght) VALUES ('Cat 8',14,15);

Table results look like that:

 ID    TITLE   LFT    RGHT
 1     Cat1    1      16
 2     Cat2    2      3
 3     Cat3    4      7
 4     Cat4    5      6
 5     Cat5    8      13
 6     Cat6    9      12
 7     Cat7    10     11
 8     Cat8    14     15

I gave sample data above, but I need to create completely new node from scratch as well.

So, how can I add a new node into this tree using PHP function that efficients with large trees?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

救赎№ 2024-10-27 11:36:22

这是一棵celko树。最简单的方法是深度优先遍历树,仅更新左值,然后以递归方式更新右值。插入的成本要高得多。

This is a celko tree. Simpelst approach would be depth-first traversal of the tree and update only the left value and then in a recursive manner the right value. Insertition is much more costly.

北座城市 2024-10-27 11:36:22

我建议您在表结构中添加“父 ID”字段,而不是“左”和“右”字段。如果子项目的订单对您很重要,也可以使用“localorder”int 字段。

在当前的结构中,每次要添加一个项目时,对于第一个项目,都必须检查是否存在前一个项目,对于最后一个项目,必须检查是否存在最终项目。

CREATE TABLE `t_categories`(
   `keyid` INTEGER UNSIGNED NOT NULL,
   `title` VARCHAR(45) NOT NULL,
   `parentid` INTEGER UNSIGNED NOT NULL,
   `sortorder` INTEGER UNSIGNED NOT NULL,
   PRIMARY KEY (`id`)
 );

-- root item, no parent
 INSERT INTO t_categories (keyid, title, parentid, sortorder) VALUES (1, 'Root', 0, 0);

-- first level
 INSERT INTO t_categories (keyid, title, parentid, sortorder) VALUES (2, 'a:', 1, 1);
 INSERT INTO t_categories (keyid, title, parentid, sortorder) VALUES (3, 'b:', 1, 2);
 INSERT INTO t_categories (keyid, title, parentid, sortorder) VALUES (3, 'c:', 1, 3);
 INSERT INTO t_categories (keyid, title, parentid, sortorder) VALUES (4, 'd:', 1, 4);

-- second level

 INSERT INTO t_categories (keyid, title, parentid, sortorder) VALUES (5, 'a:\temp', 2, 1);
 INSERT INTO t_categories (keyid, title, parentid, sortorder) VALUES (6, 'a:\docs'', 2, 2);
 INSERT INTO t_categories (keyid, title, parentid, sortorder) VALUES (7, 'a:\music', 2, 3);

 INSERT INTO t_categories (keyid, title, parentid, sortorder) VALUES (8, 'c:\temp', 4, 1);
 INSERT INTO t_categories (keyid, title, parentid, sortorder) VALUES (9, 'c:\docs'', 4, 2);
 INSERT INTO t_categories (keyid, title, parentid, sortorder) VALUES (10, 'c:\music', 4, 3);

-- and so on

I recommend that you add a "parent id" field to your table structure instead of the "left" and "right" fields. If its important to you have an order for the children items, use also a "localorder" int field.

With the current structure, each time you want to add an item, you have to check if there is a previous item, for the first item, and to check if there is a final item, for a last item.

CREATE TABLE `t_categories`(
   `keyid` INTEGER UNSIGNED NOT NULL,
   `title` VARCHAR(45) NOT NULL,
   `parentid` INTEGER UNSIGNED NOT NULL,
   `sortorder` INTEGER UNSIGNED NOT NULL,
   PRIMARY KEY (`id`)
 );

-- root item, no parent
 INSERT INTO t_categories (keyid, title, parentid, sortorder) VALUES (1, 'Root', 0, 0);

-- first level
 INSERT INTO t_categories (keyid, title, parentid, sortorder) VALUES (2, 'a:', 1, 1);
 INSERT INTO t_categories (keyid, title, parentid, sortorder) VALUES (3, 'b:', 1, 2);
 INSERT INTO t_categories (keyid, title, parentid, sortorder) VALUES (3, 'c:', 1, 3);
 INSERT INTO t_categories (keyid, title, parentid, sortorder) VALUES (4, 'd:', 1, 4);

-- second level

 INSERT INTO t_categories (keyid, title, parentid, sortorder) VALUES (5, 'a:\temp', 2, 1);
 INSERT INTO t_categories (keyid, title, parentid, sortorder) VALUES (6, 'a:\docs'', 2, 2);
 INSERT INTO t_categories (keyid, title, parentid, sortorder) VALUES (7, 'a:\music', 2, 3);

 INSERT INTO t_categories (keyid, title, parentid, sortorder) VALUES (8, 'c:\temp', 4, 1);
 INSERT INTO t_categories (keyid, title, parentid, sortorder) VALUES (9, 'c:\docs'', 4, 2);
 INSERT INTO t_categories (keyid, title, parentid, sortorder) VALUES (10, 'c:\music', 4, 3);

-- and so on
妳是的陽光 2024-10-27 11:36:22

霍夫曼压缩使用同一棵树来计算给定文档中字母的出现次数。我认为对字符串进行编码,然后算法还使用深度优先遍历,以便使用尽可能少的位对出现次数最多的字母进行编码。我不知道它在这里是否有用,但使用香农定理 -log(x)+log(2) 可以找到文本的最低熵,其中 x 是字母,log(2) 是位的基数,它始终是2.

The same tree is used by the huffman compresssion to count the occurrence of a letter in the given document. I think to encode a string the algorithm then use also a depth-first traversal so that the letter with the most occurrence is encoded with the least bits possible. I don't know if it is useful here but the lowest entropy of a text is found using shannon theorm -log(x)+log(2) where x is the letter and log(2) is the base in bits it is always 2.

别闹i 2024-10-27 11:36:22

我之前的回答不完整。这是一个摘要,整个代码太长了,无法在论坛帖子中发表。忘了问,程序化 PHP,还是面向对象 PHP?

MySQL:
创建表t_categories(
keyid 整数无符号非空,
标题 VARCHAR(45) NOT NULL,
parentid 整数无符号非空,
sortorder 整数无符号非空,
主键(id
);

PHP 函数头:

// globar var,作用类似于类型
/* typedef */ treeNodeType = array(
“密钥ID”=> 0,
“标题”=> "",
“父代” => 0,
“排序顺序”=> 0,
)

// globar var,作用类似于类型
/* typedef */ treeType = array(
“根” =>零,
“无论如何” => "",
)

/* treeNodeType / function insertNode(/ treeType / ATree, AParentId, ATitle) { ... }
/
void / function deleteNode(/ treeType */ ATree, AKeyId) { ... }

// -->主要的
主要的();

/* 无效 */ 函数 main() {
// 树类型 myTree;
myTree = 树类型;

// 插入根=0
rootNode = insertNode(myTree, 0, '[PC]');

...
}

My previous answer is incomplete. It's a summary, the whole code is to long to be in a forum post. Forgot to ask, procedural PHP, or Object Oriented PHP ?

MySQL:
CREATE TABLE t_categories(
keyid INTEGER UNSIGNED NOT NULL,
title VARCHAR(45) NOT NULL,
parentid INTEGER UNSIGNED NOT NULL,
sortorder INTEGER UNSIGNED NOT NULL,
PRIMARY KEY (id)
);

PHP function headers:

// globar var, acts like a type
/* typedef */ treeNodeType = array(
"keyid" => 0,
"title" => "",
"parentid" => 0,
"sortorder" => 0,
)

// globar var, acts like a type
/* typedef */ treeType = array(
"root" => nil,
"whatever" => "",
)

/* treeNodeType / function insertNode(/ treeType / ATree, AParentId, ATitle) { ... }
/
void / function deleteNode(/ treeType */ ATree, AKeyId) { ... }

// --> MAIN
main();

/* void */ function main() {
// treeType myTree;
myTree = treeType;

// insert root = 0
rootNode = insertNode(myTree, 0, '[PC]');

...
}

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文