2016 Update

This commit is contained in:
Tina Müller 2016-12-05 22:15:40 +01:00
parent 948b86eafa
commit dcf5d15da3
7965 changed files with 139854 additions and 31002 deletions

View file

@ -1,4 +1,12 @@
Implement a binary tree where each node carries an integer, and implement preoder, inorder, postorder and level-order [[wp:Tree traversal|traversal]]. Use those traversals to output the following tree:
;Task:
Implement a binary tree where each node carries an integer,   and implement:
:::*   pre-order,
:::*   in-order,
:::*   post-order,     and
:::*   level-order   [[wp:Tree traversal|traversal]].
Use those traversals to output the following tree:
1
/ \
/ \
@ -15,4 +23,7 @@ The correct output should look like this:
postorder: 7 4 5 2 8 9 6 3 1
level-order: 1 2 3 4 5 6 7 8 9
[[wp:Tree traversal|This article]] has more information on traversing trees.
;See also:
*   Wikipedia article:   [[wp:Tree traversal|Tree traversal]].
<br><br>

View file

@ -0,0 +1,88 @@
on run
set tree to {1, {2, {4, {7}, {}}, {5}}, {3, {6, {8}, {9}}, {}}}
return {|pre-order|:¬
traverse("pre-order", tree), |in-order|:¬
traverse("in-order", tree), |post-order|:¬
traverse("post-order", tree), |level-order|:¬
traverse("level-order", tree)}
end run
-- traverse :: String -> Tree -> [Int]
on traverse(strOrderName, tree)
if strOrderName does not start with "level" then
set {v, l, r} to nodeParts(tree)
if l is {} then
set lstLeft to []
else
set lstLeft to traverse(strOrderName, l)
end if
if r is {} then
set lstRight to []
else
set lstRight to traverse(strOrderName, r)
end if
-- PRE-ORDER
if strOrderName begins with "pre" then
v & lstLeft & lstRight
-- IN-ORDER
else if strOrderName begins with "in" then
lstLeft & v & lstRight
-- POST-ORDER
else if strOrderName begins with "post" then
lstLeft & lstRight & v
end if
else
-- LEVEL-ORDER
levelOrder({tree})
end if
end traverse
-- levelOrder :: [Tree] -> [Int]
on levelOrder(lstTree)
if length of lstTree > 0 then
set {head, tail} to uncons(lstTree)
-- Take any value found in the head node
-- deferring any child nodes to the end of the tail
-- before recursing
if head is not {} then
set {v, l, r} to nodeParts(head)
v & levelOrder(tail & {l, r})
else
levelOrder(tail)
end if
else
{}
end if
end levelOrder
-- nodeParts :: Tree -> (Int, Tree, Tree)
on nodeParts(tree)
if class of tree is list and length of tree = 3 then
tree
else
{tree} & {{}, {}}
end if
end nodeParts
-- GENERIC
-- uncons :: [a] -> Maybe (a, [a])
on uncons(xs)
if length of xs > 0 then
{item 1 of xs, rest of xs}
else
missing value
end if
end uncons

View file

@ -0,0 +1,4 @@
{|pre-order|:{1, 2, 4, 7, 5, 3, 6, 8, 9},
|in-order|:{7, 4, 2, 5, 1, 8, 6, 9, 3},
|post-order|:{7, 4, 5, 2, 8, 9, 6, 3, 1},
|level-order|:{1, 2, 3, 4, 5, 6, 7, 8, 9}}

View file

