2016 Update
This commit is contained in:
parent
948b86eafa
commit
dcf5d15da3
7965 changed files with 139854 additions and 31002 deletions
|
|
@ -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>
|
||||
|
|
|
|||
88
Task/Tree-traversal/AppleScript/tree-traversal-1.applescript
Normal file
88
Task/Tree-traversal/AppleScript/tree-traversal-1.applescript
Normal 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
|
||||
|
|
@ -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}}
|
||||
56
Task/Tree-traversal/Elixir/tree-traversal.elixir
Normal file
56
Task/Tree-traversal/Elixir/tree-traversal.elixir
Normal 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
|
||||
5
Task/Tree-traversal/Fortran/tree-traversal-1.f
Normal file
5
Task/Tree-traversal/Fortran/tree-traversal-1.f
Normal 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)
|
||||
3
Task/Tree-traversal/Fortran/tree-traversal-2.f
Normal file
3
Task/Tree-traversal/Fortran/tree-traversal-2.f
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
DO GASP = 1,MAXLEVEL
|
||||
CALL TARZAN(1,HOW)
|
||||
END DO
|
||||
202
Task/Tree-traversal/Fortran/tree-traversal-3.f
Normal file
202
Task/Tree-traversal/Fortran/tree-traversal-3.f
Normal 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.
|
||||
121
Task/Tree-traversal/JavaScript/tree-traversal-4.js
Normal file
121
Task/Tree-traversal/JavaScript/tree-traversal-4.js
Normal 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
|
||||
);
|
||||
}, {});
|
||||
|
||||
})();
|
||||
4
Task/Tree-traversal/JavaScript/tree-traversal-5.js
Normal file
4
Task/Tree-traversal/JavaScript/tree-traversal-5.js
Normal 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]}
|
||||
67
Task/Tree-traversal/Kotlin/tree-traversal-1.kotlin
Normal file
67
Task/Tree-traversal/Kotlin/tree-traversal-1.kotlin
Normal 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)
|
||||
}
|
||||
42
Task/Tree-traversal/Kotlin/tree-traversal-2.kotlin
Normal file
42
Task/Tree-traversal/Kotlin/tree-traversal-2.kotlin
Normal 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)
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
175
Task/Tree-traversal/Rust/tree-traversal.rust
Normal file
175
Task/Tree-traversal/Rust/tree-traversal.rust
Normal 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");
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue