use crate::tree::*;
use crate::node::*;
pub struct IterInterface<'a, T: NodeContent> {
tree: &'a Tree<T>
}
impl<'a, T: NodeContent> IterInterface<'a, T> {
pub fn new(tree: &'a Tree<T>) -> Self {
IterInterface { tree }
}
pub fn sequential(&self) -> SequentialIter<'a, T> {
SequentialIter::new(self.tree)
}
pub fn inv_sequential(&self) -> InvSequentialIter<'a, T> {
InvSequentialIter::new(self.tree)
}
pub fn bfs(&self) -> BfsIter<'a, T> {
BfsIter::new(self.tree)
}
pub fn inv_bfs(&self) -> InvBfsIter<'a, T> {
InvBfsIter::new(self.tree)
}
pub fn pre_dfs(&self) -> PreDfsIter<'a, T> {
PreDfsIter::new(self.tree)
}
pub fn inv_pre_dfs(&self) -> InvPreDfsIter<'a, T> {
InvPreDfsIter::new(self.tree)
}
pub fn post_dfs(&self) -> PostDfsIter<'a, T> {
PostDfsIter::new(self.tree)
}
pub fn inv_post_dfs(&self) -> InvPostDfsIter<'a, T> {
InvPostDfsIter::new(self.tree)
}
}
pub struct SequentialIter<'a, T: NodeContent> {
tree: &'a Tree<T>,
position: usize
}
impl<'a, T: NodeContent> SequentialIter<'a, T> {
pub fn new(tree: &'a Tree<T>) -> Self {
Self {
tree,
position: 0
}
}
}
impl<'a, T: NodeContent> Iterator for SequentialIter<'a, T> {
type Item = (&'a Node<T>, usize);
fn next(&mut self) -> Option<Self::Item> {
let position = self.position;
match &self.tree.get_nodes_ref().get(self.position) {
Some(node) => {
self.position += 1;
Some((node, position))
},
None => None
}
}
}
pub struct InvSequentialIter<'a, T: NodeContent> {
tree: &'a Tree<T>,
position: usize,
finished: bool
}
impl<'a, T: NodeContent> InvSequentialIter<'a, T> {
pub fn new(tree: &'a Tree<T>) -> Self {
if tree.get_nodes_len() > 0 {
Self {
tree,
position: tree.get_nodes_len() - 1,
finished: false
}
}
else {
Self {
tree,
position: 0,
finished: true
}
}
}
}
impl<'a, 'b, T: NodeContent> Iterator for InvSequentialIter<'a, T> {
type Item = (&'a Node<T>, usize);
fn next(&mut self) -> Option<Self::Item> {
if self.finished {
return None;
}
let position = self.position;
match &self.tree.get_nodes_ref().get(self.position) {
Some(node) => {
if self.position > 0 {
self.position -= 1;
}
else {
self.finished = true;
}
Some((node, position))
},
None => None
}
}
}
pub struct BfsIter<'a, T: NodeContent> {
tree: &'a Tree<T>,
cua: Vec<usize>,
next: usize,
finished: bool
}
impl<'a, T: NodeContent> BfsIter<'a, T> {
pub fn new(tree: &'a Tree<T>) -> Self {
Self {
tree,
cua: vec!(),
next: 0,
finished: false
}
}
}
impl<'a, T: NodeContent> Iterator for BfsIter<'a, T> {
type Item = (&'a Node<T>, usize);
fn next(&mut self) -> Option<Self::Item> {
if self.finished {
return None;
}
let position = self.next;
if let Some(node) = self.tree.get_nodes_ref().get(position) {
for child in node.get_children_ref().iter() {
self.cua.push(*child);
}
if self.cua.len() > 0 {
self.next = self.cua.remove(0);
}
else {
self.finished = true;
}
Some((node, position))
}
else {
None
}
}
}
pub struct InvBfsIter<'a, T: NodeContent> {
tree: &'a Tree<T>,
cua: Vec<usize>,
next: usize,
finished: bool
}
impl<'a, T: NodeContent> InvBfsIter<'a, T> {
pub fn new(tree: &'a Tree<T>) -> Self {
Self {
tree,
cua: vec!(),
next: 0,
finished: false
}
}
}
impl<'a, T: NodeContent> Iterator for InvBfsIter<'a, T> {
type Item = (&'a Node<T>, usize);
fn next(&mut self) -> Option<Self::Item> {
if self.finished {
return None;
}
let position = self.next;
if let Some(node) = self.tree.get_nodes_ref().get(position) {
for child in node.get_children_ref().iter().rev() {
self.cua.push(*child);
}
if self.cua.len() > 0 {
self.next = self.cua.remove(0);
}
else {
self.finished = true;
}
Some((node, position))
}
else {
None
}
}
}
pub struct PreDfsIter<'a, T: NodeContent> {
tree: &'a Tree<T>,
pila: Vec<usize>,
next: usize,
finished: bool
}
impl<'a, T: NodeContent> PreDfsIter<'a, T> {
pub fn new(tree: &'a Tree<T>) -> Self {
Self {
tree,
pila: vec!(),
next: 0,
finished: false
}
}
}
impl<'a, T: NodeContent> Iterator for PreDfsIter<'a, T> {
type Item = (&'a Node<T>, usize);
fn next(&mut self) -> Option<Self::Item> {
if self.finished {
return None;
}
let position = self.next;
if let Some(node) = self.tree.get_nodes_ref().get(position) {
for child in node.get_children_ref().iter().rev() {
self.pila.push(*child);
}
if let Some(next_node_index) = self.pila.pop() {
self.next = next_node_index;
}
else {
self.finished = true;
}
Some((node, position))
}
else {
None
}
}
}
pub struct InvPreDfsIter<'a, T: NodeContent> {
tree: &'a Tree<T>,
pila: Vec<usize>,
next: usize,
finished: bool
}
impl<'a, T: NodeContent> InvPreDfsIter<'a, T> {
pub fn new(tree: &'a Tree<T>) -> Self {
Self {
tree,
pila: vec!(),
next: 0,
finished: false
}
}
}
impl<'a, T: NodeContent> Iterator for InvPreDfsIter<'a, T> {
type Item = (&'a Node<T>, usize);
fn next(&mut self) -> Option<Self::Item> {
if self.finished {
return None;
}
let position = self.next;
if let Some(node) = self.tree.get_nodes_ref().get(position) {
for child in node.get_children_ref().iter() {
self.pila.push(*child);
}
if let Some(next_node_index) = self.pila.pop() {
self.next = next_node_index;
}
else {
self.finished = true;
}
Some((node, position))
}
else {
None
}
}
}
pub struct PostDfsIter<'a, T: NodeContent> {
tree: &'a Tree<T>,
pila: Vec<(usize, bool)>
}
impl<'a, T: NodeContent> PostDfsIter<'a, T> {
pub fn new(tree: &'a Tree<T>) -> Self {
Self {
tree,
pila: vec!((0, true))
}
}
}
impl<'a, T: NodeContent> Iterator for PostDfsIter<'a, T> {
type Item = (&'a Node<T>, usize);
fn next(&mut self) -> Option<Self::Item> {
if let Some(next_node_tuple) = self.pila.pop() {
let next = next_node_tuple.0;
let push_children = next_node_tuple.1;
let position = next;
if let Some(node) = self.tree.get_nodes_ref().get(position) {
if !push_children {
return Some((node, position));
}
if node.get_children_ref().len() > 0 {
self.pila.push((next, false));
for child in node.get_children_ref().iter().rev() {
self.pila.push((*child, true));
}
return self.next();
}
else {
return Some((node, position));
}
}
else {
return None;
}
}
None
}
}
pub struct InvPostDfsIter<'a, T: NodeContent> {
tree: &'a Tree<T>,
pila: Vec<(usize, bool)>
}
impl<'a, T: NodeContent> InvPostDfsIter<'a, T> {
pub fn new(tree: &'a Tree<T>) -> Self {
Self {
tree,
pila: vec!((0, true))
}
}
}
impl<'a, T: NodeContent> Iterator for InvPostDfsIter<'a, T> {
type Item = (&'a Node<T>, usize);
fn next(&mut self) -> Option<Self::Item> {
if let Some(next_node_tuple) = self.pila.pop() {
let next = next_node_tuple.0;
let push_children = next_node_tuple.1;
let position = next;
if let Some(node) = self.tree.get_nodes_ref().get(position) {
if !push_children {
return Some((node, position));
}
if node.get_children_ref().len() > 0 {
self.pila.push((next, false));
for child in node.get_children_ref().iter() {
self.pila.push((*child, true));
}
return self.next();
}
else {
return Some((node, position));
}
}
else {
return None;
}
}
None
}
}