@ -0,0 +1,56 @@
defmodule Tree_Traversal do
defp tnode, do: {}
defp tnode(v), do: {:node, v, {}, {}}
defp tnode(v,l,r), do: {:node, v, l, r}
defp preorder(_,{}), do: :ok
defp preorder(f,{:node,v,l,r}) do
f.(v)
preorder(f,l)
preorder(f,r)
end
defp inorder(_,{}), do: :ok
defp inorder(f,{:node,v,l,r}) do
inorder(f,l)
f.(v)
inorder(f,r)
end
defp postorder(_,{}), do: :ok
defp postorder(f,{:node,v,l,r}) do
postorder(f,l)
postorder(f,r)
f.(v)
end
defp levelorder(_, []), do: []
defp levelorder(f, [{}|t]), do: levelorder(f, t)
defp levelorder(f, [{:node,v,l,r}|t]) do
f.(v)
levelorder(f, t++[l,r])
end
defp levelorder(f, x), do: levelorder(f, [x])
def main do
tree = tnode(1,
tnode(2,
tnode(4, tnode(7), tnode()),
tnode(5, tnode(), tnode())),
tnode(3,
tnode(6, tnode(8), tnode(9)),
tnode()))
f = fn x -> IO.write "#{x} " end
IO.write "preorder: "
preorder(f, tree)
IO.write "\ninorder: "
inorder(f, tree)
IO.write "\npostorder: "
postorder(f, tree)
IO.write "\nlevelorder: "
levelorder(f, tree)
IO.puts ""
end
end
Tree_Traversal.main

View file

@ -0,0 +1,5 @@
IF (STYLE.EQ."PRE") CALL OUT(HAS)
IF (LINKL(HAS).GT.0) CALL TARZAN(LINKL(HAS),STYLE)
IF (STYLE.EQ."IN") CALL OUT(HAS)
IF (LINKR(HAS).GT.0) CALL TARZAN(LINKR(HAS),STYLE)
IF (STYLE.EQ."POST") CALL OUT(HAS)

View file

@ -0,0 +1,3 @@
DO GASP = 1,MAXLEVEL
CALL TARZAN(1,HOW)
END DO

View file

