0
# Tree Modification
1
2
Insert, append, and remove objects with constant-time operations.
3
4
## Capabilities
5
6
### Append Child
7
8
Insert an object as the last child of a parent.
9
10
```javascript { .api }
11
/**
12
* Insert object as the last child of the reference object
13
* Time Complexity: O(1)
14
* @param {Object} referenceObject - Parent object
15
* @param {Object} newObject - Object to insert as last child
16
* @returns {Object} The inserted newObject
17
* @throws {Error} If newObject is already present in this SymbolTree
18
*/
19
appendChild(referenceObject: Object, newObject: Object): Object;
20
```
21
22
### Prepend Child
23
24
Insert an object as the first child of a parent.
25
26
```javascript { .api }
27
/**
28
* Insert object as the first child of the reference object
29
* Time Complexity: O(1)
30
* @param {Object} referenceObject - Parent object
31
* @param {Object} newObject - Object to insert as first child
32
* @returns {Object} The inserted newObject
33
* @throws {Error} If newObject is already present in this SymbolTree
34
*/
35
prependChild(referenceObject: Object, newObject: Object): Object;
36
```
37
38
### Insert Before
39
40
Insert an object before a reference object (as a sibling).
41
42
```javascript { .api }
43
/**
44
* Insert object before the reference object as a sibling
45
* Time Complexity: O(1)
46
* @param {Object} referenceObject - Reference object
47
* @param {Object} newObject - Object to insert before reference
48
* @returns {Object} The inserted newObject
49
* @throws {Error} If newObject is already present in this SymbolTree
50
*/
51
insertBefore(referenceObject: Object, newObject: Object): Object;
52
```
53
54
### Insert After
55
56
Insert an object after a reference object (as a sibling).
57
58
```javascript { .api }
59
/**
60
* Insert object after the reference object as a sibling
61
* Time Complexity: O(1)
62
* @param {Object} referenceObject - Reference object
63
* @param {Object} newObject - Object to insert after reference
64
* @returns {Object} The inserted newObject
65
* @throws {Error} If newObject is already present in this SymbolTree
66
*/
67
insertAfter(referenceObject: Object, newObject: Object): Object;
68
```
69
70
### Remove Object
71
72
Remove an object from the tree.
73
74
```javascript { .api }
75
/**
76
* Remove object from the tree
77
* Time Complexity: O(1)
78
* @param {Object} removeObject - Object to remove
79
* @returns {Object} The removed object (same as removeObject)
80
*/
81
remove(removeObject: Object): Object;
82
```
83
84
## Usage Examples
85
86
### Building Trees
87
88
```javascript
89
const SymbolTree = require("symbol-tree");
90
const tree = new SymbolTree();
91
92
// Create DOM-like structure
93
const html = { tag: "html" };
94
const head = { tag: "head" };
95
const body = { tag: "body" };
96
const title = { tag: "title", text: "My Page" };
97
const h1 = { tag: "h1", text: "Welcome" };
98
const p = { tag: "p", text: "Hello world" };
99
100
// Build the tree structure
101
tree.appendChild(html, head);
102
tree.appendChild(html, body);
103
tree.appendChild(head, title);
104
tree.appendChild(body, h1);
105
tree.appendChild(body, p);
106
107
console.log(tree.firstChild(html) === head); // true
108
console.log(tree.lastChild(body) === p); // true
109
```
110
111
### Manipulating Tree Structure
112
113
```javascript
114
const tree = new SymbolTree();
115
116
const parent = { name: "parent" };
117
const child1 = { name: "child1" };
118
const child2 = { name: "child2" };
119
const child3 = { name: "child3" };
120
121
// Add children in order
122
tree.appendChild(parent, child2);
123
tree.prependChild(parent, child1); // child1 is now first
124
tree.insertAfter(child2, child3); // child3 comes after child2
125
126
// Final order: child1 -> child2 -> child3
127
let current = tree.firstChild(parent);
128
while (current) {
129
console.log(current.name);
130
current = tree.nextSibling(current);
131
}
132
// Output: child1, child2, child3
133
134
// Rearrange - move child3 to the beginning
135
tree.remove(child3);
136
tree.prependChild(parent, child3);
137
138
// New order: child3 -> child1 -> child2
139
```
140
141
### Building Linked Lists
142
143
```javascript
144
const tree = new SymbolTree();
145
146
// Create nodes
147
const nodes = [
148
{ id: 1, value: "first" },
149
{ id: 2, value: "second" },
150
{ id: 3, value: "third" },
151
{ id: 4, value: "fourth" }
152
];
153
154
// Build linked list using insertAfter
155
let current = nodes[0];
156
for (let i = 1; i < nodes.length; i++) {
157
tree.insertAfter(current, nodes[i]);
158
current = nodes[i];
159
}
160
161
// Or build using insertBefore
162
const moreNodes = [
163
{ id: 5, value: "fifth" },
164
{ id: 6, value: "sixth" }
165
];
166
167
tree.insertBefore(nodes[0], moreNodes[1]); // sixth -> first -> ...
168
tree.insertBefore(moreNodes[1], moreNodes[0]); // fifth -> sixth -> first -> ...
169
```
170
171
### Dynamic Tree Operations
172
173
```javascript
174
const tree = new SymbolTree();
175
176
function createNode(name, children = []) {
177
const node = { name };
178
179
for (const childName of children) {
180
const child = createNode(childName);
181
tree.appendChild(node, child);
182
}
183
184
return node;
185
}
186
187
// Create initial tree
188
const root = createNode("root", ["branch1", "branch2"]);
189
190
// Add more nodes dynamically
191
const newBranch = createNode("branch3", ["leaf1", "leaf2"]);
192
tree.appendChild(root, newBranch);
193
194
// Insert between existing branches
195
const middleBranch = createNode("branch1.5");
196
const branch2 = tree.lastChild(tree.firstChild(root)); // Navigate to branch2
197
tree.insertBefore(branch2, middleBranch);
198
199
// Remove and reorganize
200
const branch1 = tree.firstChild(root);
201
tree.remove(branch1);
202
tree.prependChild(newBranch, branch1); // Move branch1 under branch3
203
```
204
205
## Error Handling
206
207
All insertion methods will throw an `Error` if the object being inserted is already present in the tree:
208
209
```javascript
210
const tree = new SymbolTree();
211
const parent = { name: "parent" };
212
const child = { name: "child" };
213
214
tree.appendChild(parent, child);
215
216
try {
217
// This will throw an error
218
tree.appendChild(parent, child);
219
} catch (error) {
220
console.log(error.message);
221
// "Given object is already present in this SymbolTree, remove it first"
222
}
223
224
// To move an object, remove it first
225
tree.remove(child);
226
tree.prependChild(parent, child); // Now this works
227
```