- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章Java中树的存储结构实现示例代码由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
1、树 。
树与线性表、栈、队列等线性结构不同,树是一种非线性结构.
一棵树只有一个根节点,如果一棵树有了多个根节点,那它已经不再是一棵树了,而是多棵树的集合,也被称为森林.
2、树的父节点表示法 。
树中除根节点之外每个节点都有一个父节点,为了记录树中节点与节点之间的父子关系,可以为每个节点增加一个parent域,用以记录该节点的父节点.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
package
com.ietree.basic.datastructure.tree;
import
java.util.ArrayList;
import
java.util.List;
/**
* Created by ietree
* 2017/4/30
*/
public
class
TreeParent<E> {
public
static
class
Node<T> {
T data;
// 保存其父节点的位置
int
parent;
public
Node() {
}
public
Node(T data) {
this
.data = data;
}
public
Node(T data,
int
parent) {
this
.data = data;
this
.parent = parent;
}
public
String toString() {
return
"TreeParent$Node[data="
+ data +
", parent="
+ parent +
"]"
;
}
}
private
final
int
DEFAULT_TREE_SIZE =
100
;
private
int
treeSize =
0
;
// 使用一个Node[]数组来记录该树里的所有节点
private
Node<E>[] nodes;
// 记录树的节点数
private
int
nodeNums;
// 以指定节点创建树
public
TreeParent(E data) {
treeSize = DEFAULT_TREE_SIZE;
nodes =
new
Node[treeSize];
nodes[
0
] =
new
Node<E>(data, -
1
);
nodeNums++;
}
// 以指定根节点、指定treeSize创建树
public
TreeParent(E data,
int
treeSize) {
this
.treeSize = treeSize;
nodes =
new
Node[treeSize];
nodes[
0
] =
new
Node<E>(data, -
1
);
nodeNums++;
}
// 为指定节点添加子节点
public
void
addNode(E data, Node parent) {
for
(
int
i =
0
; i < treeSize; i++) {
// 找到数组中第一个为null的元素,该元素保存新节点
if
(nodes[i] ==
null
) {
// 创建新节点,并用指定的数组元素保存它
nodes[i] =
new
Node(data, pos(parent));
nodeNums++;
return
;
}
}
throw
new
RuntimeException(
"该树已满,无法添加新节点"
);
}
// 判断树是否为空
public
boolean
empty() {
// 根结点是否为null
return
nodes[
0
] ==
null
;
}
// 返回根节点
public
Node<E> root() {
// 返回根节点
return
nodes[
0
];
}
// 返回指定节点(非根结点)的父节点
public
Node<E> parent(Node node) {
// 每个节点的parent记录了其父节点的位置
return
nodes[node.parent];
}
// 返回指定节点(非叶子节点)的所有子节点
public
List<Node<E>> children(Node parent) {
List<Node<E>> list =
new
ArrayList<Node<E>>();
for
(
int
i =
0
; i < treeSize; i++) {
// 如果当前节点的父节点的位置等于parent节点的位置
if
(nodes[i] !=
null
&& nodes[i].parent == pos(parent)) {
list.add(nodes[i]);
}
}
return
list;
}
// 返回该树的深度
public
int
deep() {
// 用于记录节点的最大深度
int
max =
0
;
for
(
int
i =
0
; i < treeSize && nodes[i] !=
null
; i++) {
// 初始化本节点的深度
int
def =
1
;
// m 记录当前节点的父节点的位置
int
m = nodes[i].parent;
// 如果其父节点存在
while
(m != -
1
&& nodes[m] !=
null
) {
// 向上继续搜索父节点
m = nodes[m].parent;
def++;
}
if
(max < def) {
max = def;
}
}
return
max;
}
// 返回包含指定值的节点
public
int
pos(Node node) {
for
(
int
i =
0
; i < treeSize; i++) {
// 找到指定节点
if
(nodes[i] == node) {
return
i;
}
}
return
-
1
;
}
}
|
测试类:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
package
com.ietree.basic.datastructure.tree;
import
java.util.List;
/**
* Created by ietree
* 2017/4/30
*/
public
class
treeParentTest {
public
static
void
main(String[] args) {
TreeParent<String> tp =
new
TreeParent<String>(
"root"
);
TreeParent.Node root = tp.root();
System.out.println(root);
tp.addNode(
"节点1"
, root);
System.out.println(
"此树的深度:"
+ tp.deep());
tp.addNode(
"节点2"
, root);
// 获取根节点的所有子节点
List<TreeParent.Node<String>> nodes = tp.children(root);
System.out.println(
"根节点的第一个子节点:"
+ nodes.get(
0
));
// 为根节点的第一个子节点新增一个子节点
tp.addNode(
"节点3"
, nodes.get(
0
));
System.out.println(
"此树的深度:"
+ tp.deep());
}
}
|
程序输出:
TreeParent$Node[data=root, parent=-1] 此树的深度:2 根节点的第一个子节点:TreeParent$Node[data=节点1, parent=0] 此树的深度:3 。
3、子节点链表示法 。
让父节点记住它的所有子节点.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
|
package
com.ietree.basic.datastructure.tree;
import
java.util.ArrayList;
import
java.util.List;
/**
* Created by ietree
* 2017/4/30
*/
public
class
TreeChild<E> {
private
static
class
SonNode {
// 记录当前节点的位置
private
int
pos;
private
SonNode next;
public
SonNode(
int
pos, SonNode next) {
this
.pos = pos;
this
.next = next;
}
}
public
static
class
Node<T> {
T data;
// 记录第一个子节点
SonNode first;
public
Node(T data) {
this
.data = data;
this
.first =
null
;
}
public
String toString() {
if
(first !=
null
) {
return
"TreeChild$Node[data="
+ data +
", first="
+ first.pos +
"]"
;
}
else
{
return
"TreeChild$Node[data="
+ data +
", first=-1]"
;
}
}
}
private
final
int
DEFAULT_TREE_SIZE =
100
;
private
int
treeSize =
0
;
// 使用一个Node[]数组来记录该树里的所有节点
private
Node<E>[] nodes;
// 记录节点数
private
int
nodeNums;
// 以指定根节点创建树
public
TreeChild(E data) {
treeSize = DEFAULT_TREE_SIZE;
nodes =
new
Node[treeSize];
nodes[
0
] =
new
Node<E>(data);
nodeNums++;
}
// 以指定根节点、指定treeSize创建树
public
TreeChild(E data,
int
treeSize) {
this
.treeSize = treeSize;
nodes =
new
Node[treeSize];
nodes[
0
] =
new
Node<E>(data);
nodeNums++;
}
// 为指定节点添加子节点
public
void
addNode(E data, Node parent) {
for
(
int
i =
0
; i < treeSize; i++) {
// 找到数组中第一个为null的元素,该元素保存新节点
if
(nodes[i] ==
null
) {
// 创建新节点,并用指定数组元素保存它
nodes[i] =
new
Node(data);
if
(parent.first ==
null
) {
parent.first =
new
SonNode(i,
null
);
}
else
{
SonNode next = parent.first;
while
(next.next !=
null
) {
next = next.next;
}
next.next =
new
SonNode(i,
null
);
}
nodeNums++;
return
;
}
}
throw
new
RuntimeException(
"该树已满,无法添加新节点"
);
}
// 判断树是否为空
public
boolean
empty() {
// 根结点是否为null
return
nodes[
0
] ==
null
;
}
// 返回根节点
public
Node<E> root() {
// 返回根节点
return
nodes[
0
];
}
// 返回指定节点(非叶子节点)的所有子节点
public
List<Node<E>> children(Node parent) {
List<Node<E>> list =
new
ArrayList<Node<E>>();
// 获取parent节点的第一个子节点
SonNode next = parent.first;
// 沿着孩子链不断搜索下一个孩子节点
while
(next !=
null
) {
// 添加孩子链中的节点
list.add(nodes[next.pos]);
next = next.next;
}
return
list;
}
// 返回指定节点(非叶子节点)的第index个子节点
public
Node<E> child(Node parent,
int
index) {
// 获取parent节点的第一个子节点
SonNode next = parent.first;
// 沿着孩子链不断搜索下一个孩子节点
for
(
int
i =
0
; next !=
null
; i++) {
if
(index == i) {
return
nodes[next.pos];
}
next = next.next;
}
return
null
;
}
// 返回该树的深度
public
int
deep() {
// 获取该树的深度
return
deep(root());
}
// 这是一个递归方法:每棵子树的深度为其所有子树的最大深度 + 1
private
int
deep(Node node) {
if
(node.first ==
null
) {
return
1
;
}
else
{
// 记录其所有子树的最大深度
int
max =
0
;
SonNode next = node.first;
// 沿着孩子链不断搜索下一个孩子节点
while
(next !=
null
) {
// 获取以其子节点为根的子树的深度
int
tmp = deep(nodes[next.pos]);
if
(tmp > max) {
max = tmp;
}
next = next.next;
}
// 最后,返回其所有子树的最大深度 + 1
return
max +
1
;
}
}
// 返回包含指定值得节点
public
int
pos(Node node) {
for
(
int
i =
0
; i < treeSize; i++) {
// 找到指定节点
if
(nodes[i] == node) {
return
i;
}
}
return
-
1
;
}
}
|
测试类:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
package
com.ietree.basic.datastructure.tree;
import
java.util.List;
/**
* Created by ietree
* 2017/4/30
*/
public
class
TreeChildTest {
public
static
void
main(String[] args) {
TreeChild<String> tp =
new
TreeChild<String>(
"root"
);
TreeChild.Node root = tp.root();
System.out.println(root);
tp.addNode(
"节点1"
, root);
tp.addNode(
"节点2"
, root);
tp.addNode(
"节点3"
, root);
System.out.println(
"添加子节点后的根结点:"
+ root);
System.out.println(
"此树的深度:"
+ tp.deep());
// 获取根节点的所有子节点
List<TreeChild.Node<String>> nodes = tp.children(root);
System.out.println(
"根节点的第一个子节点:"
+ nodes.get(
0
));
// 为根节点的第一个子节点新增一个子节点
tp.addNode(
"节点4"
, nodes.get(
0
));
System.out.println(
"此树第一个子节点:"
+ nodes.get(
0
));
System.out.println(
"此树的深度:"
+ tp.deep());
}
}
|
程序输出:
TreeChild$Node[data=root, first=-1] 添加子节点后的根结点:TreeChild$Node[data=root, first=1] 此树的深度:2 根节点的第一个子节点:TreeChild$Node[data=节点1, first=-1] 此树第一个子节点:TreeChild$Node[data=节点1, first=4] 此树的深度:3 。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我.
原文链接:http://www.cnblogs.com/Dylansuns/p/6791270.html 。
最后此篇关于Java中树的存储结构实现示例代码的文章就讲到这里了,如果你想了解更多关于Java中树的存储结构实现示例代码的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我目前正在尝试基于哈希表构建字典。逻辑是:有一个名为 HashTable 的结构,其中包含以下内容: HashFunc HashFunc; PrintFunc PrintEntry; CompareF
如果我有一个指向结构/对象的指针,并且该结构/对象包含另外两个指向其他对象的指针,并且我想删除“包含这两个指针的对象而不破坏它所持有的指针”——我该怎么做这样做吗? 指向对象 A 的指针(包含指向对象
像这样的代码 package main import "fmt" type Hello struct { ID int Raw string } type World []*Hell
我有一个采用以下格式的 CSV: Module, Topic, Sub-topic 它需要能够导入到具有以下格式的 MySQL 数据库中: CREATE TABLE `modules` ( `id
通常我使用类似的东西 copy((uint8_t*)&POD, (uint8_t*)(&POD + 1 ), back_inserter(rawData)); copy((uint8_t*)&PODV
错误 : 联合只能在具有兼容列类型的表上执行。 结构(层:字符串,skyward_number:字符串,skyward_points:字符串)<> 结构(skyward_number:字符串,层:字符
我有一个指向结构的指针数组,我正在尝试使用它们进行 while 循环。我对如何准确初始化它并不完全有信心,但我一直这样做: Entry *newEntry = malloc(sizeof(Entry)
我正在学习 C,我的问题可能很愚蠢,但我很困惑。在这样的函数中: int afunction(somevariables) { if (someconditions)
我现在正在做一项编程作业,我并没有真正完全掌握链接,因为我们还没有涉及它。但是我觉得我需要它来做我想做的事情,因为数组还不够 我创建了一个结构,如下 struct node { float coef;
给定以下代码片段: #include #include #define MAX_SIZE 15 typedef struct{ int touchdowns; int intercepti
struct contact list[3]; int checknullarray() { for(int x=0;x<10;x++) { if(strlen(con
这个问题在这里已经有了答案: 关闭 11 年前。 Possible Duplicate: Empty “for” loop in Facebook ajax what does AJAX call
我刚刚在反射器中浏览了一个文件,并在结构构造函数中看到了这个: this = new Binder.SyntaxNodeOrToken(); 我以前从未见过该术语。有人能解释一下这个赋值在 C# 中的
我经常使用字符串常量,例如: DICT_KEY1 = 'DICT_KEY1' DICT_KEY2 = 'DICT_KEY2' ... 很多时候我不介意实际的文字是什么,只要它们是独一无二的并且对人类读
我是 C 的新手,我不明白为什么下面的代码不起作用: typedef struct{ uint8_t a; uint8_t* b; } test_struct; test_struct
您能否制作一个行为类似于内置类之一的结构,您可以在其中直接分配值而无需调用属性? 前任: RoundedDouble count; count = 5; 而不是使用 RoundedDouble cou
这是我的代码: #include typedef struct { const char *description; float value; int age; } swag
在创建嵌套列表时,我认为 R 具有对列表元素有用的命名结构。我有一个列表列表,并希望应用包含在任何列表中的每个向量的函数。 lapply这样做但随后剥离了列表的命名结构。我该怎么办 lapply嵌套列
我正在做一个用于学习目的的个人组织者,我从来没有使用过 XML,所以我不确定我的解决方案是否是最好的。这是我附带的 XML 文件的基本结构:
我是新来的 nosql概念,所以当我开始学习时 PouchDB ,我找到了这个转换表。我的困惑是,如何PouchDB如果可以说我有多个表,是否意味着我需要创建多个数据库?因为根据我在 pouchdb
我是一名优秀的程序员,十分优秀!