@ -0,0 +1,202 @@
MODULE ARAUCARIA !Cunning crosswords, also.
INTEGER ENUFF !To suit the set example.
PARAMETER (ENUFF = 9) !This will do.
INTEGER NODE(ENUFF),LINKL(ENUFF),LINKR(ENUFF) !The nodes, and their links.
DATA NODE/ 1,2,3,4,5,6,7,8,9/ !Value = index. A rather boring payload.
DATA LINKL/2,4,6,7,0,8,0,0,0/ !"Left" and "Right" are as looking at the page.
DATA LINKR/3,5,0,0,0,9,0,0,0/ !If one thinks within the tree, they're the other way around!
C 1 !Thus, looking from the "1", to the right is "2" and to the left is "3".
C / \ !But, looking at the scheme, to the left is "2" and to the right is "3".
C / \ !This latter seems to be the popular view from the outside, not within the data.
C / \ !Similarily, although called a "tree", the depiction is upside down!
C 2 3 !How can computers be expected to keep up with this contrariness?
C / \ / !Humm, no example of a rightwards link with no leftwards link.
C 4 5 6 !Topologically equivalent, but not so in usage.
C / / \
C 7 8 9
INTEGER N,LIST(ENUFF) !This is to be developed.
INTEGER LEVEL,MAXLEVEL !While these vary in various ways.
INTEGER GASP !Communication from JANE.
CONTAINS !No checks for invalid links, etc.
SUBROUTINE OUT(IS) !Append a value to a list.
INTEGER IS !The value.
N = N + 1 !The list's count so far.
LIST(N) = IS !Place.
END SUBROUTINE OUT !Eventually, the list can be written in one go.
RECURSIVE SUBROUTINE TARZAN(HAS,STYLE) !Skilled at tree traversal, is he.
INTEGER HAS !The current position.
CHARACTER*(*) STYLE !Traversal type.
LEVEL = LEVEL + 1 !A leap is made.
IF (LEVEL.GT.MAXLEVEL) MAXLEVEL = LEVEL !Staring at the moon.
SELECT CASE(STYLE) !And, in what manner?
CASE ("PRE") !Declare the position first.
CALL OUT(HAS) !Thus.
IF (LINKL(HAS).GT.0) CALL TARZAN(LINKL(HAS),STYLE)
IF (LINKR(HAS).GT.0) CALL TARZAN(LINKR(HAS),STYLE)
CASE ("IN") !Or in the middle.
IF (LINKL(HAS).GT.0) CALL TARZAN(LINKL(HAS),STYLE)
CALL OUT(HAS) !Thus.
IF (LINKR(HAS).GT.0) CALL TARZAN(LINKR(HAS),STYLE)
CASE ("POST") !Or at the end.
IF (LINKL(HAS).GT.0) CALL TARZAN(LINKL(HAS),STYLE)
IF (LINKR(HAS).GT.0) CALL TARZAN(LINKR(HAS),STYLE)
CALL OUT(HAS) !Thus.
CASE ("LEVEL") !Or at specified levels.
IF (LEVEL.EQ.GASP) CALL OUT(HAS) !Such as this?
IF (LINKL(HAS).GT.0) CALL TARZAN(LINKL(HAS),STYLE)
IF (LINKR(HAS).GT.0) CALL TARZAN(LINKR(HAS),STYLE)
CASE DEFAULT !This shouldn't happen.
WRITE (6,*) "Unknown style ",STYLE !But, paranoia.
STOP "No can do!" !Rather than flounder about.
END SELECT !That was simple.
LEVEL = LEVEL - 1 !Sag back.
END SUBROUTINE TARZAN !Not like George of the Jungle.
SUBROUTINE JANE(HOW) !Tells Tarzan what to do.
CHARACTER*(*) HOW !A single word suffices.
N = 0 !No positions trampled.
LEVEL = 0 !Starting on the ground.
MAXLEVEL = 0 !The ascent follows.
IF (HOW.NE."LEVEL") THEN !Ordinary styles?
CALL TARZAN(1,HOW) !Yes. From the root, go...
ELSE !But this is not tree-structured.
GASP = 0 !Instead, we ascend through the canopy in stages.
1 GASP = GASP + 1 !Up one stage.
CALL TARZAN(1,HOW) !And do it all again.
IF (GASP.LT.MAXLEVEL) GO TO 1 !Are we there yet?
END IF !Don't know MAXLEVEL until after the first clamber.
Cast forth the list.
WRITE (6,10) HOW,NODE(LIST(1:N)) !Show spoor.
10 FORMAT (A6,"-order:",66(1X,I0)) !Large enough.
WRITE (6,*) !Sigh.
END SUBROUTINE JANE !That was simple.
END MODULE ARAUCARIA !The monkeys are puzzled.
PROGRAM GORILLA !No fancy stuff. Just brute force.
USE ARAUCARIA !This is for lightweight but cunning monkeys.
INTEGER IT !A finger.
INTEGER SP,STACK(ENUFF) !The tree may be slim.
INTEGER SLEVL(ENUFF) !So prepare for maximum usage.
INTEGER MIST(ENUFF,0:ENUFF) !Multiple lists.
Chase the links preorder style: name the node, delve its left link, delve its right link.
N = 0 !No nodes have been visited.
SP = 0 !My stack is empty.
IT = 1 !I start at the root.
10 N = N + 1 !Another node arrived at.
LIST(N) = IT !Finger it.
IF (LINKL(IT).GT.0) THEN !A left link?
IF (LINKR(IT).GT.0) THEN !Yes. A right link also?
SP = SP + 1 !Yes. Stack it up.
STACK(SP) = LINKR(IT) !For later investigation.
END IF !So much for the right link.
IT = LINKL(IT) !Fingered by the left link.
GO TO 10 !See what happens.
END IF !But if there is no left link,
IF (LINKR(IT).GT.0) THEN !There still might be a right link.
IT = LINKR(IT) !There is.
GO TO 10 !See what happens.
END IF !And if there are no links,
IF (SP.GT.0) THEN !Perhaps the stack has bottomed out too?
IT = STACK(SP) !No, this was deferred.
SP = SP - 1 !So, pick up where we left off.
GO TO 10 !And carry on.
END IF !So much for unstacking.
WRITE (6,12) "Preorder",NODE(LIST(1:N)) !I've got a little list!
12 FORMAT (A12,":",66(1X,I0))
CALL JANE("PRE") !Try it fancy style.
Chase the links inorder style: delve left fully, name the node and try its right, then unstack.
N = 0 !No nodes have been visited.
SP = 0 !My stack is empty.
IT = 1 !I start at the root.
20 SP = SP + 1 !I'm on the way down.
STACK(SP) = IT !So, save this position to later retreat to.
IF (LINKL(IT).GT.0) THEN !Can I delve further left?
IT = LINKL(IT) !Yes.
GO TO 20 !And see what happens.
END IF !So much for diving.
21 IF (SP.GT.0) THEN !Can I retreat?
IT = STACK(SP) !Yes.
SP = SP - 1 !Go back to whence I had delved left.
N = N + 1 !This now counts as a place in order.
LIST(N) = IT !So list it.
IF (LINKR(IT).GT.0) THEN!Have I a rightwards path?
IT = LINKR(IT) !Yes. Take it.
GO TO 20 !And delve therefrom.
END IF !This node is now finished with.
GO TO 21 !So, try for another retreat.
END IF !So much for unstacking.
WRITE (6,12) "Inorder",NODE(LIST(1:N)) !I've got a little list!
CALL JANE("IN") !Try with more style.
Chase the links postorder style: delve left fully, delve right, name the node, then unstack.
N = 0 !No nodes have been visited.
SP = 0 !My stack is empty.
IT = 1 !I start at the root.
30 SP = SP + 1 !Action follows delving,
STACK(SP) = IT !So this node will be returned to.
IF (LINKL(IT).GT.0) THEN !Take any leftwards link straightaway.
IT = LINKL(IT) !Thus.
GO TO 30 !Thanks to the stack, we'll return to IT (as was).
END IF !But if there is no leftwards link to follow,
IF (LINKR(IT).GT.0) THEN !Perhaps there is a rightwards one?
STACK(SP) = -STACK(SP) !=-IT Mark the stacked finger as a rightwards lurch!
IT = LINKR(IT) !The rightwards link is now to be taken.
GO TO 30 !Thus start on a sub-tree.
END IF !But if there is no rightwards link either,
31 IF (SP.GT.0) THEN !See if there is anywhere to retreat to.
IT = STACK(SP) !The same IT placed at 30 if we dropped into 31.
SP = SP - 1 !But now we're in a different mood.
IF (IT.LT.0) THEN !Returning to what had been a rightwards departure?
N = N + 1 !Yes! Then this node is post-interest.
LIST(N) = -IT !So, time to roll it forth at last.
GO TO 31 !And retreat some more.
END IF !But if we hadn't gone right from IT,
IF (LINKR(IT).LE.0) THEN!We had gone left.
N = N + 1 !And now there is nowhere rightwards.
LIST(N) = IT !So this node is post-interest.
GO TO 31 !And retreat some more.
END IF !But if there is a rightwards leap,
SP = SP + 1 !Prepare to return to it,
STACK(SP) = -IT !Marked as having gone rightwards.
IT = LINKR(IT) !The rightwards move.
GO TO 30 !Peruse a fresh sub-tree.
END IF !And if the stack is reduced,
WRITE (6,12) "Postorder",NODE(LIST(1:N)) !Results!
CALL JANE("POST") !The same again?
Chase the nodes level style.
SP = 0 !My stack is empty.
IT = 1 !I start at the root.
LEVEL = 0 !On the ground.
MAXLEVEL = 0 !No ascent as yet.
MIST(:,0) = 0 !At all levels, nothing.
40 LEVEL = LEVEL + 1 !Every arrival is one level up.
IF (LEVEL.GT.MAXLEVEL) MAXLEVEL = LEVEL !Note the most high.
MIST(LEVEL,0) = MIST(LEVEL,0) + 1 !The count at that level.
MIST(LEVEL,MIST(LEVEL,0)) = IT !Add to the level's list.
IF (LINKL(IT).GT.0) THEN !Righto, can we go left?
IF (LINKR(IT).GT.0) THEN !Yes. Rightwards as well?
SP = SP + 1 !Yes! This will have to wait.
STACK(SP) = LINKR(IT) !So remember it,
SLEVL(SP) = LEVEL !And what level we're at now.
END IF !I can only go one way at a time.
IT = LINKL(IT) !Accept the fingered leftwards lurch.
GO TO 40 !Go to IT.
END IF !But if there is no leftwards link,
IF (LINKR(IT).GT.0) THEN !Perhaps there is a rightwards one?
IT = LINKR(IT) !There is.
GO TO 40 !Go to IT.
END IF !And if there are no further links,
IF (SP.GT.0) THEN !Perhaps we can retreat to what was deferred.
IT = STACK(SP) !The finger.
LEVEL = SLEVL(SP) !The level.
SP = SP - 1 !Wind back the stack.
GO TO 40 !Go to IT.
END IF !So much for the stack.
WRITE (6,12) "Levelorder", !Roll the lists in ascending LEVEL order.
1 (NODE(MIST(LEVEL,1:MIST(LEVEL,0))), LEVEL = 1,MAXLEVEL)
CALL JANE("LEVEL") !Alternatively...
END !So much for that.

