Skip to content

Commit 3bae00b

Browse files
committed
Add remove_node method
1 parent f4532bf commit 3bae00b

File tree

2 files changed

+74
-10
lines changed

2 files changed

+74
-10
lines changed

src/lib.rs

Lines changed: 49 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,9 @@ pub struct WalkSiblings<Ix: IndexType> {
8585
maybe_walk_children: Option<WalkChildren<Ix>>,
8686
}
8787

88+
/// `RoseTree`'s API ensures that it always has a "root" node and that its index is always 0.
89+
pub const ROOT: usize = 0;
90+
8891

8992
impl<N, Ix = DefIndex> RoseTree<N, Ix> where Ix: IndexType {
9093

@@ -107,16 +110,6 @@ impl<N, Ix = DefIndex> RoseTree<N, Ix> where Ix: IndexType {
107110
self.graph.node_count()
108111
}
109112

110-
/// Remove all nodes in the `RoseTree` except for the root.
111-
pub fn remove_all_but_root(&mut self) {
112-
// We can assume that the `root`'s index is zero, as it is always the first node to be
113-
// added to the RoseTree.
114-
if let Some(root) = self.graph.remove_node(NodeIndex::new(0)) {
115-
self.graph.clear();
116-
self.graph.add_node(root);
117-
}
118-
}
119-
120113
/// Borrow the `RoseTree`'s underlying `PetGraph<N, Ix>`.
121114
/// All existing `NodeIndex`s may be used to index into this graph the same way they may be
122115
/// used to index into the `RoseTree`.
@@ -163,6 +156,52 @@ impl<N, Ix = DefIndex> RoseTree<N, Ix> where Ix: IndexType {
163156
self.graph.index_twice_mut(a, b)
164157
}
165158

159+
/// Remove all nodes in the `RoseTree` except for the root.
160+
pub fn remove_all_but_root(&mut self) {
161+
// We can assume that the `root`'s index is zero, as it is always the first node to be
162+
// added to the RoseTree.
163+
if let Some(root) = self.graph.remove_node(NodeIndex::new(0)) {
164+
self.graph.clear();
165+
self.graph.add_node(root);
166+
}
167+
}
168+
169+
/// Removes and returns the node at the given index.
170+
///
171+
/// The parent of `node` will become the new parent for all of its children.
172+
///
173+
/// The root node cannot be removed. If its index is given, `None` will be returned.
174+
///
175+
/// Note: this method may shift other node indices, invalidating previously returned indices!
176+
pub fn remove_node(&mut self, node: NodeIndex<Ix>) -> Option<N> {
177+
178+
// Check if an attempt to remove the root node has been made.
179+
if node.index() == ROOT || self.graph.node_weight(node).is_none() {
180+
return None;
181+
}
182+
183+
// Now that we know we're not the root node, we know that we **must** have some parent.
184+
let parent = self.parent(node).expect("No parent node found");
185+
186+
// For each of `node`'s children, set their parent to `node`'s parent.
187+
let mut children = self.graph.walk_edges_directed(node, pg::Outgoing);
188+
while let Some((child_edge, child_node)) = children.next_neighbor(&self.graph) {
189+
self.graph.remove_edge(child_edge);
190+
self.graph.add_edge(parent, child_node, ());
191+
}
192+
193+
// Finally, remove our node and return it.
194+
self.graph.remove_node(node)
195+
}
196+
197+
/// Removes the node at the given index along with all their children, returning them as a new
198+
/// RoseTree.
199+
///
200+
/// If there was no node at the given index, `None` will be returned.
201+
pub fn remove_node_with_children(&mut self, _node: NodeIndex<Ix>) -> Option<RoseTree<N, Ix>> {
202+
unimplemented!();
203+
}
204+
166205
/// An index to the parent of the node at the given index if there is one.
167206
pub fn parent(&self, child: NodeIndex<Ix>) -> Option<NodeIndex<Ix>> {
168207
self.graph.neighbors_directed(child, pg::Incoming).next()

tests/remove.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
2+
extern crate rose_tree;
3+
4+
use rose_tree::RoseTree;
5+
6+
7+
#[test]
8+
fn remove_node() {
9+
10+
let (mut tree, root) = RoseTree::<u32, u32>::new(0);
11+
let a = tree.add_child(root, 1);
12+
let _b = tree.add_child(a, 2);
13+
let _c = tree.add_child(a, 3);
14+
let _d = tree.add_child(a, 4);
15+
16+
assert_eq!(Some(1), tree.remove_node(a));
17+
18+
let mut children = tree.children(root);
19+
assert_eq!(Some(2), children.next().map(|idx| tree[idx]));
20+
assert_eq!(Some(3), children.next().map(|idx| tree[idx]));
21+
assert_eq!(Some(4), children.next().map(|idx| tree[idx]));
22+
assert_eq!(None, children.next());
23+
}
24+
25+

0 commit comments

Comments
 (0)