This commit is contained in:
Ingy döt Net 2013-10-27 22:24:23 +00:00
commit 776bba907c
3887 changed files with 59896 additions and 7282 deletions

View file

@ -1,21 +1,21 @@
import std.stdio;
import std.stdio, std.traits;
const class Node(T) {
const final class Node(T) {
T data;
Node left, right;
this(in T data, in Node left=null, in Node right=null)
pure nothrow {
const pure nothrow {
this.data = data;
this.left = left;
this.right = right;
}
}
// static templated opCall can't be used in Node
// 'static' templated opCall can't be used in Node
auto node(T)(in T data, in Node!T left=null, in Node!T right=null)
pure nothrow {
return new Node!T(data, left, right);
return new const(Node!T)(data, left, right);
}
void show(T)(in T x) {
@ -24,15 +24,12 @@ void show(T)(in T x) {
enum Visit { pre, inv, post }
// visitor can be any kind of callable or it uses a default visitor.
// 'visitor' can be any kind of callable or it uses a default visitor.
// TNode can be any kind of Node, with data, left and right fields,
// so this is more generic than a member function of Node.
void backtrackingOrder(Visit v, TNode, TyF=void*)
(in TNode node, TyF visitor=null) {
static if (is(TyF == void*))
auto trueVisitor = &show!(typeof(node.data));
else
auto trueVisitor = visitor;
alias trueVisitor = Select!(is(TyF == void*), show, visitor);
if (node !is null) {
static if (v == Visit.pre)
trueVisitor(node.data);
@ -48,37 +45,34 @@ void backtrackingOrder(Visit v, TNode, TyF=void*)
void levelOrder(TNode, TyF=void*)
(TNode node, TyF visitor=null,
const(TNode)[] more=[]) {
static if (is(TyF == void*))
auto trueVisitor = &show!(typeof(node.data));
else
auto trueVisitor = visitor;
alias trueVisitor = Select!(is(TyF == void*), show, visitor);
if (node !is null) {
more ~= [node.left, node.right];
trueVisitor(node.data);
}
if (more.length)
levelOrder(more[0], trueVisitor, more[1 .. $]);
levelOrder(more[0], visitor, more[1 .. $]);
}
void main() {
alias node N;
auto tree = N(1,
N(2,
N(4,
N(7)),
N(5)),
N(3,
N(6,
N(8),
N(9))));
alias N = node;
const tree = N(1,
N(2,
N(4,
N(7)),
N(5)),
N(3,
N(6,
N(8),
N(9))));
write(" preOrder: ");
backtrackingOrder!(Visit.pre)(tree);
tree.backtrackingOrder!(Visit.pre);
write("\n inorder: ");
backtrackingOrder!(Visit.inv)(tree);
tree.backtrackingOrder!(Visit.inv);
write("\n postOrder: ");
backtrackingOrder!(Visit.post)(tree);
tree.backtrackingOrder!(Visit.post);
write("\nlevelorder: ");
levelOrder(tree);
writeln();
tree.levelOrder;
writeln;
}

View file

@ -0,0 +1,80 @@
:- object(tree_traversal).
:- public(orders/1).
orders(Tree) :-
write('Pre-order: '), pre_order(Tree), nl,
write('In-order: '), in_order(Tree), nl,
write('Post-order: '), post_order(Tree), nl,
write('Level-order: '), level_order(Tree).
:- public(orders/0).
orders :-
tree(Tree),
orders(Tree).
tree(
t(1,
t(2,
t(4,
t(7, t, t),
t
),
t(5, t, t)
),
t(3,
t(6,
t(8, t, t),
t(9, t, t)
),
t
)
)
).
pre_order(t).
pre_order(t(Value, Left, Right)) :-
write(Value), write(' '),
pre_order(Left),
pre_order(Right).
in_order(t).
in_order(t(Value, Left, Right)) :-
in_order(Left),
write(Value), write(' '),
in_order(Right).
post_order(t).
post_order(t(Value, Left, Right)) :-
post_order(Left),
post_order(Right),
write(Value), write(' ').
level_order(t).
level_order(t(Value, Left, Right)) :-
% write tree root value
write(Value), write(' '),
% write rest of the tree
level_order([Left, Right], Tail-Tail).
level_order([], Trees-[]) :-
( Trees \= [] ->
% print next level
level_order(Trees, Tail-Tail)
; % no more levels
true
).
level_order([Tree| Trees], Rest0) :-
( Tree = t(Value, Left, Right) ->
write(Value), write(' '),
% collect the subtrees to print the next level
append(Rest0, [Left, Right| Tail]-Tail, Rest1),
% continue printing the current level
level_order(Trees, Rest1)
; % continue printing the current level
level_order(Trees, Rest0)
).
% use difference-lists for constant time append
append(List1-Tail1, Tail1-Tail2, List1-Tail2).
:- end_object.

View file

@ -0,0 +1,6 @@
| ?- ?- tree_traversal::orders.
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
yes

View file

@ -0,0 +1,25 @@
#lang racket
(define the-tree ; Node: (list <data> <left> <right>)
'(1 (2 (4 (7 #f #f) #f) (5 #f #f)) (3 (6 (8 #f #f) (9 #f #f)) #f)))
(define (preorder tree visit)
(let loop ([t tree])
(when t (visit (car t)) (loop (cadr t)) (loop (caddr t)))))
(define (inorder tree visit)
(let loop ([t tree])
(when t (loop (cadr t)) (visit (car t)) (loop (caddr t)))))
(define (postorder tree visit)
(let loop ([t tree])
(when t (loop (cadr t)) (loop (caddr t)) (visit (car t)))))
(define (levelorder tree visit)
(let loop ([trees (list tree)])
(unless (null? trees)
((compose1 loop (curry filter values) append*)
(for/list ([t trees] #:when t) (visit (car t)) (cdr t))))))
(define (run order)
(printf "~a:" (object-name order))
(order the-tree (λ(x) (printf " ~s" x)))
(newline))
(for-each run (list preorder inorder postorder levelorder))