View file

@ -0,0 +1,121 @@
(function () {
'use strict';
// 'preorder' | 'inorder' | 'postorder' | 'level-order'
// traverse :: String -> Tree {value: a, nest: [Tree]} -> [a]
function traverse(strOrderName, dctTree) {
var strName = strOrderName.toLowerCase();
if (strName.startsWith('level')) {
// LEVEL-ORDER
return levelOrder([dctTree]);
} else if (strName.startsWith('in')) {
var lstNest = dctTree.nest;
if ((lstNest ? lstNest.length : 0) < 3) {
var left = lstNest[0] || [],
right = lstNest[1] || [],
lstLeft = left.nest ? (
traverse(strName, left)
) : (left.value || []),
lstRight = right.nest ? (
traverse(strName, right)
) : (right.value || []);
return (lstLeft !== undefined && lstRight !== undefined) ?
// IN-ORDER
(lstLeft instanceof Array ? lstLeft : [lstLeft])
.concat(dctTree.value)
.concat(lstRight) : undefined;
} else { // in-order only defined here for binary trees
return undefined;
}
} else {
var lstTraversed = concatMap(function (x) {
return traverse(strName, x);
}, (dctTree.nest || []));
return (
strName.startsWith('pre') ? (
// PRE-ORDER
[dctTree.value].concat(lstTraversed)
) : strName.startsWith('post') ? (
// POST-ORDER
lstTraversed.concat(dctTree.value)
) : []
);
}
}
// levelOrder :: [Tree {value: a, nest: [Tree]}] -> [a]
function levelOrder(lstTree) {
var lngTree = lstTree.length,
head = lngTree ? lstTree[0] : undefined,
tail = lstTree.slice(1);
// Recursively take any value found in the head node
// of the remaining tail, deferring any child nodes
// of that head to the end of the tail
return lngTree ? (
head ? (
[head.value].concat(
levelOrder(
tail
.concat(head.nest || [])
)
)
) : levelOrder(tail)
) : [];
}
// concatMap :: (a -> [b]) -> [a] -> [b]
function concatMap(f, xs) {
return [].concat.apply([], xs.map(f));
}
var dctTree = {
value: 1,
nest: [{
value: 2,
nest: [{
value: 4,
nest: [{
value: 7
}]
}, {
value: 5
}]
}, {
value: 3,
nest: [{
value: 6,
nest: [{
value: 8
}, {
value: 9
}]
}]
}]
};
return ['preorder', 'inorder', 'postorder', 'level-order']
.reduce(function (a, k) {
return (
a[k] = traverse(k, dctTree),
a
);
}, {});
})();

