Skip to main content

csc_7b_fc/
avlnavigator.rs

1//! ## AVL Tree Navigator Module.
2//! A "tree navigator" is similar in concept to an interator. It works by
3//! keeping a "current" node and a stack of "ancestors" along
4//! with whether current is on the left or right of the ancestor.
5//! With this information we can navigate to any part of tree.
6//! Only immutable operations on the tree are permitted with a navigator.
7//! Example:
8//! ```
9//!   fn f<'lt, T:Ord>(tree:&'lt Bst<T>, key:&T) -> Option<&'lt T> {
10//!     let mut navigator = AVLNavigator::start(tree);
11//!     navigator.seek(key);
12//!     navigator.goto_predecessor();
13//!     navigator.current_item()
14//!   }
15//! ```
16//!
17use crate::avltree::Bst::*;
18use crate::avltree::*;
19use crate::avlmap::KVPair;
20
21/// Structure for a Tree Navigator
22#[derive(Clone)]
23pub struct AVLNavigator<'lt,T> {
24  ancestors : Vec<(&'lt Bst<T>,bool)>,  // bool true = left, false = right;
25  current : &'lt Bst<T>,
26}
27impl<'lt,T:Ord> AVLNavigator<'lt,T> {
28
29  /// creates a new navigator with given tree, which could be empty,
30  /// the current "pointer".
31  pub fn start(tree: &'lt Bst<T>) -> Self {
32    AVLNavigator {ancestors:Vec::new(), current:tree}
33  }
34
35  /// returns the current node (or Empty)
36  pub fn get_current(&self) -> &'lt Bst<T> { 
37     self.current
38  }
39  /// alias for [Self::get_current]
40  pub fn now(&self) -> &'lt Bst<T> { 
41     self.current
42  }  
43
44  /// Navigate to the left child.  If there is no left child,
45  /// the navigator stays at the same point.  Returns true on
46  /// successful navigation
47  pub fn go_left(&mut self) -> bool {
48     let mut answer = false;
49     if let Node(cell) = self.current {
50       let left = &cell.left;
51       if let Node(_) = left {
52         answer = true;
53         self.ancestors.push((self.current,true));
54         self.current = left;
55       }
56     }
57     answer
58  }
59
60  /// Navigate to the right child.  If there is no right child,
61  /// the navigator stays at the same point and the function returns false.
62  pub fn go_right(&mut self) -> bool {
63     let mut answer = false;     
64     if let Node(cell) = self.current {
65       let right = &cell.right;
66       if let Node(_) = right {
67         answer = true;
68         self.ancestors.push((self.current,false));
69         self.current = right;
70       }       
71     }
72     answer
73  }
74
75  /// Attempts to navigate to the parent node.  If there is no parent,
76  /// however, the navigator stays at the same point. Returns true on
77  /// successful navigation
78  pub fn go_up(&mut self) -> bool {
79    let mut answer = false;
80    let parent = self.ancestors.pop();
81    parent.map(|(p,_)|{self.current=p; answer=true;});
82    answer
83  }
84
85  /// alias for [Self::go_up]
86  pub fn goto_parent(&mut self) -> bool { self.go_up() } //alias
87
88  /// Navigate to the successor node, or stay at the same node if the successor
89  /// doesn't exist. The successor is either the leftmost child of the
90  /// right subtree, or, if the right subtree does not exist, the
91  /// closest ancestor that the current node is to the left of.
92  pub fn goto_successor(&mut self) -> bool {
93    let mut answer = false;
94    if let Node(cell) = self.current {
95      if let Node(_) = &cell.right {
96        answer = true;
97        self.go_right();
98        self.goto_leftmost();
99      }// successor on right subtree
100      else {
101        let mut i = self.ancestors.len();
102        while i>0 {
103          let ((ancestor,dir)) = self.ancestors[i-1];
104          if dir {
105            answer = true;
106            self.current = ancestor;
107            self.ancestors.truncate(i-1);
108            break;
109          }          
110          i -= 1;
111        }
112      } // successor is closest "left" ancestor
113    }
114    answer
115  }//goto_successor
116
117  /// Navigate to the predecessor node, or stay at the same node if the 
118  /// predecessor doesn't exist and the function returns false.
119  pub fn goto_predecessor(&mut self) -> bool {
120    let mut answer = false;
121    if let Node(cell) = self.current {
122      if let Node(_) = &cell.left {
123        answer = true;
124        self.go_left();
125        self.goto_rightmost();
126      }
127      else {
128        let mut i = self.ancestors.len();
129        while i>0 {
130          let ((ancestor,dir)) = self.ancestors[i-1];
131          if !dir {
132            answer = true;
133            self.current = ancestor;
134            self.ancestors.truncate(i-1);
135            break;
136          }          
137          i -= 1;
138        }//while
139      }
140    }
141    answer
142  }//goto_successor
143
144  /// Navigate back to the starting node of the navigator, returns true
145  /// on successful navigation.
146  pub fn goto_root(&mut self) -> bool {
147    if self.ancestors.len()>0 {
148      self.current = self.ancestors[0].0;
149      self.ancestors.clear();
150      true
151    }
152    else {false}
153  }
154
155  /// returns the value inside the current node, if it exists
156  pub fn current_item(&self) -> Option<&'lt T> {
157    self.get_current().get_item()
158  }
159
160  /// Navigate to the node sharing the same parent as the current node,
161  /// returning false if there is no sibling.
162  pub fn goto_sibling(&mut self) -> bool {
163    let mut answer = false;
164    if self.ancestors.len()==0 { return false; }
165    let (parent,dir) = self.ancestors[self.ancestors.len()-1];
166    let sibling =  if dir { parent.get_right() } else { parent.get_left() };
167    if let Node(_) = sibling {
168      answer = true;
169      self.current = sibling;      
170    }
171    answer
172  }
173
174  /// Navigate to sibling of parent
175  pub fn goto_aunt(&mut self) -> bool {
176    if (self.goto_parent()) {
177      self.goto_sibling()
178    }
179    else {false}
180  }
181  /// Navigate to sibling of parent
182  pub fn goto_uncle(&mut self) -> bool { self.goto_aunt() }
183
184  /// go to right most node (containing maximum vaule) of current subtree
185  pub fn goto_rightmost(&mut self) -> bool {
186     if let Empty = self.current { return false; }
187     while let Node(_) = self.current.get_right() {
188       self.go_right();
189     }
190     true
191  }
192
193  /// go to the node containing the minimum value (leftmost node)
194  pub fn goto_leftmost(&mut self) -> bool {
195     if let Empty = self.current { return false; }     
196     while let Node(_) = self.current.get_left() {
197       self.go_left();
198     }
199     true
200  }
201
202  /// Search for node containing the given key starting from the current node.
203  /// Returns true on success. If the key is not found, the navigator is
204  /// restored to its previous state.
205  pub fn seek(&mut self, key:&T) -> bool {
206    let mut answer = false;
207    let savelen = self.ancestors.len();
208    let savecurrent = self.current;
209    while let Node(cell) = self.current {
210      if key == &cell.item {
211         answer = true;
212         break;
213      }
214      else if key < &cell.item { //go left
215        self.ancestors.push((self.current,true));
216        self.current = &cell.left
217      }
218      else {
219        self.ancestors.push((self.current,false));      
220        self.current = &cell.right;
221      }
222    }//while
223    if !answer { // restore navigator
224      self.ancestors.truncate(savelen);
225      self.current = savecurrent;
226    }
227    answer
228  }//goto_item
229
230}// impl AVLNavigator
231
232impl<'lt,T:Ord> Bst<T> {
233  /// returns a [AVLNavigator] starting at the current tree
234  pub fn new_navigator(&'lt self) -> AVLNavigator<'lt,T> {
235    AVLNavigator::start(self)
236  }
237}
238
239impl<'lt,T:Ord> AVLSet<T> {
240  /// returns a [AVLNavigator] starting at the root
241  pub fn get_navigator(&'lt self) -> AVLNavigator<'lt,T> {
242    AVLNavigator::start(&self.root)
243  }
244}
245
246impl<'lt,KT:Ord,VT> AVLNavigator<'lt,KVPair<KT,VT>> {
247pub fn seek_key(&mut self, key:&KT) -> bool {
248    let mut answer = false;
249    let savelen = self.ancestors.len();
250    let savecurrent = self.current;
251    while let Node(cell) = self.current {
252      if key == &cell.item.key {
253         answer = true;
254         break;
255      }
256      else if key < &cell.item.key { //go left
257        self.ancestors.push((self.current,true));
258        self.current = &cell.left
259      }
260      else {
261        self.ancestors.push((self.current,false));      
262        self.current = &cell.right;
263      }
264    }//while
265    if !answer { // restore navigator
266      self.ancestors.truncate(savelen);
267      self.current = savecurrent;
268    }
269    answer
270  }//seek
271}
272
273// sample function that uses navigator
274fn f<'lt, T:Ord>(tree:&'lt Bst<T>, key:&T) -> Option<&'lt T> {
275  let mut navigator = AVLNavigator::start(tree);
276  navigator.seek(key);
277  navigator.goto_predecessor();
278  navigator.current_item()
279}