65.9K
CodeProject 正在变化。 阅读更多。
Home

动态链表树

starIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIconemptyStarIcon

1.07/5 (16投票s)

2006年6月30日

4分钟阅读

viewsIcon

40695

使用Vector和双向链表创建树。

引言

首先,我要感谢您学习新知识的热情,现在让我们继续我要告诉您的内容。链表树的想法非常简单,我假设您对什么是链表有一定的了解。

什么是链表树?

- 它在某种程度上是一个新概念,旨在加快处理需要嵌套数据类型和信息的数据,例如家族树之类的东西。链表树的这个想法基于双向链表,我们知道链表是一种包含同类型指针的数据类型,下面是我用来解释我意思的代码

struct DoubleLinkList

{

/* 这是一个相同数据类型的指针,它将指向

此类型的上一个对象(实例)*/

DoubleLinkList *Previous;

wchar_t UserName[50];

/* 这是一个相同数据类型的指针,它将指向下一个

此类型的对象(实例)*/

DoubleLinkList *Next;

}

现在让我们来解释什么是链表树。在图1中,它显示了数据类型的每个实例(对象)都将指向多个元素。正如您在图中看到的,每个元素都有一个路径“?-?-?”。例如,让我们看看元素路径“1-3-2”,您会注意到这个实例与其父节点“1-3”相连,而“1-3”又与对象实例路径“1”相关。现在我认为理论上已经很清楚了,它就像一个双向链表,只是它有多个子节点。我想我们需要一小段代码来解释这一点。

图 1

如何编写支持链表树的代码?

答案是使用一个指向子节点的指针数组和一个指向父节点的指针,下面是解释我所说的代码:

struct TreeLinkedList

{

/* 这个指针具有相同的数据类型,它

将指向这个相同数据类型的

父实例 */

TreeLinkedList* Parent;

wchar_t UserName[50];

/* 这是整个想法中最重要的部分,

它是一个指针数组,

将指向同一数据类型的

子实例*/

std::vector<TreeLinkedList*> Childes;

// 我使用了 vector(标准模板库之一)

// 你可以在 CodeProject.com 上找到关于它的好文章

// WTL 和 STD 有时会存在一些问题,所以如果你

// 不喜欢或者不能使用 STD vector,你可以把它做成

// 结构化的数据类型(我的意思是添加一些函数

// 来管理向子指针数组中添加新指针)

~TreeLinkedList()

{

// 不要忘记释放内存

Childes.empty();

}

};

如何使用我刚写的内容?

// 这里我们创建了 TreeLinkedList 数据类型的一些实例

// 你可以从变量名中理解树的层次结构

//

TreeLinkedList CurrentInstance;

TreeLinkedList CurrentInstanceChild1;

TreeLinkedList CurrentInstanceChild1_1;

TreeLinkedList CurrentInstanceChild2;

TreeLinkedList CurrentInstanceChild2_1;

TreeLinkedList CurrentInstanceChild2_2;

TreeLinkedList CurrentInstanceChild2_2_1;

TreeLinkedList CurrentInstanceChild2_3;

TreeLinkedList CurrentInstanceChild2_3_1;

// 首先将根实例的指针赋为 NULL,以确保

// 这个实例是父节点

CurrentInstance.Parent = 0;

// 使用 vector 模板类的成员 (push_back) 添加根节点的子节点

CurrentInstance.Childes.push_back(&CurrentInstanceChild1);

// 将父指针赋给这个数据类型的实例

CurrentInstanceChild1.Parent = &CurrentInstance;

//与 CurrentInstanceChild1 相同

CurrentInstance.Childes.push_back(&CurrentInstanceChild2);

//与 CurrentInstanceChild1 相同

CurrentInstanceChild2.Parent = &CurrentInstance;

// 之后,你要为子节点树分配父指针

CurrentInstanceChild1.Childes.push_back(&CurrentInstanceChild1_1);

CurrentInstanceChild1_1.Parent = &CurrentInstance;

CurrentInstanceChild2.Childes.push_back(&CurrentInstanceChild2_1);

CurrentInstanceChild2_1.Parent = &CurrentInstanceChild2;

CurrentInstanceChild2.Childes.push_back(&CurrentInstanceChild2_2);

CurrentInstanceChild2_2.Parent = &CurrentInstanceChild2;

CurrentInstanceChild2.Childes.push_back(&CurrentInstanceChild2_3);

CurrentInstanceChild2_3.Parent = &CurrentInstanceChild2;

CurrentInstanceChild2_2.Childes.push_back(&CurrentInstanceChild2_2_1);

CurrentInstanceChild2_2_1.Parent = &CurrentInstanceChild2_2;

CurrentInstanceChild2_3.Childes.push_back(&CurrentInstanceChild2_3_1);

CurrentInstanceChild2_3_1.Parent = &CurrentInstanceChild2_3;

我想这个例子非常清楚,但是我们如何从 CurrentInstanceChild2_3_1 实例中获取 UserName 数据呢?很简单,你只需要把它当作指针数组来处理,下面就是获取目标实例 UserName 的方法

CurrentInstance.Childes[0]->Childes[1]->Childes[2]->Childes[1]->UserName;

有人可能会认为这样做可能毫无用处,我们仍然在编写大量代码来添加和获取数据。在这种情况下,我会告诉你,这个理论是用于动态树的,或者你必须等到需要它的时候才会发现它的用处。

现在,真心感谢您花时间阅读我写的内容。

© . All rights reserved.