View file

@ -0,0 +1,4 @@
{"preorder":[1, 2, 4, 7, 5, 3, 6, 8, 9],
"inorder":[7, 4, 2, 5, 1, 8, 6, 9, 3],
"postorder":[7, 4, 5, 2, 8, 9, 6, 3, 1],
"level-order":[1, 2, 3, 4, 5, 6, 7, 8, 9]}

View file

@ -0,0 +1,67 @@
data class Node(val v: Int, var left: Node? = null, var right: Node? = null) {
override fun toString() = "$v"
}
fun preOrder(n: Node?) {
n?.let {
print("$n ")
preOrder(n.left)
preOrder(n.right)
}
}
fun inorder(n: Node?) {
n?.let {
inorder(n.left)
print("$n ")
inorder(n.right)
}
}
fun postOrder(n: Node?) {
n?.let {
postOrder(n.left)
postOrder(n.right)
print("$n ")
}
}
fun levelOrder(n: Node?) {
n?.let {
val queue = mutableListOf(n)
while (queue.isNotEmpty()) {
val node = queue.removeAt(0)
print("$node ")
node.left?.let { queue.add(it) }
node.right?.let { queue.add(it) }
}
}
}
inline fun exec(name: String, n: Node?, f: (Node?) -> Unit) {
print(name)
f(n)
println()
}
fun main(args: Array<String>) {
val nodes = Array(10) { Node(it) }
nodes[1].left = nodes[2]
nodes[1].right = nodes[3]
nodes[2].left = nodes[4]
nodes[2].right = nodes[5]
nodes[4].left = nodes[7]
nodes[3].left = nodes[6]
nodes[6].left = nodes[8]
nodes[6].right = nodes[9]
exec(" preOrder: ", nodes[1], ::preOrder)
exec(" inorder: ", nodes[1], ::inorder)
exec(" postOrder: ", nodes[1], ::postOrder)
exec("level-order: ", nodes[1], ::levelOrder)
}

View file

@ -0,0 +1,42 @@
data class Node(val v: Int, var left: Node? = null, var right: Node? = null) {
override fun toString() = " $v"
fun preOrder() { print(this); left?.preOrder(); right?.preOrder() }
fun inorder() { left?.inorder(); print(this); right?.inorder() }
fun postOrder() { left?.postOrder(); right?.postOrder(); print(this) }
fun levelOrder() = with(mutableListOf(this)) {
do {
val node = removeAt(0)
print(node)
node.left?.let { add(it) }
node.right?.let { add(it) }
} while (any())
}
inline fun exec(name: String, f: (Node) -> Unit) {
print(name)
f(this)
println()
}
}
fun main(args: Array<String>) {
val nodes = Array(10) { Node(it) }
nodes[1].left = nodes[2]
nodes[1].right = nodes[3]
nodes[2].left = nodes[4]
nodes[2].right = nodes[5]
nodes[4].left = nodes[7]
nodes[3].left = nodes[6]
nodes[6].left = nodes[8]
nodes[6].right = nodes[9]
with(nodes[1]) {
exec(" preOrder:", Node::preOrder)
exec(" inorder:", Node::inorder)
exec(" postOrder:", Node::postOrder)
exec("level-order:", Node::levelOrder)
}
}

View file

@ -5,7 +5,7 @@ class TreeNode {
has $.value;
method pre-order {
gather {
flat gather {
take $.value;
take $.left.pre-order if $.left;
take $.right.pre-order if $.right
@ -13,7 +13,7 @@ class TreeNode {
}
method in-order {
gather {
flat gather {
take $.left.in-order if $.left;
take $.value;
take $.right.in-order if $.right;
@ -21,7 +21,7 @@ class TreeNode {
}
method post-order {
gather {
flat gather {
take $.left.post-order if $.left;
take $.right.post-order if $.right;
take $.value;
@ -30,7 +30,7 @@ class TreeNode {
method level-order {
my TreeNode @queue = (self);
gather while @queue.elems {
flat gather while @queue.elems {
my $n = @queue.shift;
take $n.value;
@queue.push($n.left) if $n.left;

View file

@ -0,0 +1,175 @@
#![feature(box_syntax, box_patterns)]
use std::collections::VecDeque;
#[derive(Debug)]
struct TreeNode<T> {
value: T,
left: Option<Box<TreeNode<T>>>,
right: Option<Box<TreeNode<T>>>,
}
enum TraversalMethod {
PreOrder,
InOrder,
PostOrder,
LevelOrder,
}
impl<T> TreeNode<T> {
pub fn new(arr: &[[i8; 3]]) -> TreeNode<i8> {
let l = match arr[0][1] {
-1 => None,
i @ _ => Some(Box::new(TreeNode::<i8>::new(&arr[(i - arr[0][0]) as usize..]))),
};
let r = match arr[0][2] {
-1 => None,
i @ _ => Some(Box::new(TreeNode::<i8>::new(&arr[(i - arr[0][0]) as usize..]))),
};
TreeNode {
value: arr[0][0],
left: l,
right: r,
}
}
pub fn traverse(&self, tr: &TraversalMethod) -> Vec<&TreeNode<T>> {
match tr {
&TraversalMethod::PreOrder => self.iterative_preorder(),
&TraversalMethod::InOrder => self.iterative_inorder(),
&TraversalMethod::PostOrder => self.iterative_postorder(),
&TraversalMethod::LevelOrder => self.iterative_levelorder(),
}
}
fn iterative_preorder(&self) -> Vec<&TreeNode<T>> {
let mut stack: Vec<&TreeNode<T>> = Vec::new();
let mut res: Vec<&TreeNode<T>> = Vec::new();
stack.push(self);
while !stack.is_empty() {
let node = stack.pop().unwrap();
res.push(node);
match node.right {
None => {}
Some(box ref n) => stack.push(n),
}
match node.left {
None => {}
Some(box ref n) => stack.push(n),
}
}
res
}
// Leftmost to rightmost
fn iterative_inorder(&self) -> Vec<&TreeNode<T>> {
let mut stack: Vec<&TreeNode<T>> = Vec::new();
let mut res: Vec<&TreeNode<T>> = Vec::new();
let mut p = self;
loop {
// Stack parents and right children while left-descending
loop {
match p.right {
None => {}
Some(box ref n) => stack.push(n),
}
stack.push(p);
match p.left {
None => break,
Some(box ref n) => p = n,
}
}
// Visit the nodes with no right child
p = stack.pop().unwrap();
while !stack.is_empty() && p.right.is_none() {
res.push(p);
p = stack.pop().unwrap();
}
// First node that can potentially have a right child:
res.push(p);
if stack.is_empty() {
break;
} else {
p = stack.pop().unwrap();
}
}
res
}
// Left-to-right postorder is same sequence as right-to-left preorder, reversed
fn iterative_postorder(&self) -> Vec<&TreeNode<T>> {
let mut stack: Vec<&TreeNode<T>> = Vec::new();
let mut res: Vec<&TreeNode<T>> = Vec::new();
stack.push(self);
while !stack.is_empty() {
let node = stack.pop().unwrap();
res.push(node);
match node.left {
None => {}
Some(box ref n) => stack.push(n),
}
match node.right {
None => {}
Some(box ref n) => stack.push(n),
}
}
let rev_iter = res.iter().rev();
let mut rev: Vec<&TreeNode<T>> = Vec::new();
for elem in rev_iter {
rev.push(elem);
}
rev
}
fn iterative_levelorder(&self) -> Vec<&TreeNode<T>> {
let mut queue: VecDeque<&TreeNode<T>> = VecDeque::new();
let mut res: Vec<&TreeNode<T>> = Vec::new();
queue.push_back(self);
while !queue.is_empty() {
let node = queue.pop_front().unwrap();
res.push(node);
match node.left {
None => {}
Some(box ref n) => queue.push_back(n),
}
match node.right {
None => {}
Some(box ref n) => queue.push_back(n),
}
}
res
}
}
fn main() {
// Array representation of task tree
let arr_tree = [[1, 2, 3],
[2, 4, 5],
[3, 6, -1],
[4, 7, -1],
[5, -1, -1],
[6, 8, 9],
[7, -1, -1],
[8, -1, -1],
[9, -1, -1]];
let root = TreeNode::<i8>::new(&arr_tree);
for method_label in [(TraversalMethod::PreOrder, "pre-order:"),
(TraversalMethod::InOrder, "in-order:"),
(TraversalMethod::PostOrder, "post-order:"),
(TraversalMethod::LevelOrder, "level-order:")]
.iter() {
print!("{}\t", method_label.1);
for n in root.traverse(&method_label.0) {
print!(" {}", n.value);
}
print!("\n");
}
}