Data commit

This commit is contained in:
Ingy döt Net 2023-07-01 11:58:00 -04:00
parent 7387c8f97b
commit cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions

View file

@ -0,0 +1,5 @@
---
category:
- Recursion
from: http://rosettacode.org/wiki/Tree_traversal
note: Data Structures

View file

@ -0,0 +1,29 @@
;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
/ \
/ \
/ \
2 3
/ \ /
4 5 6
/ / \
7 8 9
The correct output should look like this:
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
;See also:
*   Wikipedia article:   [[wp:Tree traversal|Tree traversal]].
<br><br>

View file

@ -0,0 +1,72 @@
T Node
Int data
Node? left
Node? right
F (data, Node? left = N, Node? right = N)
.data = data
.left = left
.right = right
F preorder(visitor) -> N
visitor(.data)
I .left != N
.left.preorder(visitor)
I .right != N
.right.preorder(visitor)
F inorder(visitor) -> N
I .left != N
.left.inorder(visitor)
visitor(.data)
I .right != N
.right.inorder(visitor)
F postorder(visitor) -> N
I .left != N
.left.postorder(visitor)
I .right != N
.right.postorder(visitor)
visitor(.data)
F preorder2(&d, level = 0) -> N
d[level].append(.data)
I .left != N
.left.preorder2(d, level + 1)
I .right != N
.right.preorder2(d, level + 1)
F levelorder(visitor)
DefaultDict[Int, [Int]] d
.preorder2(&d)
L(k) sorted(d.keys())
L(v) d[k]
visitor(v)
V tree = Node(1,
Node(2,
Node(4,
Node(7, N, N),
N),
Node(5, N, N)),
Node(3,
Node(6,
Node(8, N, N),
Node(9, N, N)),
N))
F printwithspace(Int i)
print(#. .format(i), end' )
print( preorder: , end' )
tree.preorder(printwithspace)
print()
print( inorder: , end' )
tree.inorder(printwithspace)
print()
print( postorder: , end' )
tree.postorder(printwithspace)
print()
print(levelorder: , end' )
tree.levelorder(printwithspace)
print()

View file

@ -0,0 +1,184 @@
org 100h
jmp demo
;;; Traverse tree at DE according to method at BC.
;;; Call routine at HL with DE=<value> for each value encounterd.
travrs: shld trvcb+1 ; Store routine pointer
xchg ; Tree in HL
push b ; Jump to method BC
ret
;;; Preorder traversal
preo: mov a,h
ora l
rz ; Null node = stop
mov e,m
inx h
mov d,m ; Load value
inx h
push h ; Handle value
call trvcb
pop h ; Left node
mov e,m
inx h
mov d,m
inx h
push h ; Save pointer
xchg
call preo
pop h
mov e,m
inx h ; Right node
mov d,m
xchg
jmp preo
;;; Inorder traversal
ino: mov a,h
ora l
rz ; Null node = stop
mov e,m
inx h
mov d,m ; Load value
inx h
push d ; Save value on stack
mov e,m
inx h
mov d,m
inx h ; Load left node
push h ; Save pointer on stack
xchg
call ino ; Traverse left node
pop h
pop d ; Get value
push h
call trvcb ; Handle value
pop h
mov e,m
inx h
mov d,m
xchg
jmp ino ; Traverse right node
;;; Postorder traversal
posto: mov a,h
ora l
rz ; Null node = stop
mov e,m
inx h
mov d,m ; Load value
inx h
push d ; Keep value on stack
mov e,m
inx h
mov d,m
inx h ; Load left node
push h
xchg
call posto ; Traverse left node
pop h
mov e,m
inx h
mov d,m ; Load right node
xchg
call posto ; Traverse right node
pop d ; Get value from stack
jmp trvcb ; Handle value
;;; Level-order traversal
lvlo: shld queue ; Store current node at beginning of queue
lxi h,queue ; HL = Queue start pointer
lxi b,queue+2 ; BC = Queue end pointer
lvllp: mov a,h ; When start == end, stop
cmp b
jnz lvlt ; Not equal
mov a,l
cmp c
rz ; Equal = stop
lvlt: mov e,m ; Load current node in DE
inx h
mov d,m
inx h
mov a,d ; Null node = ignore
ora e
jz lvllp
push h ; Keep queue start pointer
xchg ; HL = current node
mov e,m ; Load value into DE
inx h
mov d,m
inx h
push h ; Keep pointer to left and right nodes
push b ; And pointer to end of queue
call trvcb ; Handle value
pop b ; Restore pointer to end of queue
pop h ; Restore pointer to left and right nodes
mvi d,4 ; D = copy counter
lvlcp: mov a,m ; Copy left and right nodes to queue
stax b
inx h
inx b
dcr d
jnz lvlcp
pop h ; Restore queue stack pointer
jmp lvllp
trvcb: jmp 0 ; Callback pointer
;;; Run examples
demo: lhld 6 ; Move stack to top of memory
sphl
lxi h,0 ; So we can still RET out of the program
push h
lxi h,orders
order: mov e,m ; Get string
inx h
mov d,m
inx h
mov a,e ; 0 = done
ora d
rz
push h ; Print string
call print
pop h
mov c,m ; Load method in BC
inx h
mov b,m
inx h
push h
lxi d,tree ; Tree in DE
lxi h,cb ; Callback in HL
call travrs ; Traverse the tree
lxi d,nl
call print ; Newline
pop h ; Restore table pointer
jmp order
;;; Print the tree value. They're all <10 for the example, so we
;;; don't need multiple digits.
cb: mvi a,'0'
add e
sta nstr
lxi d,nstr
print: mvi c,9 ; CP/M print string call
jmp 5
nstr: db '* $'
nl: db 13,10,'$'
;;; Example tree
tree: dw 1, node2, node3
node2: dw 2, node4, node5
node3: dw 3, node6, 0
node4: dw 4, node7, 0
node5: dw 5, 0, 0
node6: dw 6, node8, node9
node7: dw 7, 0, 0
node8: dw 8, 0, 0
node9: dw 9, 0 ,0
;;; Table of names and orders
orders: dw spreo,preo
dw sino,ino
dw sposto,posto
dw slvlo,lvlo
dw 0
spreo: db 'Preorder: $'
sino: db 'Inorder: $'
sposto: db 'Postorder: $'
slvlo: db 'Level-order: $'
queue: equ $ ; Put level-order queue on heap

View file

@ -0,0 +1,114 @@
cpu 8086
org 100h
section .text
jmp demo
;;; Traverse tree at SI. Call routine at CX with values in AX.
;;; CX must preserve BX, CX, SI, DI.
;;; Preorder traversal
preo: test si,si
jz pdone ; Zero pointer = done
lodsw ; Load value
call cx ; Handle value
push si ; Keep value
mov si,[si] ; Load left node
call preo ; Traverse left node
pop si
mov si,[si+2] ; Load right node
jmp preo ; Traverse right node
;;; Inorder traversal
ino: test si,si
jz pdone ; Zero pointer = done
push si
mov si,[si+2] ; Load left node
call ino ; Traverse left node
pop si
lodsw ; Load value
call cx ; Handle value
mov si,[si+2] ; Load right node
jmp ino ; Traverse right node
;;; Postorder traversal
posto: test si,si
jz pdone ; Zero pointer = done
push si
mov si,[si+2] ; Load left node
call posto ; Traverse left node
pop si
push si
mov si,[si+4] ; Load right node
call posto
pop si ; Load value
lodsw
jmp cx ; Handle value
pdone: ret
;;; Level-order traversal
lvlo: mov di,queue ; DI = queue end pointer
mov ax,si
mov si,di ; SI = queue start pointer
stosw
.step: cmp di,si ; If end == start, done
je pdone
lodsw ; Get next item
test ax,ax ; Null?
jz .step
mov bx,si ; Keep start pointer in BX
mov si,ax ; Load item
lodsw ; Get value
call cx ; Handle value
lodsw ; Copy nodes to queue
stosw
lodsw
stosw
mov si,bx ; Put start pointer back
jmp .step
;;; Demo code
demo: mov si,orders
.loop: lodsw ; Load next order
test ax,ax
jz .done
mov dx,ax ; Print order name
mov ah,9
int 21h
lodsw ; Load order routine
mov bp,si ; Keep SI
mov si,tree ; Traverse the tree
mov cx,pdgt ; Printing the digits
call ax
mov si,bp
jmp .loop
.done: ret
;;; Callback: print single digit
pdgt: add al,'0'
mov [.str],al
mov ah,9
mov dx,.str
int 21h
ret
.str: db '* $'
section .data
;;; List of orders
orders: dw .preo,preo
dw .ino,ino
dw .posto,posto
dw .lvlo,lvlo
dw 0
.preo: db 'Preorder: $'
.ino: db 13,10,'Inorder: $'
.posto: db 13,10,'Postorder: $'
.lvlo: db 13,10,'Level-order: $'
;;; Exampe tree
tree: dw 1,.n2,.n3
.n2: dw 2,.n4,.n5
.n3: dw 3,.n6,0
.n4: dw 4,.n7,0
.n5: dw 5,0,0
.n6: dw 6,.n8,.n9
.n7: dw 7,0,0
.n8: dw 8,0,0
.n9: dw 9,0,0
section .bss
queue: resw 256

View file

@ -0,0 +1,387 @@
/* ARM assembly AARCH64 Raspberry PI 3B */
/* program deftree64.s */
/*******************************************/
/* Constantes file */
/*******************************************/
/* for this file see task include a file in language AArch64 assembly*/
.include "../includeConstantesARM64.inc"
.equ NBVAL, 9
/*******************************************/
/* Structures */
/********************************************/
/* structure tree */
.struct 0
tree_root: // root pointer
.struct tree_root + 8
tree_size: // number of element of tree
.struct tree_size + 8
tree_fin:
/* structure node tree */
.struct 0
node_left: // left pointer
.struct node_left + 8
node_right: // right pointer
.struct node_right + 8
node_value: // element value
.struct node_value + 8
node_fin:
/* structure queue*/
.struct 0
queue_begin: // next pointer
.struct queue_begin + 8
queue_end: // element value
.struct queue_end + 8
queue_fin:
/* structure node queue */
.struct 0
queue_node_next: // next pointer
.struct queue_node_next + 8
queue_node_value: // element value
.struct queue_node_value + 8
queue_node_fin:
/*******************************************/
/* Initialized data */
/*******************************************/
.data
szMessInOrder: .asciz "inOrder :\n"
szMessPreOrder: .asciz "PreOrder :\n"
szMessPostOrder: .asciz "PostOrder :\n"
szMessLevelOrder: .asciz "LevelOrder :\n"
szCarriageReturn: .asciz "\n"
/* datas error display */
szMessErreur: .asciz "Error detected.\n"
/* datas message display */
szMessResult: .ascii "Element value : @ \n"
/*******************************************/
/* UnInitialized data */
/*******************************************/
.bss
.align 4
sZoneConv: .skip 24
stTree: .skip tree_fin // place to structure tree
stQueue: .skip queue_fin // place to structure queue
/*******************************************/
/* code section */
/*******************************************/
.text
.global main
main:
mov x1,1 // node tree value
1:
ldr x0,qAdrstTree // structure tree address
bl insertElement // add element value x1
cmp x0,-1
beq 99f
add x1,x1,1 // increment value
cmp x1,NBVAL // end ?
ble 1b // no -> loop
ldr x0,qAdrszMessPreOrder
bl affichageMess
ldr x3,qAdrstTree // tree root address (begin structure)
ldr x0,[x3,#tree_root]
ldr x1,qAdrdisplayElement // function to execute
bl preOrder
ldr x0,qAdrszMessInOrder
bl affichageMess
ldr x3,qAdrstTree
ldr x0,[x3,#tree_root]
ldr x1,qAdrdisplayElement // function to execute
bl inOrder
ldr x0,qAdrszMessPostOrder
bl affichageMess
ldr x3,qAdrstTree
ldr x0,[x3,#tree_root]
ldr x1,qAdrdisplayElement // function to execute
bl postOrder
ldr x0,qAdrszMessLevelOrder
bl affichageMess
ldr x3,qAdrstTree
ldr x0,[x3,#tree_root]
ldr x1,qAdrdisplayElement // function to execute
bl levelOrder
b 100f
99: // display error
ldr x0,qAdrszMessErreur
bl affichageMess
100: // standard end of the program
mov x8,EXIT // request to exit program
svc 0 // perform system call
qAdrszMessInOrder: .quad szMessInOrder
qAdrszMessPreOrder: .quad szMessPreOrder
qAdrszMessPostOrder: .quad szMessPostOrder
qAdrszMessLevelOrder: .quad szMessLevelOrder
qAdrszMessErreur: .quad szMessErreur
qAdrszCarriageReturn: .quad szCarriageReturn
qAdrstTree: .quad stTree
qAdrstQueue: .quad stQueue
qAdrdisplayElement: .quad displayElement
/******************************************************************/
/* insert element in the tree */
/******************************************************************/
/* x0 contains the address of the tree structure */
/* x1 contains the value of element */
/* x0 returns address of element or - 1 if error */
insertElement:
stp x1,lr,[sp,-16]! // save registers
mov x4,x0
mov x0,node_fin // reservation place one element
bl allocHeap
cmp x0,-1 // allocation error
beq 100f
mov x5,x0
str x1,[x5,node_value] // store value in address heap
mov x1,0
str x1,[x5,node_left] // init left pointer with zero
str x1,[x5,node_right] // init right pointer with zero
ldr x2,[x4,tree_size] // load tree size
cbnz x2,1f // 0 element ?
str x5,[x4,tree_root] // yes -> store in root
b 6f
1: // else search free address in tree
ldr x3,[x4,tree_root] // start with address root
add x6,x2,1 // increment tree size
clz x7,x6 // compute zeroes left bits
add x7,x7,1 // for sustract the first left bit
lsl x6,x6,x7 // shift number in left
2:
tst x6,1<<63 // test left bit
lsl x6,x6,1 // shift left bit
bne 3f // bit at one
ldr x1,[x3,node_left] // no store node address in left pointer
cbz x1,4f // if equal zero
mov x3,x1 // else loop with next node
b 2b
3: // yes
ldr x1,[x3,node_right] // store node address in right pointer
cbz x1,5f // if equal zero
mov x3,x1 // else loop with next node
b 2b
4:
str x5,[x3,node_left]
b 6f
5:
str x5,[x3,node_right]
6:
add x2,x2,1 // increment tree size
str x2,[x4,tree_size]
100:
ldp x1,lr,[sp],16 // restaur 2 registers
ret // return to address lr x30
/******************************************************************/
/* preOrder */
/******************************************************************/
/* x0 contains the address of the node */
/* x1 function address */
preOrder:
stp x1,lr,[sp,-16]! // save registers
stp x2,x3,[sp,-16]! // save registers
cmp x0,#0
beq 100f
mov x2,x0
blr x1 // call function
ldr x0,[x2,#node_left]
bl preOrder
ldr x0,[x2,#node_right]
bl preOrder
100:
ldp x2,x3,[sp],16 // restaur 2 registers
ldp x1,lr,[sp],16 // restaur 2 registers
ret // return to address lr x30
/******************************************************************/
/* inOrder */
/******************************************************************/
/* x0 contains the address of the node */
/* x1 function address */
inOrder:
stp x1,lr,[sp,-16]! // save registers
stp x2,x3,[sp,-16]! // save registers
cbz x0,100f
mov x3,x0
mov x2,x1
ldr x0,[x3,node_left]
bl inOrder
mov x0,x3
blr x2 // call function
ldr x0,[x3,node_right]
mov x1,x2
bl inOrder
100:
ldp x2,x3,[sp],16 // restaur 2 registers
ldp x1,lr,[sp],16 // restaur 2 registers
ret // return to address lr x30
/******************************************************************/
/* postOrder */
/******************************************************************/
/* x0 contains the address of the node */
/* x1 function address */
postOrder:
stp x1,lr,[sp,-16]! // save registers
stp x2,x3,[sp,-16]! // save registers
cbz x0,100f
mov x3,x0
mov x2,x1
ldr x0,[x3,#node_left]
bl postOrder
ldr x0,[x3,#node_right]
mov x1,x2
bl postOrder
mov x0,x3
blr x2 // call function
100:
ldp x2,x3,[sp],16 // restaur 2 registers
ldp x1,lr,[sp],16 // restaur 2 registers
ret // return to address lr x30
/******************************************************************/
/* levelOrder */
/******************************************************************/
/* x0 contains the address of the node */
/* x1 function address */
levelOrder:
stp x1,lr,[sp,-16]! // save registers
stp x2,x3,[sp,-16]! // save registers
cbz x0,100f
mov x2,x1
mov x1,x0
ldr x0,qAdrstQueue // adresse queue
bl enqueueNode // queue the node
1: // begin loop
ldr x0,qAdrstQueue
bl isEmptyQueue // is queue empty
cbz x0,100f // yes -> end
ldr x0,qAdrstQueue
bl dequeueNode
mov x3,x0 // save node
blr x2 // call function
ldr x14,[x3,#node_left] // left node ok ?
cbz x14,2f
ldr x0,qAdrstQueue // yes -> enqueue
mov x1,x14
bl enqueueNode
2:
ldr x14,[x3,#node_right] // right node ok ?
cbz x14,3f
ldr x0,qAdrstQueue // yes -> enqueue
mov x1,x14
bl enqueueNode
3:
b 1b // and loop
100:
ldp x2,x3,[sp],16 // restaur 2 registers
ldp x1,lr,[sp],16 // restaur 2 registers
ret // return to address lr x30
/******************************************************************/
/* display node */
/******************************************************************/
/* x0 contains node address */
displayElement:
stp x1,lr,[sp,-16]! // save registers
ldr x0,[x0,#node_value]
ldr x1,qAdrsZoneConv
bl conversion10S
ldr x0,qAdrszMessResult
ldr x1,qAdrsZoneConv
bl strInsertAtCharInc // insert result at @ character
bl affichageMess
100:
ldp x1,lr,[sp],16 // restaur 2 registers
ret // return to address lr x30
qAdrszMessResult: .quad szMessResult
qAdrsZoneConv: .quad sZoneConv
/******************************************************************/
/* enqueue node */
/******************************************************************/
/* x0 contains the address of the queue */
/* x1 contains the value of element */
/* x0 returns address of element or - 1 if error */
enqueueNode:
stp x1,lr,[sp,-16]! // save registers
stp x2,x3,[sp,-16]! // save registers
mov x14,x0
mov x0,#queue_node_fin // allocation place heap
bl allocHeap
cmp x0,#-1 // allocation error
beq 100f
mov x15,x0 // save heap address
str x1,[x15,#queue_node_value] // store node value
mov x1,#0
str x1,[x15,#queue_node_next] // init pointer next
ldr x0,[x14,#queue_end]
cbz x0,1f
str x15,[x0,#queue_node_next]
b 2f
1:
str x15,[x14,#queue_begin]
2:
str x15,[x14,#queue_end]
mov x0,#0
100:
ldp x2,x3,[sp],16 // restaur 2 registers
ldp x1,lr,[sp],16 // restaur 2 registers
ret // return to address lr x30
/******************************************************************/
/* dequeue node */
/******************************************************************/
/* x0 contains the address of the queue */
/* x0 returns address of element or - 1 if error */
dequeueNode:
stp x1,lr,[sp,-16]! // save registers
ldr x14,[x0,#queue_begin]
ldr x15,[x14,#queue_node_value]
ldr x16,[x14,#queue_node_next]
str x16,[x0,#queue_begin]
cbnz x16,1f
str x16,[x0,#queue_end]
1:
mov x0,x15
100:
ldp x1,lr,[sp],16 // restaur 2 registers
ret // return to address lr x30
/******************************************************************/
/* dequeue node */
/******************************************************************/
/* x0 contains the address of the queue */
/* x0 returns 0 if empty else 1 */
isEmptyQueue:
ldr x0,[x0,#queue_begin]
cmp x0,#0
cset x0,ne
ret // return
/******************************************************************/
/* memory allocation on the heap */
/******************************************************************/
/* x0 contains the size to allocate */
/* x0 returns address of memory heap or - 1 if error */
/* CAUTION : The size of the allowance must be a multiple of 4 */
allocHeap:
stp x8,lr,[sp,-16]! // save registers
// allocation
mov x16,x0 // save size
mov x0,0 // read address start heap
mov x8,BRK // call system 'brk'
svc 0
mov x15,x0 // save address heap for return
add x0,x0,x16 // reservation place for size
mov x8,BRK // call system 'brk'
svc 0
cmp x0,-1 // allocation error
beq 100f
mov x0,x15 // return address memory heap
100:
ldp x8,lr,[sp],16 // restaur 2 registers
ret // return to address lr x30
/***********************************************/
/* File Include fonctions */
/********************************************************/
/* for this file see task include a file in language AArch64 assembly */
.include "../includeARM64.inc"

View file

@ -0,0 +1,47 @@
(defun flatten-preorder (tree)
(if (endp tree)
nil
(append (list (first tree))
(flatten-preorder (second tree))
(flatten-preorder (third tree)))))
(defun flatten-inorder (tree)
(if (endp tree)
nil
(append (flatten-inorder (second tree))
(list (first tree))
(flatten-inorder (third tree)))))
(defun flatten-postorder (tree)
(if (endp tree)
nil
(append (flatten-postorder (second tree))
(flatten-postorder (third tree))
(list (first tree)))))
(defun flatten-level-r1 (tree level levels)
(if (endp tree)
levels
(let ((curr (cdr (assoc level levels))))
(flatten-level-r1
(second tree)
(1+ level)
(flatten-level-r1
(third tree)
(1+ level)
(put-assoc level
(append curr (list (first tree)))
levels))))))
(defun flatten-level-r2 (levels max-level)
(declare (xargs :measure (nfix (1+ max-level))))
(if (zp (1+ max-level))
nil
(append (flatten-level-r2 levels
(1- max-level))
(reverse (cdr (assoc max-level levels))))))
(defun flatten-level (tree)
(let ((levels (flatten-level-r1 tree 0 nil)))
(flatten-level-r2 levels (len levels))))

View file

@ -0,0 +1,124 @@
MODE VALUE = INT;
PROC value repr = (VALUE value)STRING: whole(value, 0);
MODE NODES = STRUCT ( VALUE value, REF NODES left, right);
MODE NODE = REF NODES;
PROC tree = (VALUE value, NODE left, right)NODE:
HEAP NODES := (value, left, right);
PROC preorder = (NODE node, PROC (VALUE)VOID action)VOID:
IF node ISNT NODE(NIL) THEN
action(value OF node);
preorder(left OF node, action);
preorder(right OF node, action)
FI;
PROC inorder = (NODE node, PROC (VALUE)VOID action)VOID:
IF node ISNT NODE(NIL) THEN
inorder(left OF node, action);
action(value OF node);
inorder(right OF node, action)
FI;
PROC postorder = (NODE node, PROC (VALUE)VOID action)VOID:
IF node ISNT NODE(NIL) THEN
postorder(left OF node, action);
postorder(right OF node, action);
action(value OF node)
FI;
PROC destroy tree = (NODE node)VOID:
postorder(node, (VALUE skip)VOID:
# free(node) - PR garbage collect hint PR #
node := (SKIP, NIL, NIL)
);
# helper queue for level order #
MODE QNODES = STRUCT (REF QNODES next, NODE value);
MODE QNODE = REF QNODES;
MODE QUEUES = STRUCT (QNODE begin, end);
MODE QUEUE = REF QUEUES;
PROC enqueue = (QUEUE queue, NODE node)VOID:
(
HEAP QNODES qnode := (NIL, node);
IF end OF queue ISNT QNODE(NIL) THEN
next OF end OF queue
ELSE
begin OF queue
FI := end OF queue := qnode
);
PROC queue empty = (QUEUE queue)BOOL:
begin OF queue IS QNODE(NIL);
PROC dequeue = (QUEUE queue)NODE:
(
NODE out := value OF begin OF queue;
QNODE second := next OF begin OF queue;
# free(begin OF queue); PR garbage collect hint PR #
QNODE(begin OF queue) := (NIL, NIL);
begin OF queue := second;
IF queue empty(queue) THEN
end OF queue := begin OF queue
FI;
out
);
PROC level order = (NODE node, PROC (VALUE)VOID action)VOID:
(
HEAP QUEUES queue := (QNODE(NIL), QNODE(NIL));
enqueue(queue, node);
WHILE NOT queue empty(queue)
DO
NODE next := dequeue(queue);
IF next ISNT NODE(NIL) THEN
action(value OF next);
enqueue(queue, left OF next);
enqueue(queue, right OF next)
FI
OD
);
PROC print node = (VALUE value)VOID:
print((" ",value repr(value)));
main: (
NODE node := tree(1,
tree(2,
tree(4,
tree(7, NIL, NIL),
NIL),
tree(5, NIL, NIL)),
tree(3,
tree(6,
tree(8, NIL, NIL),
tree(9, NIL, NIL)),
NIL));
MODE TEST = STRUCT(
STRING name,
PROC(NODE,PROC(VALUE)VOID)VOID order
);
PROC test = (TEST test)VOID:(
STRING pad=" "*(12-UPB name OF test);
print((name OF test,pad,": "));
(order OF test)(node, print node);
print(new line)
);
[]TEST test list = (
("preorder",preorder),
("inorder",inorder),
("postorder",postorder),
("level order",level order)
);
FOR i TO UPB test list DO test(test list[i]) OD;
destroy tree(node)
)

View file

@ -0,0 +1,4 @@
preorder ? {l r?? ?? ? ? (?r)???(×?r)?(?l)???(×?l)?? ?? ?}
inorder ? {l r?? ?? ? ? (?r)???(×?r)?? ???(?l)???(×?l)??}
postorder? {l r?? ?? ? ? ? ???(?r)???(×?r)?(?l)???(×?l)??}
lvlorder ? {0=??:? ? (????/(??),??)??°(,/)?2??°??¨?}

View file

@ -0,0 +1,3 @@
tree?1(2(4(7??)?)(5??))(3(6(8??)(9??))?)
visit?{?,(×??)???}
children?{?¨@(×°?¨)1??}

View file

@ -0,0 +1,434 @@
/* ARM assembly Raspberry PI */
/* program deftree2.s */
/* Constantes */
.equ STDOUT, 1 @ Linux output console
.equ EXIT, 1 @ Linux syscall
.equ READ, 3
.equ WRITE, 4
.equ NBVAL, 9
/*******************************************/
/* Structures */
/********************************************/
/* structure tree */
.struct 0
tree_root: @ root pointer
.struct tree_root + 4
tree_size: @ number of element of tree
.struct tree_size + 4
tree_fin:
/* structure node tree */
.struct 0
node_left: @ left pointer
.struct node_left + 4
node_right: @ right pointer
.struct node_right + 4
node_value: @ element value
.struct node_value + 4
node_fin:
/* structure queue*/
.struct 0
queue_begin: @ next pointer
.struct queue_begin + 4
queue_end: @ element value
.struct queue_end + 4
queue_fin:
/* structure node queue */
.struct 0
queue_node_next: @ next pointer
.struct queue_node_next + 4
queue_node_value: @ element value
.struct queue_node_value + 4
queue_node_fin:
/* Initialized data */
.data
szMessInOrder: .asciz "inOrder :\n"
szMessPreOrder: .asciz "PreOrder :\n"
szMessPostOrder: .asciz "PostOrder :\n"
szMessLevelOrder: .asciz "LevelOrder :\n"
szCarriageReturn: .asciz "\n"
/* datas error display */
szMessErreur: .asciz "Error detected.\n"
/* datas message display */
szMessResult: .ascii "Element value :"
sValue: .space 12,' '
.asciz "\n"
/* UnInitialized data */
.bss
stTree: .skip tree_fin @ place to structure tree
stQueue: .skip queue_fin @ place to structure queue
/* code section */
.text
.global main
main:
mov r1,#1 @ node tree value
1:
ldr r0,iAdrstTree @ structure tree address
bl insertElement @ add element value r1
cmp r0,#-1
beq 99f
add r1,#1 @ increment value
cmp r1,#NBVAL @ end ?
ble 1b @ no -> loop
ldr r0,iAdrszMessPreOrder
bl affichageMess
ldr r3,iAdrstTree @ tree root address (begin structure)
ldr r0,[r3,#tree_root]
ldr r1,iAdrdisplayElement @ function to execute
bl preOrder
ldr r0,iAdrszMessInOrder
bl affichageMess
ldr r3,iAdrstTree
ldr r0,[r3,#tree_root]
ldr r1,iAdrdisplayElement @ function to execute
bl inOrder
ldr r0,iAdrszMessPostOrder
bl affichageMess
ldr r3,iAdrstTree
ldr r0,[r3,#tree_root]
ldr r1,iAdrdisplayElement @ function to execute
bl postOrder
ldr r0,iAdrszMessLevelOrder
bl affichageMess
ldr r3,iAdrstTree
ldr r0,[r3,#tree_root]
ldr r1,iAdrdisplayElement @ function to execute
bl levelOrder
b 100f
99: @ display error
ldr r0,iAdrszMessErreur
bl affichageMess
100: @ standard end of the program
mov r7, #EXIT @ request to exit program
svc 0 @ perform system call
iAdrszMessInOrder: .int szMessInOrder
iAdrszMessPreOrder: .int szMessPreOrder
iAdrszMessPostOrder: .int szMessPostOrder
iAdrszMessLevelOrder: .int szMessLevelOrder
iAdrszMessErreur: .int szMessErreur
iAdrszCarriageReturn: .int szCarriageReturn
iAdrstTree: .int stTree
iAdrstQueue: .int stQueue
iAdrdisplayElement: .int displayElement
/******************************************************************/
/* insert element in the tree */
/******************************************************************/
/* r0 contains the address of the tree structure */
/* r1 contains the value of element */
/* r0 returns address of element or - 1 if error */
insertElement:
push {r1-r7,lr} @ save registers
mov r4,r0
mov r0,#node_fin @ reservation place one element
bl allocHeap
cmp r0,#-1 @ allocation error
beq 100f
mov r5,r0
str r1,[r5,#node_value] @ store value in address heap
mov r1,#0
str r1,[r5,#node_left] @ init left pointer with zero
str r1,[r5,#node_right] @ init right pointer with zero
ldr r2,[r4,#tree_size] @ load tree size
cmp r2,#0 @ 0 element ?
bne 1f
str r5,[r4,#tree_root] @ yes -> store in root
b 4f
1: @ else search free address in tree
ldr r3,[r4,#tree_root] @ start with address root
add r6,r2,#1 @ increment tree size
clz r7,r6 @ compute zeroes left bits
add r7,#1 @ for sustract the first left bit
lsl r6,r7 @ shift number in left
2:
lsls r6,#1 @ read left bit
bcs 3f @ is 1 ?
ldr r1,[r3,#node_left] @ no store node address in left pointer
cmp r1,#0 @ if equal zero
streq r5,[r3,#node_left]
beq 4f
mov r3,r1 @ else loop with next node
b 2b
3: @ yes
ldr r1,[r3,#node_right] @ store node address in right pointer
cmp r1,#0 @ if equal zero
streq r5,[r3,#node_right]
beq 4f
mov r3,r1 @ else loop with next node
b 2b
4:
add r2,#1 @ increment tree size
str r2,[r4,#tree_size]
100:
pop {r1-r7,lr} @ restaur registers
bx lr @ return
/******************************************************************/
/* preOrder */
/******************************************************************/
/* r0 contains the address of the node */
/* r1 function address */
preOrder:
push {r1-r2,lr} @ save registers
cmp r0,#0
beq 100f
mov r2,r0
blx r1 @ call function
ldr r0,[r2,#node_left]
bl preOrder
ldr r0,[r2,#node_right]
bl preOrder
100:
pop {r1-r2,lr} @ restaur registers
bx lr
/******************************************************************/
/* inOrder */
/******************************************************************/
/* r0 contains the address of the node */
/* r1 function address */
inOrder:
push {r1-r3,lr} @ save registers
cmp r0,#0
beq 100f
mov r3,r0
mov r2,r1
ldr r0,[r3,#node_left]
bl inOrder
mov r0,r3
blx r2 @ call function
ldr r0,[r3,#node_right]
mov r1,r2
bl inOrder
100:
pop {r1-r3,lr} @ restaur registers
bx lr @ return
/******************************************************************/
/* postOrder */
/******************************************************************/
/* r0 contains the address of the node */
/* r1 function address */
postOrder:
push {r1-r3,lr} @ save registers
cmp r0,#0
beq 100f
mov r3,r0
mov r2,r1
ldr r0,[r3,#node_left]
bl postOrder
ldr r0,[r3,#node_right]
mov r1,r2
bl postOrder
mov r0,r3
blx r2 @ call function
100:
pop {r1-r3,lr} @ restaur registers
bx lr @ return
/******************************************************************/
/* levelOrder */
/******************************************************************/
/* r0 contains the address of the node */
/* r1 function address */
levelOrder:
push {r1-r4,lr} @ save registers
cmp r0,#0
beq 100f
mov r2,r1
mov r1,r0
ldr r0,iAdrstQueue @ adresse queue
bl enqueueNode @ queue the node
1: @ begin loop
ldr r0,iAdrstQueue
bl isEmptyQueue @ is queue empty
cmp r0,#0
beq 100f @ yes -> end
ldr r0,iAdrstQueue
bl dequeueNode
mov r3,r0 @ save node
blx r2 @ call function
ldr r4,[r3,#node_left] @ left node ok ?
cmp r4,#0
beq 2f @ no
ldr r0,iAdrstQueue @ yes -> enqueue
mov r1,r4
bl enqueueNode
2:
ldr r4,[r3,#node_right] @ right node ok ?
cmp r4,#0
beq 3f @ no
ldr r0,iAdrstQueue @ yes -> enqueue
mov r1,r4
bl enqueueNode
3:
b 1b @ and loop
100:
pop {r1-r4,lr} @ restaur registers
bx lr @ return
/******************************************************************/
/* display node */
/******************************************************************/
/* r0 contains node address */
displayElement:
push {r1,lr} @ save registers
ldr r0,[r0,#node_value]
ldr r1,iAdrsValue
bl conversion10S
ldr r0,iAdrszMessResult
bl affichageMess
100:
pop {r1,lr} @ restaur registers
bx lr @ return
iAdrszMessResult: .int szMessResult
iAdrsValue: .int sValue
/******************************************************************/
/* enqueue node */
/******************************************************************/
/* r0 contains the address of the queue */
/* r1 contains the value of element */
/* r0 returns address of element or - 1 if error */
enqueueNode:
push {r1-r5,lr} @ save registers
mov r4,r0
mov r0,#queue_node_fin @ allocation place heap
bl allocHeap
cmp r0,#-1 @ allocation error
beq 100f
mov r5,r0 @ save heap address
str r1,[r5,#queue_node_value] @ store node value
mov r1,#0
str r1,[r5,#queue_node_next] @ init pointer next
ldr r0,[r4,#queue_end]
cmp r0,#0
strne r5,[r0,#queue_node_next]
streq r5,[r4,#queue_begin]
str r5,[r4,#queue_end]
mov r0,#0
pop {r1-r5,lr}
bx lr @ return
/******************************************************************/
/* dequeue node */
/******************************************************************/
/* r0 contains the address of the queue */
/* r0 returns address of element or - 1 if error */
dequeueNode:
push {r1-r5,lr} @ save registers
ldr r4,[r0,#queue_begin]
ldr r5,[r4,#queue_node_value]
ldr r6,[r4,#queue_node_next]
str r6,[r0,#queue_begin]
cmp r6,#0
streq r6,[r0,#queue_end]
mov r0,r5
100:
pop {r1-r5,lr}
bx lr @ return
/******************************************************************/
/* dequeue node */
/******************************************************************/
/* r0 contains the address of the queue */
/* r0 returns 0 if empty else 1 */
isEmptyQueue:
ldr r0,[r0,#queue_begin]
cmp r0,#0
movne r0,#1
bx lr @ return
/******************************************************************/
/* memory allocation on the heap */
/******************************************************************/
/* r0 contains the size to allocate */
/* r0 returns address of memory heap or - 1 if error */
/* CAUTION : The size of the allowance must be a multiple of 4 */
allocHeap:
push {r5-r7,lr} @ save registers
@ allocation
mov r6,r0 @ save size
mov r0,#0 @ read address start heap
mov r7,#0x2D @ call system 'brk'
svc #0
mov r5,r0 @ save address heap for return
add r0,r6 @ reservation place for size
mov r7,#0x2D @ call system 'brk'
svc #0
cmp r0,#-1 @ allocation error
movne r0,r5 @ return address memory heap
pop {r5-r7,lr} @ restaur registers
bx lr @ return
/******************************************************************/
/* display text with size calculation */
/******************************************************************/
/* r0 contains the address of the message */
affichageMess:
push {r0,r1,r2,r7,lr} @ save registers
mov r2,#0 @ counter length */
1: @ loop length calculation
ldrb r1,[r0,r2] @ read octet start position + index
cmp r1,#0 @ if 0 its over
addne r2,r2,#1 @ else add 1 in the length
bne 1b @ and loop
@ so here r2 contains the length of the message
mov r1,r0 @ address message in r1
mov r0,#STDOUT @ code to write to the standard output Linux
mov r7, #WRITE @ code call system "write"
svc #0 @ call system
pop {r0,r1,r2,r7,lr} @ restaur registers
bx lr @ return
/***************************************************/
/* Converting a register to a signed decimal */
/***************************************************/
/* r0 contains value and r1 area address */
conversion10S:
push {r0-r4,lr} @ save registers
mov r2,r1 @ debut zone stockage
mov r3,#'+' @ par defaut le signe est +
cmp r0,#0 @ negative number ?
movlt r3,#'-' @ yes
mvnlt r0,r0 @ number inversion
addlt r0,#1
mov r4,#10 @ length area
1: @ start loop
bl divisionpar10U
add r1,#48 @ digit
strb r1,[r2,r4] @ store digit on area
sub r4,r4,#1 @ previous position
cmp r0,#0 @ stop if quotient = 0
bne 1b
strb r3,[r2,r4] @ store signe
subs r4,r4,#1 @ previous position
blt 100f @ if r4 < 0 -> end
mov r1,#' ' @ space
2:
strb r1,[r2,r4] @store byte space
subs r4,r4,#1 @ previous position
bge 2b @ loop if r4 > 0
100:
pop {r0-r4,lr} @ restaur registers
bx lr
/***************************************************/
/* division par 10 unsigned */
/***************************************************/
/* r0 dividende */
/* r0 quotient */
/* r1 remainder */
divisionpar10U:
push {r2,r3,r4, lr}
mov r4,r0 @ save value
//mov r3,#0xCCCD @ r3 <- magic_number lower raspberry 3
//movt r3,#0xCCCC @ r3 <- magic_number higter raspberry 3
ldr r3,iMagicNumber @ r3 <- magic_number raspberry 1 2
umull r1, r2, r3, r0 @ r1<- Lower32Bits(r1*r0) r2<- Upper32Bits(r1*r0)
mov r0, r2, LSR #3 @ r2 <- r2 >> shift 3
add r2,r0,r0, lsl #2 @ r2 <- r0 * 5
sub r1,r4,r2, lsl #1 @ r1 <- r4 - (r2 * 2) = r4 - (r0 * 10)
pop {r2,r3,r4,lr}
bx lr @ leave function
iMagicNumber: .int 0xCCCCCCCD

View file

@ -0,0 +1,98 @@
#include
"share/atspre_staload.hats"
//
(* ****** ****** *)
//
datatype
tree (a:t@ype) =
| tnil of ()
| tcons of (tree a, a, tree a)
//
(* ****** ****** *)
symintr ++
infixr (+) ++
overload ++ with list_append
(* ****** ****** *)
#define sing list_sing
(* ****** ****** *)
fun{
a:t@ype
} preorder
(t0: tree a): List0 a =
case t0 of
| tnil () => nil ()
| tcons (tl, x, tr) => sing(x) ++ preorder(tl) ++ preorder(tr)
(* ****** ****** *)
fun{
a:t@ype
} inorder
(t0: tree a): List0 a =
case t0 of
| tnil () => nil ()
| tcons (tl, x, tr) => inorder(tl) ++ sing(x) ++ inorder(tr)
(* ****** ****** *)
fun{
a:t@ype
} postorder
(t0: tree a): List0 a =
case t0 of
| tnil () => nil ()
| tcons (tl, x, tr) => postorder(tl) ++ postorder(tr) ++ sing(x)
(* ****** ****** *)
fun{
a:t@ype
} levelorder
(t0: tree a): List0 a = let
//
fun auxlst
(ts: List (tree(a))): List0 a =
case ts of
| list_nil () => list_nil ()
| list_cons (t, ts) =>
(
case+ t of
| tnil () => auxlst (ts)
| tcons (tl, x, tr) => cons (x, auxlst (ts ++ $list{tree(a)}(tl, tr)))
)
//
in
auxlst (sing(t0))
end // end of [levelorder]
(* ****** ****** *)
macdef
tsing(x) = tcons (tnil, ,(x), tnil)
(* ****** ****** *)
implement
main0 () = let
//
val t0 =
tcons{int}
(
tcons (tcons (tsing (7), 4, tnil ()), 2, tsing (5))
,
1
,
tcons (tcons (tsing (8), 6, tsing (9)), 3, tnil ())
)
//
in
println! ("preorder:\t", preorder(t0));
println! ("inorder:\t", inorder(t0));
println! ("postorder:\t", postorder(t0));
println! ("level-order:\t", levelorder(t0));
end (* end of [main0] *)

View file

@ -0,0 +1,89 @@
function preorder(tree, node, res, child) {
if (node == "")
return
res[res["count"]++] = node
split(tree[node], child, ",")
preorder(tree,child[1],res)
preorder(tree,child[2],res)
}
function inorder(tree, node, res, child) {
if (node == "")
return
split(tree[node], child, ",")
inorder(tree,child[1],res)
res[res["count"]++] = node
inorder(tree,child[2],res)
}
function postorder(tree, node, res, child) {
if (node == "")
return
split(tree[node], child, ",")
postorder(tree,child[1], res)
postorder(tree,child[2], res)
res[res["count"]++] = node
}
function levelorder(tree, node, res, nextnode, queue, child) {
if (node == "")
return
queue["tail"] = 0
queue[queue["head"]++] = node
while (queue["head"] - queue["tail"] >= 1) {
nextnode = queue[queue["tail"]]
delete queue[queue["tail"]++]
res[res["count"]++] = nextnode
split(tree[nextnode], child, ",")
if (child[1] != "")
queue[queue["head"]++] = child[1]
if (child[2] != "")
queue[queue["head"]++] = child[2]
}
delete queue
}
BEGIN {
tree["1"] = "2,3"
tree["2"] = "4,5"
tree["3"] = "6,"
tree["4"] = "7,"
tree["5"] = ","
tree["6"] = "8,9"
tree["7"] = ","
tree["8"] = ","
tree["9"] = ","
preorder(tree,"1",result)
printf "preorder:\t"
for (n = 0; n < result["count"]; n += 1)
printf result[n]" "
printf "\n"
delete result
inorder(tree,"1",result)
printf "inorder:\t"
for (n = 0; n < result["count"]; n += 1)
printf result[n]" "
printf "\n"
delete result
postorder(tree,"1",result)
printf "postorder:\t"
for (n = 0; n < result["count"]; n += 1)
printf result[n]" "
printf "\n"
delete result
levelorder(tree,"1",result)
printf "level-order:\t"
for (n = 0; n < result["count"]; n += 1)
printf result[n]" "
printf "\n"
delete result
}

View file

@ -0,0 +1,251 @@
CARD EndProg ;required for ALLOCATE.ACT
INCLUDE "D2:ALLOCATE.ACT" ;from the Action! Tool Kit. You must type 'SET EndProg=*' from the monitor after compiling, but before running this program!
DEFINE PTR="CARD"
DEFINE TREE_NODE_SIZE="5"
TYPE TreeNode=[BYTE tData PTR left,right]
DEFINE QUEUE_NODE_SIZE="4"
TYPE QueueNode=[PTR qData,qNext]
DEFINE STACK_NODE_SIZE="4"
TYPE StackNode=[PTR sData,sNext]
Type Tree=[PTR root] ;TreeNode POINTER
TYPE Stack=[PTR top] ;StackNode POINTER
TYPE Queue=[PTR front,rear] ;QueueNode POINTER
PROC QueueInit(Queue POINTER q)
q.front=0 q.rear=0
RETURN
BYTE FUNC QueueIsEmpty(Queue POINTER q)
IF q.front=0 THEN RETURN (1) FI
RETURN (0)
PROC QueuePush(Queue POINTER q TreeNode POINTER d)
QueueNode POINTER node,tmp
node=Alloc(QUEUE_NODE_SIZE)
node.qData=d
node.qNext=0
IF QueueIsEmpty(q) THEN
q.front=node
ELSE
tmp=q.rear
tmp.qNext=node
FI
q.rear=node
RETURN
PTR FUNC QueuePop(Queue POINTER q)
QueueNode POINTER node
TreeNode POINTER d
IF QueueIsEmpty(q) THEN
PrintE("Error: queue is empty!")
Break()
FI
node=q.front
d=node.qData
q.front=node.qNext
Free(node,QUEUE_NODE_SIZE)
RETURN (d)
PROC StackInit(Stack POINTER s)
s.top=0
RETURN
BYTE FUNC StackIsEmpty(Stack POINTER s)
IF s.top=0 THEN
RETURN (1)
FI
RETURN (0)
PROC StackPush(Stack POINTER s TreeNode POINTER d)
StackNode POINTER node
node=Alloc(STACK_NODE_SIZE)
node.sData=d
node.sNext=s.top
s.top=node
RETURN
PTR FUNC StackPop(Stack POINTER s)
StackNode POINTER node
TreeNode POINTER d
IF StackIsEmpty(s) THEN
PrintE("Error stack is empty!")
Break()
FI
node=s.top
d=node.sData
s.top=node.sNext
Free(node,STACK_NODE_SIZE)
RETURN (d)
PTR FUNC CreateTreeNode(BYTE d TreeNode POINTER l,r)
TreeNode POINTER node
node=Alloc(TREE_NODE_SIZE)
node.tData=d
node.left=l
node.right=r
RETURN (node)
PROC BuildTree(Tree POINTER t)
TreeNode POINTER t2,t3,t4,t5,t6,t7,t8,t9
t7=CreateTreeNode(7,0,0)
t4=CreateTreeNode(4,t7,0)
t5=CreateTreeNode(5,0,0)
t2=CreateTreeNode(2,t4,t5)
t8=CreateTreeNode(8,0,0)
t9=CreateTreeNode(9,0,0)
t6=CreateTreeNode(6,t8,t9)
t3=CreateTreeNode(3,t6,0)
t.root=CreateTreeNode(1,t2,t3)
RETURN
PROC DestroyTree(Tree POINTER t)
TreeNode POINTER n
Queue q
IF t.root=0 THEN RETURN FI
QueueInit(q)
QueuePush(q,t.root)
WHILE QueueIsEmpty(q)=0
DO
n=QueuePop(q)
IF n.left#0 THEN
QueuePush(q,n.left)
FI
IF n.right#0 THEN
QueuePush(q,n.right)
FI
Free(n,TREE_NODE_SIZE)
OD
t.root=0
RETURN
PROC VisitNode(TreeNode POINTER n)
PrintB(n.tData) Put(32)
RETURN
PROC PreOrder(Tree POINTER t)
TreeNode POINTER n
Stack s
StackInit(s)
StackPush(s,t.root)
WHILE StackIsEmpty(s)=0
DO
n=StackPop(s)
VisitNode(n)
IF n.right#0 THEN
StackPush(s,n.right)
FI
IF n.left#0 THEN
StackPush(s,n.left)
FI
OD
RETURN
PROC InOrder(Tree POINTER t)
TreeNode POINTER n
Stack s
StackInit(s)
n=t.root
DO
DO
IF n.right#0 THEN
StackPush(s,n.right)
FI
StackPush(s,n)
IF n.left#0 THEN
n=n.left
ELSE
EXIT
FI
OD
n=StackPop(s)
WHILE StackIsEmpty(s)=0 AND n.right=0
DO
VisitNode(n)
n=StackPop(s)
OD
VisitNode(n)
IF StackIsEmpty(s) THEN EXIT FI
n=StackPop(s)
OD
RETURN
PROC PostOrder(Tree POINTER t)
TreeNode POINTER n
Stack s,tmp
StackInit(s)
StackInit(tmp)
StackPush(s,t.root)
WHILE StackIsEmpty(s)=0
DO
n=StackPop(s)
StackPush(tmp,n)
IF n.left#0 THEN
StackPush(s,n.left)
FI
IF n.right#0 THEN
StackPush(s,n.right)
FI
OD
WHILE StackIsEmpty(tmp)=0
DO
n=StackPop(tmp)
VisitNode(n)
OD
RETURN
PROC LevelOrder(Tree POINTER t)
TreeNode POINTER n
Queue q
QueueInit(q)
QueuePush(q,t.root)
WHILE QueueIsEmpty(q)=0
DO
n=QueuePop(q)
IF n.left#0 THEN
QueuePush(q,n.left)
FI
IF n.right#0 THEN
QueuePush(q,n.right)
FI
VisitNode(n)
OD
RETURN
PROC Main()
Tree t
Put(125) PutE() ;clear screen
AllocInit(0)
BuildTree(t)
Print("pre-order: ") PreOrder(t) PutE()
Print("in-order: ") InOrder(t) PutE()
Print("post-order: ") PostOrder(t) PutE()
Print("level-order: ") LevelOrder(t) PutE()
DestroyTree(t)
RETURN

View file

@ -0,0 +1,108 @@
with Ada.Text_Io; use Ada.Text_Io;
with Ada.Unchecked_Deallocation;
with Ada.Containers.Doubly_Linked_Lists;
procedure Tree_Traversal is
type Node;
type Node_Access is access Node;
type Node is record
Left : Node_Access := null;
Right : Node_Access := null;
Data : Integer;
end record;
procedure Destroy_Tree(N : in out Node_Access) is
procedure free is new Ada.Unchecked_Deallocation(Node, Node_Access);
begin
if N.Left /= null then
Destroy_Tree(N.Left);
end if;
if N.Right /= null then
Destroy_Tree(N.Right);
end if;
Free(N);
end Destroy_Tree;
function Tree(Value : Integer; Left : Node_Access; Right : Node_Access) return Node_Access is
Temp : Node_Access := new Node;
begin
Temp.Data := Value;
Temp.Left := Left;
Temp.Right := Right;
return Temp;
end Tree;
procedure Preorder(N : Node_Access) is
begin
Put(Integer'Image(N.Data));
if N.Left /= null then
Preorder(N.Left);
end if;
if N.Right /= null then
Preorder(N.Right);
end if;
end Preorder;
procedure Inorder(N : Node_Access) is
begin
if N.Left /= null then
Inorder(N.Left);
end if;
Put(Integer'Image(N.Data));
if N.Right /= null then
Inorder(N.Right);
end if;
end Inorder;
procedure Postorder(N : Node_Access) is
begin
if N.Left /= null then
Postorder(N.Left);
end if;
if N.Right /= null then
Postorder(N.Right);
end if;
Put(Integer'Image(N.Data));
end Postorder;
procedure Levelorder(N : Node_Access) is
package Queues is new Ada.Containers.Doubly_Linked_Lists(Node_Access);
use Queues;
Node_Queue : List;
Next : Node_Access;
begin
Node_Queue.Append(N);
while not Is_Empty(Node_Queue) loop
Next := First_Element(Node_Queue);
Delete_First(Node_Queue);
Put(Integer'Image(Next.Data));
if Next.Left /= null then
Node_Queue.Append(Next.Left);
end if;
if Next.Right /= null then
Node_Queue.Append(Next.Right);
end if;
end loop;
end Levelorder;
N : Node_Access;
begin
N := Tree(1,
Tree(2,
Tree(4,
Tree(7, null, null),
null),
Tree(5, null, null)),
Tree(3,
Tree(6,
Tree(8, null, null),
Tree(9, null, null)),
null));
Put("preorder: ");
Preorder(N);
New_Line;
Put("inorder: ");
Inorder(N);
New_Line;
Put("postorder: ");
Postorder(N);
New_Line;
Put("level order: ");
Levelorder(N);
New_Line;
Destroy_Tree(N);
end Tree_traversal;

View file

@ -0,0 +1,75 @@
open import Data.List using (List; _?_; []; concat)
open import Data.Nat using (N; suc; zero)
open import Level using (Level)
open import Relation.Binary.PropositionalEquality using (_=_; refl)
data Tree {a} (A : Set a) : Set a where
leaf : Tree A
node : A ? Tree A ? Tree A ? Tree A
variable
a : Level
A : Set a
preorder : Tree A ? List A
preorder tr = go tr []
where
go : Tree A ? List A ? List A
go leaf ys = ys
go (node x ls rs) ys = x ? go ls (go rs ys)
inorder : Tree A ? List A
inorder tr = go tr []
where
go : Tree A ? List A ? List A
go leaf ys = ys
go (node x ls rs) ys = go ls (x ? go rs ys)
postorder : Tree A ? List A
postorder tr = go tr []
where
go : Tree A ? List A ? List A
go leaf ys = ys
go (node x ls rs) ys = go ls (go rs (x ? ys))
level-order : Tree A ? List A
level-order tr = concat (go tr [])
where
go : Tree A ? List (List A) ? List (List A)
go leaf qs = qs
go (node x ls rs) [] = (x ? []) ? go ls (go rs [])
go (node x ls rs) (q ? qs) = (x ? q ) ? go ls (go rs qs)
example-tree : Tree N
example-tree =
node 1
(node 2
(node 4
(node 7
leaf
leaf)
leaf)
(node 5
leaf
leaf))
(node 3
(node 6
(node 8
leaf
leaf)
(node 9
leaf
leaf))
leaf)
_ : preorder example-tree = 1 ? 2 ? 4 ? 7 ? 5 ? 3 ? 6 ? 8 ? 9 ? []
_ = refl
_ : inorder example-tree = 7 ? 4 ? 2 ? 5 ? 1 ? 8 ? 6 ? 9 ? 3 ? []
_ = refl
_ : postorder example-tree = 7 ? 4 ? 5 ? 2 ? 8 ? 9 ? 6 ? 3 ? 1 ? []
_ = refl
_ : level-order example-tree = 1 ? 2 ? 3 ? 4 ? 5 ? 6 ? 7 ? 8 ? 9 ? []
_ = refl

View file

@ -0,0 +1,325 @@
on run
-- Sample tree of integers
set tree to node(1, ¬
{node(2, ¬
{node(4, {node(7, {})}), ¬
node(5, {})}), ¬
node(3, ¬
{node(6, {node(8, {}), ¬
node(9, {})})})})
-- Output of AppleScript code at Rosetta Code task
-- 'Visualize a Tree':
set strTree to unlines({¬
" + 4 - 7", ¬
" + 2 ¦", ¬
" ¦ + 5", ¬
" 1 ¦", ¬
" ¦ + 8", ¬
" + 3 - 6 ¦", ¬
" + 9"})
script tabulate
on |?|(s, xs)
justifyRight(14, space, s & ": ") & unwords(xs)
end |?|
end script
set strResult to strTree & linefeed & unlines(zipWith(tabulate, ¬
["preorder", "inorder", "postorder", "level-order"], ¬
apList([¬
foldTree(preorder), ¬
foldTree(inorder), ¬
foldTree(postorder), ¬
levelOrder], [tree])))
set the clipboard to strResult
return strResult
end run
---------------------- TREE TRAVERSAL ----------------------
-- preorder :: a -> [[a]] -> [a]
on preorder(x, xs)
{x} & concat(xs)
end preorder
-- inorder :: a -> [[a]] -> [a]
on inorder(x, xs)
if {} ? xs then
item 1 of xs & x & concat(rest of xs)
else
{x}
end if
end inorder
-- postorder :: a -> [[a]] -> [a]
on postorder(x, xs)
concat(xs) & {x}
end postorder
-- levelOrder :: Tree a -> [a]
on levelOrder(tree)
concat(levels(tree))
end levelOrder
-- foldTree :: (a -> [b] -> b) -> Tree a -> b
on foldTree(f)
script
on |?|(tree)
script go
property g : |?| of mReturn(f)
on |?|(oNode)
g(root of oNode, |?|(nest of oNode) ¬
of map(go))
end |?|
end script
|?|(tree) of go
end |?|
end script
end foldTree
------------------------- GENERIC --------------------------
-- Node :: a -> [Tree a] -> Tree a
on node(v, xs)
{type:"Node", root:v, nest:xs}
end node
-- e.g. [(*2),(/2), sqrt] <*> [1,2,3]
-- --> ap([dbl, hlf, root], [1, 2, 3])
-- --> [2,4,6,0.5,1,1.5,1,1.4142135623730951,1.7320508075688772]
-- Each member of a list of functions applied to
-- each of a list of arguments, deriving a list of new values
-- apList (<*>) :: [(a -> b)] -> [a] -> [b]
on apList(fs, xs)
set lst to {}
repeat with f in fs
tell mReturn(contents of f)
repeat with x in xs
set end of lst to |?|(contents of x)
end repeat
end tell
end repeat
return lst
end apList
-- concat :: [[a]] -> [a]
-- concat :: [String] -> String
on concat(xs)
set lng to length of xs
if 0 < lng and string is class of (item 1 of xs) then
set acc to ""
else
set acc to {}
end if
repeat with i from 1 to lng
set acc to acc & item i of xs
end repeat
acc
end concat
-- foldr :: (a -> b -> b) -> b -> [a] -> b
on foldr(f, startValue, xs)
tell mReturn(f)
set v to startValue
set lng to length of xs
repeat with i from lng to 1 by -1
set v to |?|(item i of xs, v, i, xs)
end repeat
return v
end tell
end foldr
-- justifyRight :: Int -> Char -> String -> String
on justifyRight(n, cFiller, strText)
if n > length of strText then
text -n thru -1 of ((replicate(n, cFiller) as text) & strText)
else
strText
end if
end justifyRight
-- length :: [a] -> Int
on |length|(xs)
set c to class of xs
if list is c or string is c then
length of xs
else
(2 ^ 29 - 1) -- (maxInt - simple proxy for non-finite)
end if
end |length|
-- levels :: Tree a -> [[a]]
on levels(tree)
-- A list of lists, grouping the root
-- values of each level of the tree.
script go
on |?|(node, a)
if {} ? a then
tell a to set {h, t} to {item 1, rest}
else
set {h, t} to {{}, {}}
end if
{{root of node} & h} & foldr(go, t, nest of node)
end |?|
end script
|?|(tree, {}) of go
end levels
-- mReturn :: First-class m => (a -> b) -> m (a -> b)
on mReturn(f)
-- 2nd class handler function lifted into 1st class script wrapper.
if script is class of f then
f
else
script
property |?| : f
end script
end if
end mReturn
-- map :: (a -> b) -> [a] -> [b]
on map(f)
-- The list obtained by applying f
-- to each element of xs.
script
on |?|(xs)
tell mReturn(f)
set lng to length of xs
set lst to {}
repeat with i from 1 to lng
set end of lst to |?|(item i of xs, i, xs)
end repeat
return lst
end tell
end |?|
end script
end map
-- min :: Ord a => a -> a -> a
on min(x, y)
if y < x then
y
else
x
end if
end min
-- nest :: Tree a -> [a]
on nest(oTree)
nest of oTree
end nest
-- Egyptian multiplication - progressively doubling a list, appending
-- stages of doubling to an accumulator where needed for binary
-- assembly of a target length
-- replicate :: Int -> a -> [a]
on replicate(n, a)
set out to {}
if 1 > n then return out
set dbl to {a}
repeat while (1 < n)
if 0 < (n mod 2) then set out to out & dbl
set n to (n div 2)
set dbl to (dbl & dbl)
end repeat
return out & dbl
end replicate
-- root :: Tree a -> a
on root(oTree)
root of oTree
end root
-- take :: Int -> [a] -> [a]
-- take :: Int -> String -> String
on take(n, xs)
set c to class of xs
if list is c then
if 0 < n then
items 1 thru min(n, length of xs) of xs
else
{}
end if
else if string is c then
if 0 < n then
text 1 thru min(n, length of xs) of xs
else
""
end if
else if script is c then
set ys to {}
repeat with i from 1 to n
set v to |?|() of xs
if missing value is v then
return ys
else
set end of ys to v
end if
end repeat
return ys
else
missing value
end if
end take
-- unlines :: [String] -> String
on unlines(xs)
-- A single string formed by the intercalation
-- of a list of strings with the newline character.
set {dlm, my text item delimiters} to ¬
{my text item delimiters, linefeed}
set str to xs as text
set my text item delimiters to dlm
str
end unlines
-- unwords :: [String] -> String
on unwords(xs)
set {dlm, my text item delimiters} to ¬
{my text item delimiters, space}
set s to xs as text
set my text item delimiters to dlm
return s
end unwords
-- zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
on zipWith(f, xs, ys)
set lng to min(|length|(xs), |length|(ys))
if 1 > lng then return {}
set xs_ to take(lng, xs) -- Allow for non-finite
set ys_ to take(lng, ys) -- generators like cycle etc
set lst to {}
tell mReturn(f)
repeat with i from 1 to lng
set end of lst to |?|(item i of xs_, item i of ys_)
end repeat
return lst
end tell
end zipWith

View file

@ -0,0 +1,53 @@
AddNode(Tree,1,2,3,1) ; Build global Tree
AddNode(Tree,2,4,5,2)
AddNode(Tree,3,6,0,3)
AddNode(Tree,4,7,0,4)
AddNode(Tree,5,0,0,5)
AddNode(Tree,6,8,9,6)
AddNode(Tree,7,0,0,7)
AddNode(Tree,8,0,0,8)
AddNode(Tree,9,0,0,9)
MsgBox % "Preorder: " PreOrder(Tree,1) ; 1 2 4 7 5 3 6 8 9
MsgBox % "Inorder: " InOrder(Tree,1) ; 7 4 2 5 1 8 6 9 3
MsgBox % "postorder: " PostOrder(Tree,1) ; 7 4 5 2 8 9 6 3 1
MsgBox % "levelorder: " LevOrder(Tree,1) ; 1 2 3 4 5 6 7 8 9
AddNode(ByRef Tree,Node,Left,Right,Value) {
if !isobject(Tree)
Tree := object()
Tree[Node, "L"] := Left
Tree[Node, "R"] := Right
Tree[Node, "V"] := Value
}
PreOrder(Tree,Node) {
ptree := Tree[Node, "V"] " "
. ((L:=Tree[Node, "L"]) ? PreOrder(Tree,L) : "")
. ((R:=Tree[Node, "R"]) ? PreOrder(Tree,R) : "")
return ptree
}
InOrder(Tree,Node) {
Return itree := ((L:=Tree[Node, "L"]) ? InOrder(Tree,L) : "")
. Tree[Node, "V"] " "
. ((R:=Tree[Node, "R"]) ? InOrder(Tree,R) : "")
}
PostOrder(Tree,Node) {
Return ptree := ((L:=Tree[Node, "L"]) ? PostOrder(Tree,L) : "")
. ((R:=Tree[Node, "R"]) ? PostOrder(Tree,R) : "")
. Tree[Node, "V"] " "
}
LevOrder(Tree,Node,Lev=1) {
Static ; make node lists static
i%Lev% .= Tree[Node, "V"] " " ; build node lists in every level
If (L:=Tree[Node, "L"])
LevOrder(Tree,L,Lev+1)
If (R:=Tree[Node, "R"])
LevOrder(Tree,R,Lev+1)
If (Lev > 1)
Return
While i%Lev% ; concatenate node lists from all levels
t .= i%Lev%, Lev++
Return t
}

View file

@ -0,0 +1,66 @@
get "libhdr"
manifest $(
VAL=0
LEFT=1
RIGHT=2
$)
let tree(v,l,r) = valof
$( let obj = getvec(2)
obj!VAL := v
obj!LEFT := l
obj!RIGHT := r
resultis obj
$)
let preorder(tree, cb) be unless tree=0
$( cb(tree!VAL)
preorder(tree!LEFT, cb)
preorder(tree!RIGHT, cb)
$)
let inorder(tree, cb) be unless tree=0
$( inorder(tree!LEFT, cb)
cb(tree!VAL)
inorder(tree!RIGHT, cb)
$)
let postorder(tree, cb) be unless tree=0
$( postorder(tree!LEFT, cb)
postorder(tree!RIGHT, cb)
cb(tree!VAL)
$)
let levelorder(tree, cb) be
$( let q=vec 255
let s=0 and e=1
q!0 := tree
until s=e do
$( unless q!s=0 do
$( q!e := q!s!LEFT
q!(e+1) := q!s!RIGHT
e := e+2
cb(q!s!VAL)
$)
s := s+1
$)
$)
let traverse(name, order, tree) be
$( let cb(n) be writef("%N ", n)
writef("%S:*T", name)
order(tree, cb)
wrch('*N')
$)
let start() be
$( let example = tree(1, tree(2, tree(4, tree(7, 0, 0), 0),
tree(5, 0, 0)),
tree(3, tree(6, tree(8, 0, 0),
tree(9, 0, 0)),
0))
traverse("preorder", preorder, example)
traverse("inorder", inorder, example)
traverse("postorder", postorder, example)
traverse("level-order", levelorder, example)
$)

View file

@ -0,0 +1,41 @@
(
( tree
= 1
. (2.(4.7.) (5.))
(3.6.(8.) (9.))
)
& ( preorder
= K sub
. !arg:(?K.?sub) ?arg
& !K preorder$!sub preorder$!arg
|
)
& out$("preorder: " preorder$!tree)
& ( inorder
= K lhs rhs
. !arg:(?K.?sub) ?arg
& ( !sub:%?lhs ?rhs
& inorder$!lhs !K inorder$!rhs inorder$!arg
| !K
)
)
& out$("inorder: " inorder$!tree)
& ( postorder
= K sub
. !arg:(?K.?sub) ?arg
& postorder$!sub !K postorder$!arg
|
)
& out$("postorder: " postorder$!tree)
& ( levelorder
= todo tree sub
. !arg:(.)&
| !arg:(?tree.?todo)
& ( !tree:(?K.?sub) ?tree
& !K levelorder$(!tree.!todo !sub)
| levelorder$(!todo.)
)
)
& out$("level-order:" levelorder$(!tree.))
&
)

View file

@ -0,0 +1,94 @@
#include <boost/scoped_ptr.hpp>
#include <iostream>
#include <queue>
template<typename T>
class TreeNode {
public:
TreeNode(const T& n, TreeNode* left = NULL, TreeNode* right = NULL)
: mValue(n),
mLeft(left),
mRight(right) {}
T getValue() const {
return mValue;
}
TreeNode* left() const {
return mLeft.get();
}
TreeNode* right() const {
return mRight.get();
}
void preorderTraverse() const {
std::cout << " " << getValue();
if(mLeft) { mLeft->preorderTraverse(); }
if(mRight) { mRight->preorderTraverse(); }
}
void inorderTraverse() const {
if(mLeft) { mLeft->inorderTraverse(); }
std::cout << " " << getValue();
if(mRight) { mRight->inorderTraverse(); }
}
void postorderTraverse() const {
if(mLeft) { mLeft->postorderTraverse(); }
if(mRight) { mRight->postorderTraverse(); }
std::cout << " " << getValue();
}
void levelorderTraverse() const {
std::queue<const TreeNode*> q;
q.push(this);
while(!q.empty()) {
const TreeNode* n = q.front();
q.pop();
std::cout << " " << n->getValue();
if(n->left()) { q.push(n->left()); }
if(n->right()) { q.push(n->right()); }
}
}
protected:
T mValue;
boost::scoped_ptr<TreeNode> mLeft;
boost::scoped_ptr<TreeNode> mRight;
private:
TreeNode();
};
int main() {
TreeNode<int> root(1,
new TreeNode<int>(2,
new TreeNode<int>(4,
new TreeNode<int>(7)),
new TreeNode<int>(5)),
new TreeNode<int>(3,
new TreeNode<int>(6,
new TreeNode<int>(8),
new TreeNode<int>(9))));
std::cout << "preorder: ";
root.preorderTraverse();
std::cout << std::endl;
std::cout << "inorder: ";
root.inorderTraverse();
std::cout << std::endl;
std::cout << "postorder: ";
root.postorderTraverse();
std::cout << std::endl;
std::cout << "level-order:";
root.levelorderTraverse();
std::cout << std::endl;
return 0;
}

View file

@ -0,0 +1,69 @@
#include <iostream>
using namespace std;
const int MAX_DIM = 16;
typedef int* tree;
int left(int index)
{
return index*2+1;
}
int right(int index)
{
return index*2+2;
}
void preorder(tree t, int index = 0)
{
if(index < MAX_DIM && t[index] != 0){
cout << t[index] << ' ';
preorder(t, left(index));
preorder(t, right(index));
}
}
void inorder(tree t, int index = 0)
{
if(index < MAX_DIM && t[index] != 0){
inorder(t, left(index));
cout << t[index] << ' ';
inorder(t, right(index));
}
}
void postorder(tree t, int index = 0)
{
if(index < MAX_DIM && t[index] != 0){
postorder(t, left(index));
postorder(t, right(index));
cout << t[index] << ' ';
}
}
void level_order(tree t, int index = 0)
{
for(int i = 0; i < MAX_DIM; ++i){
if(t[i] != 0)
cout << t[i] << ' ';
}
}
int main()
{
int t[MAX_DIM] = {1,2,3,4,5,6,0,7,0,0,0,8,9};
cout << "preorder: ";
preorder(t);
cout << endl;
cout << "inorder: ";
inorder(t);
cout << endl;
cout << "postorder: ";
postorder(t);
cout << endl;
cout << "level_order: ";
level_order(t);
cout << endl;
}

View file

@ -0,0 +1,95 @@
#include <iostream>
#include <memory>
#include <queue>
template <typename T>
class node {
public:
node(T value) : value_(value) {}
node(T value, std::unique_ptr<node>&& left)
: value_(value), left_(std::move(left)) {}
node(T value, std::unique_ptr<node>&& left, std::unique_ptr<node>&& right)
: value_(value), left_(std::move(left)), right_(std::move(right)) {}
template <typename Function>
void pre_order(Function f) {
f(value_);
if (left_)
left_->pre_order(f);
if (right_)
right_->pre_order(f);
}
template <typename Function>
void in_order(Function f) {
if (left_)
left_->in_order(f);
f(value_);
if (right_)
right_->in_order(f);
}
template <typename Function>
void post_order(Function f) {
if (left_)
left_->post_order(f);
if (right_)
right_->post_order(f);
f(value_);
}
template <typename Function>
void level_order(Function f) {
std::queue<node*> queue;
queue.push(this);
while (!queue.empty()) {
node* next = queue.front();
queue.pop();
f(next->value_);
if (next->left_)
queue.push(next->left_.get());
if (next->right_)
queue.push(next->right_.get());
}
}
private:
T value_;
std::unique_ptr<node> left_;
std::unique_ptr<node> right_;
};
template <typename T, typename... Args>
std::unique_ptr<node<T>>
tree(T value, Args&&... args) {
return std::make_unique<node<T>>(value, std::forward<Args>(args)...);
}
int main() {
node<int> n(1,
tree(2,
tree(4,
tree(7)),
tree(5)),
tree(3,
tree(6,
tree(8),
tree(9))));
auto print = [](int n) { std::cout << n << ' '; };
std::cout << "pre-order: ";
n.pre_order(print);
std::cout << '\n';
std::cout << "in-order: ";
n.in_order(print);
std::cout << '\n';
std::cout << "post-order: ";
n.post_order(print);
std::cout << '\n';
std::cout << "level-order: ";
n.level_order(print);
std::cout << '\n';
}

View file

@ -0,0 +1,72 @@
using System;
using System.Collections.Generic;
using System.Linq;
class Node
{
int Value;
Node Left;
Node Right;
Node(int value = default(int), Node left = default(Node), Node right = default(Node))
{
Value = value;
Left = left;
Right = right;
}
IEnumerable<int> Preorder()
{
yield return Value;
if (Left != null)
foreach (var value in Left.Preorder())
yield return value;
if (Right != null)
foreach (var value in Right.Preorder())
yield return value;
}
IEnumerable<int> Inorder()
{
if (Left != null)
foreach (var value in Left.Inorder())
yield return value;
yield return Value;
if (Right != null)
foreach (var value in Right.Inorder())
yield return value;
}
IEnumerable<int> Postorder()
{
if (Left != null)
foreach (var value in Left.Postorder())
yield return value;
if (Right != null)
foreach (var value in Right.Postorder())
yield return value;
yield return Value;
}
IEnumerable<int> LevelOrder()
{
var queue = new Queue<Node>();
queue.Enqueue(this);
while (queue.Any())
{
var node = queue.Dequeue();
yield return node.Value;
if (node.Left != null)
queue.Enqueue(node.Left);
if (node.Right != null)
queue.Enqueue(node.Right);
}
}
static void Main()
{
var tree = new Node(1, new Node(2, new Node(4, new Node(7)), new Node(5)), new Node(3, new Node(6, new Node(8), new Node(9))));
foreach (var traversal in new Func<IEnumerable<int>>[] { tree.Preorder, tree.Inorder, tree.Postorder, tree.LevelOrder })
Console.WriteLine("{0}:\t{1}", traversal.Method.Name, string.Join(" ", traversal()));
}
}

View file

@ -0,0 +1,146 @@
#include <stdlib.h>
#include <stdio.h>
typedef struct node_s
{
int value;
struct node_s* left;
struct node_s* right;
} *node;
node tree(int v, node l, node r)
{
node n = malloc(sizeof(struct node_s));
n->value = v;
n->left = l;
n->right = r;
return n;
}
void destroy_tree(node n)
{
if (n->left)
destroy_tree(n->left);
if (n->right)
destroy_tree(n->right);
free(n);
}
void preorder(node n, void (*f)(int))
{
f(n->value);
if (n->left)
preorder(n->left, f);
if (n->right)
preorder(n->right, f);
}
void inorder(node n, void (*f)(int))
{
if (n->left)
inorder(n->left, f);
f(n->value);
if (n->right)
inorder(n->right, f);
}
void postorder(node n, void (*f)(int))
{
if (n->left)
postorder(n->left, f);
if (n->right)
postorder(n->right, f);
f(n->value);
}
/* helper queue for levelorder */
typedef struct qnode_s
{
struct qnode_s* next;
node value;
} *qnode;
typedef struct { qnode begin, end; } queue;
void enqueue(queue* q, node n)
{
qnode node = malloc(sizeof(struct qnode_s));
node->value = n;
node->next = 0;
if (q->end)
q->end->next = node;
else
q->begin = node;
q->end = node;
}
node dequeue(queue* q)
{
node tmp = q->begin->value;
qnode second = q->begin->next;
free(q->begin);
q->begin = second;
if (!q->begin)
q->end = 0;
return tmp;
}
int queue_empty(queue* q)
{
return !q->begin;
}
void levelorder(node n, void(*f)(int))
{
queue nodequeue = {};
enqueue(&nodequeue, n);
while (!queue_empty(&nodequeue))
{
node next = dequeue(&nodequeue);
f(next->value);
if (next->left)
enqueue(&nodequeue, next->left);
if (next->right)
enqueue(&nodequeue, next->right);
}
}
void print(int n)
{
printf("%d ", n);
}
int main()
{
node n = tree(1,
tree(2,
tree(4,
tree(7, 0, 0),
0),
tree(5, 0, 0)),
tree(3,
tree(6,
tree(8, 0, 0),
tree(9, 0, 0)),
0));
printf("preorder: ");
preorder(n, print);
printf("\n");
printf("inorder: ");
inorder(n, print);
printf("\n");
printf("postorder: ");
postorder(n, print);
printf("\n");
printf("level-order: ");
levelorder(n, print);
printf("\n");
destroy_tree(n);
return 0;
}

View file

@ -0,0 +1,94 @@
bintree = cluster [T: type] is leaf, node,
pre_order, post_order, in_order, level_order
branch = struct[left, right: bintree[T], val: T]
rep = oneof[br: branch, leaf: null]
leaf = proc () returns (cvt)
return(rep$make_leaf(nil))
end leaf
node = proc (val: T, l,r: cvt) returns (cvt)
return(rep$make_br(branch${left:up(l), right:up(r), val:val}))
end node
pre_order = iter (n: cvt) yields (T)
tagcase n
tag br (b: branch):
yield(b.val)
for v: T in pre_order(b.left) do yield(v) end
for v: T in pre_order(b.right) do yield(v) end
tag leaf:
end
end pre_order
in_order = iter (n: cvt) yields (T)
tagcase n
tag br (b: branch):
for v: T in in_order(b.left) do yield(v) end
yield(b.val)
for v: T in in_order(b.right) do yield(v) end
tag leaf:
end
end in_order
post_order = iter (n: cvt) yields (T)
tagcase n
tag br (b: branch):
for v: T in post_order(b.left) do yield(v) end
for v: T in post_order(b.right) do yield(v) end
yield(b.val)
tag leaf:
end
end post_order
level_order = iter (n: cvt) yields (T)
bfs: array[rep] := array[rep]$[n]
while ~array[rep]$empty(bfs) do
cur: rep := array[rep]$reml(bfs)
tagcase cur
tag br (b: branch):
yield(b.val)
array[rep]$addh(bfs,down(b.left))
array[rep]$addh(bfs,down(b.right))
tag leaf:
end
end
end level_order
end bintree
start_up = proc ()
bt = bintree[int]
po: stream := stream$primary_output()
tree: bt := bt$node(1,
bt$node(2,
bt$node(4,
bt$node(7, bt$leaf(), bt$leaf()),
bt$leaf()),
bt$node(5, bt$leaf(), bt$leaf())),
bt$node(3,
bt$node(6,
bt$node(8, bt$leaf(), bt$leaf()),
bt$node(9, bt$leaf(), bt$leaf())),
bt$leaf()))
stream$puts(po, "preorder: ")
for i: int in bt$pre_order(tree) do
stream$puts(po, " " || int$unparse(i))
end
stream$puts(po, "\ninorder: ")
for i: int in bt$in_order(tree) do
stream$puts(po, " " || int$unparse(i))
end
stream$puts(po, "\npostorder: ")
for i: int in bt$post_order(tree) do
stream$puts(po, " " || int$unparse(i))
end
stream$puts(po, "\nlevel-order:")
for i: int in bt$level_order(tree) do
stream$puts(po, " " || int$unparse(i))
end
end start_up

View file

@ -0,0 +1,97 @@
import ceylon.collection {
ArrayList
}
shared void run() {
class Node(label, left = null, right = null) {
shared Integer label;
shared Node? left;
shared Node? right;
string => label.string;
}
void preorder(Node node) {
process.write(node.string + " ");
if(exists left = node.left) {
preorder(left);
}
if(exists right = node.right) {
preorder(right);
}
}
void inorder(Node node) {
if(exists left = node.left) {
inorder(left);
}
process.write(node.string + " ");
if(exists right = node.right) {
inorder(right);
}
}
void postorder(Node node) {
if(exists left = node.left) {
postorder(left);
}
if(exists right = node.right) {
postorder(right);
}
process.write(node.string + " ");
}
void levelOrder(Node node) {
value nodes = ArrayList<Node> {node};
while(exists current = nodes.accept()) {
process.write(current.string + " ");
if(exists left = current.left) {
nodes.offer(left);
}
if(exists right = current.right) {
nodes.offer(right);
}
}
}
value tree = Node {
label = 1;
left = Node {
label = 2;
left = Node {
label = 4;
left = Node {
label = 7;
};
};
right = Node {
label = 5;
};
};
right = Node {
label = 3;
left = Node {
label = 6;
left = Node {
label = 8;
};
right = Node {
label = 9;
};
};
};
};
process.write("preorder: ");
preorder(tree);
print("");
process.write("inorder: ");
inorder(tree);
print("");
process.write("postorder: ");
postorder(tree);
print("");
process.write("levelorder: ");
levelOrder(tree);
print("");
}

View file

@ -0,0 +1,44 @@
(defn walk [node f order]
(when node
(doseq [o order]
(if (= o :visit)
(f (:val node))
(walk (node o) f order)))))
(defn preorder [node f]
(walk node f [:visit :left :right]))
(defn inorder [node f]
(walk node f [:left :visit :right]))
(defn postorder [node f]
(walk node f [:left :right :visit]))
(defn queue [& xs]
(when (seq xs)
(apply conj clojure.lang.PersistentQueue/EMPTY xs)))
(defn level-order [root f]
(loop [q (queue root)]
(when-not (empty? q)
(if-let [node (first q)]
(do
(f (:val node))
(recur (conj (pop q) (:left node) (:right node))))
(recur (pop q))))))
(defn vec-to-tree [t]
(if (vector? t)
(let [[val left right] t]
{:val val
:left (vec-to-tree left)
:right (vec-to-tree right)})
t))
(let [tree (vec-to-tree [1 [2 [4 [7]] [5]] [3 [6 [8] [9]]]])
fs '[preorder inorder postorder level-order]
pr-node #(print (format "%2d" %))]
(doseq [f fs]
(print (format "%-12s" (str f ":")))
((resolve f) tree pr-node)
(println)))

View file

@ -0,0 +1,46 @@
# In this example, we don't encapsulate binary trees as objects; instead, we have a
# convention on how to store them as arrays, and we namespace the functions that
# operate on those data structures.
binary_tree =
preorder: (tree, visit) ->
return unless tree?
[node, left, right] = tree
visit node
binary_tree.preorder left, visit
binary_tree.preorder right, visit
inorder: (tree, visit) ->
return unless tree?
[node, left, right] = tree
binary_tree.inorder left, visit
visit node
binary_tree.inorder right, visit
postorder: (tree, visit) ->
return unless tree?
[node, left, right] = tree
binary_tree.postorder left, visit
binary_tree.postorder right, visit
visit node
levelorder: (tree, visit) ->
q = []
q.push tree
while q.length > 0
t = q.shift()
continue unless t?
[node, left, right] = t
visit node
q.push left
q.push right
do ->
tree = [1, [2, [4, [7]], [5]], [3, [6, [8],[9]]]]
test_walk = (walk_function_name) ->
output = []
binary_tree[walk_function_name] tree, output.push.bind(output)
console.log walk_function_name, output.join ' '
test_walk "preorder"
test_walk "inorder"
test_walk "postorder"
test_walk "levelorder"

View file

@ -0,0 +1,38 @@
(defun preorder (node f)
(when node
(funcall f (first node))
(preorder (second node) f)
(preorder (third node) f)))
(defun inorder (node f)
(when node
(inorder (second node) f)
(funcall f (first node))
(inorder (third node) f)))
(defun postorder (node f)
(when node
(postorder (second node) f)
(postorder (third node) f)
(funcall f (first node))))
(defun level-order (node f)
(loop with level = (list node)
while level
do
(setf level (loop for node in level
when node
do (funcall f (first node))
and collect (second node)
and collect (third node)))))
(defparameter *tree* '(1 (2 (4 (7))
(5))
(3 (6 (8)
(9)))))
(defun show (traversal-function)
(format t "~&~(~A~):~12,0T" traversal-function)
(funcall traversal-function *tree* (lambda (value) (format t " ~A" value))))
(map nil #'show '(preorder inorder postorder level-order))

View file

@ -0,0 +1,51 @@
Require Import Utf8.
Require Import List.
Unset Elimination Schemes.
(* Rose tree, with numbers on nodes *)
Inductive tree := Tree { value : nat ; children : list tree }.
Fixpoint height (t: tree) : nat :=
1 + fold_left (? n t, max n (height t)) (children t) 0.
Example leaf n : tree := {| value := n ; children := nil |}.
Example t2 : tree := {| value := 2 ; children := {| value := 4 ; children := leaf 7 :: nil |} :: leaf 5 :: nil |}.
Example t3 : tree := {| value := 3 ; children := {| value := 6 ; children := leaf 8 :: leaf 9 :: nil |} :: nil |}.
Example t9 : tree := {| value := 1 ; children := t2 :: t3 :: nil |}.
Fixpoint preorder (t: tree) : list nat :=
let '{| value := n ; children := c |} := t in
n :: flat_map preorder c.
Fixpoint inorder (t: tree) : list nat :=
let '{| value := n ; children := c |} := t in
match c with
| nil => n :: nil
| l :: r => inorder l ++ n :: flat_map inorder r
end.
Fixpoint postorder (t: tree) : list nat :=
let '{| value := n ; children := c |} := t in
flat_map postorder c ++ n :: nil.
(* Auxiliary function for levelorder, which operates on forests *)
(* Since the recursion is tricky, it relies on a fuel parameter which obviously decreases. *)
Fixpoint levelorder_forest (fuel: nat) (f: list tree) : list nat:=
match fuel with
| O => nil
| S fuel' =>
let '(p, f) := fold_right (? t r, let '(x, f) := r in (value t :: x, children t ++ f) ) (nil, nil) f in
p ++ levelorder_forest fuel' f
end.
Definition levelorder (t: tree) : list nat :=
levelorder_forest (height t) (t :: nil).
Compute preorder t9.
Compute inorder t9.
Compute postorder t9.
Compute levelorder t9.

View file

@ -0,0 +1,80 @@
class Node(T)
property left : Nil | Node(T)
property right : Nil | Node(T)
property data : T
def initialize(@data, @left = nil, @right = nil)
end
def preorder_traverse
print " #{data}"
if left = @left
left.preorder_traverse
end
if right = @right
right.preorder_traverse
end
end
def inorder_traverse
if left = @left
left.inorder_traverse
end
print " #{data}"
if right = @right
right.inorder_traverse
end
end
def postorder_traverse
if left = @left
left.postorder_traverse
end
if right = @right
right.postorder_traverse
end
print " #{data}"
end
def levelorder_traverse
queue = Array(Node(T)).new
queue << self
until queue.size <= 0
node = queue.shift
unless node
next
end
print " #{node.data}"
if left = node.left
queue << left
end
if right = node.right
queue << right
end
end
end
end
tree = Node(Int32).new(1,
Node(Int32).new(2,
Node(Int32).new(4,
Node(Int32).new(7)),
Node(Int32).new(5)),
Node(Int32).new(3,
Node(Int32).new(6,
Node(Int32).new(8),
Node(Int32).new(9))))
print "preorder: "
tree.preorder_traverse
print "\ninorder: "
tree.inorder_traverse
print "\npostorder: "
tree.postorder_traverse
print "\nlevelorder: "
tree.levelorder_traverse
puts

View file

@ -0,0 +1,77 @@
import std.stdio, std.traits;
const final class Node(T) {
T data;
Node left, right;
this(in T data, in Node left=null, in Node right=null)
const pure nothrow {
this.data = data;
this.left = left;
this.right = right;
}
}
// '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 const(Node!T)(data, left, right);
}
void show(T)(in T x) {
write(x, " ");
}
enum Visit { pre, inv, post }
// '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) {
alias trueVisitor = Select!(is(TyF == void*), show, visitor);
if (node !is null) {
static if (v == Visit.pre)
trueVisitor(node.data);
backtrackingOrder!v(node.left, visitor);
static if (v == Visit.inv)
trueVisitor(node.data);
backtrackingOrder!v(node.right, visitor);
static if (v == Visit.post)
trueVisitor(node.data);
}
}
void levelOrder(TNode, TyF=void*)
(in TNode node, TyF visitor=null, const(TNode)[] more=[]) {
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], visitor, more[1 .. $]);
}
void main() {
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: ");
tree.backtrackingOrder!(Visit.pre);
write("\n inorder: ");
tree.backtrackingOrder!(Visit.inv);
write("\n postOrder: ");
tree.backtrackingOrder!(Visit.post);
write("\nlevelorder: ");
tree.levelOrder;
writeln;
}

View file

@ -0,0 +1,44 @@
const struct Node(T) {
T v;
Node* l, r;
}
T[] preOrder(T)(in Node!T* t) pure nothrow {
return t ? t.v ~ preOrder(t.l) ~ preOrder(t.r) : [];
}
T[] inOrder(T)(in Node!T* t) pure nothrow {
return t ? inOrder(t.l) ~ t.v ~ inOrder(t.r) : [];
}
T[] postOrder(T)(in Node!T* t) pure nothrow {
return t ? postOrder(t.l) ~ postOrder(t.r) ~ t.v : [];
}
T[] levelOrder(T)(in Node!T* t) pure nothrow {
static T[] loop(in Node!T*[] a) pure nothrow {
if (!a.length) return [];
if (!a[0]) return loop(a[1 .. $]);
return a[0].v ~ loop(a[1 .. $] ~ [a[0].l, a[0].r]);
}
return loop([t]);
}
void main() {
alias N = Node!int;
auto tree = new N(1,
new N(2,
new N(4,
new N(7)),
new N(5)),
new N(3,
new N(6,
new N(8),
new N(9))));
import std.stdio;
writeln(preOrder(tree));
writeln(inOrder(tree));
writeln(postOrder(tree));
writeln(levelOrder(tree));
}

View file

@ -0,0 +1,65 @@
import std.stdio, std.algorithm, std.range, std.string;
const struct Tree(T) {
T value;
Tree* left, right;
}
alias VisitRange(T) = InputRange!(const Tree!T);
VisitRange!T preOrder(T)(in Tree!T* t) /*pure nothrow*/ {
enum self = mixin("&" ~ __FUNCTION__.split(".").back);
if (t == null)
return typeof(return).init.takeNone.inputRangeObject;
return [*t]
.chain([t.left, t.right]
.filter!(t => t != null)
.map!(a => self(a))
.joiner)
.inputRangeObject;
}
VisitRange!T inOrder(T)(in Tree!T* t) /*pure nothrow*/ {
enum self = mixin("&" ~ __FUNCTION__.split(".").back);
if (t == null)
return typeof(return).init.takeNone.inputRangeObject;
return [t.left]
.filter!(t => t != null)
.map!(a => self(a))
.joiner
.chain([*t])
.chain([t.right]
.filter!(t => t != null)
.map!(a => self(a))
.joiner)
.inputRangeObject;
}
VisitRange!T postOrder(T)(in Tree!T* t) /*pure nothrow*/ {
enum self = mixin("&" ~ __FUNCTION__.split(".").back);
if (t == null)
return typeof(return).init.takeNone.inputRangeObject;
return [t.left, t.right]
.filter!(t => t != null)
.map!(a => self(a))
.joiner
.chain([*t])
.inputRangeObject;
}
void main() {
alias N = Tree!int;
const tree = new N(1,
new N(2,
new N(4,
new N(7)),
new N(5)),
new N(3,
new N(6,
new N(8),
new N(9))));
tree.preOrder.map!(t => t.value).writeln;
tree.inOrder.map!(t => t.value).writeln;
tree.postOrder.map!(t => t.value).writeln;
}

View file

@ -0,0 +1,89 @@
{Structure holding node data}
type PNode = ^TNode;
TNode = record
Data: integer;
Left,Right: PNode;
end;
function PreOrder(Node: TNode): string;
{Recursively traverse Node-Left-Right}
begin
Result:=IntToStr(Node.Data);
if Node.Left<>nil then Result:=Result+' '+PreOrder(Node.Left^);
if Node.Right<>nil then Result:=Result+' '+PreOrder(Node.Right^);
end;
function InOrder(Node: TNode): string;
{Recursively traverse Left-Node-Right}
begin
Result:='';
if Node.Left<>nil then Result:=Result+inOrder(Node.Left^);
Result:=Result+IntToStr(Node.Data)+' ';
if Node.Right<>nil then Result:=Result+inOrder(Node.Right^);
end;
function PostOrder(Node: TNode): string;
{Recursively traverse Left-Right-Node}
begin
Result:='';
if Node.Left<>nil then Result:=Result+PostOrder(Node.Left^);
if Node.Right<>nil then Result:=Result+PostOrder(Node.Right^);
Result:=Result+IntToStr(Node.Data)+' ';
end;
function LevelOrder(Node: TNode): string;
{Traverse the tree at each level, Left to right}
var Queue: TList;
var NT: TNode;
begin
Queue:=TList.Create;
try
Result:='';
Queue.Add(@Node);
while true do
begin
{Display oldest node in queue}
NT:=PNode(Queue[0])^;
Queue.Delete(0);
Result:=Result+IntToStr(NT.Data)+' ';
{Queue left and right children}
if NT.left<>nil then Queue.add(NT.left);
if NT.right<>nil then Queue.add(NT.right);
if Queue.Count<1 then break;
end;
finally Queue.Free; end;
end;
procedure ShowBinaryTree(Memo: TMemo);
var Tree: array [0..9] of TNode;
var I: integer;
begin
{Fill array of node with data}
{that matchs its position in the array}
for I:=0 to High(Tree) do
begin
Tree[I].Data:=I+1;
Tree[I].Left:=nil;
Tree[I].Right:=nil;
end;
{Build the specified tree}
Tree[0].left:=@Tree[2-1];
Tree[0].right:=@Tree[3-1];
Tree[1].left:=@Tree[4-1];
Tree[1].right:=@Tree[5-1];
Tree[3].left:=@Tree[7-1];
Tree[2].left:=@Tree[6-1];
Tree[5].left:=@Tree[8-1];
Tree[5].right:=@Tree[9-1];
{Tranverse the tree in four specified ways}
Memo.Lines.Add('Pre-Order: '+PreOrder(Tree[0]));
Memo.Lines.Add('In-Order: '+InOrder(Tree[0]));
Memo.Lines.Add('Post-Order: '+PostOrder(Tree[0]));
Memo.Lines.Add('Level-Order: '+LevelOrder(Tree[0]));
end;

View file

@ -0,0 +1,76 @@
type
Node = struct {
int val;
*Node left, right;
},
Tree = *Node;
proc tree(int v; Tree l, r) Tree:
Tree t;
t := new(Node);
t*.val := v;
t*.left := l;
t*.right := r;
t
corp
proc preorder(Tree t) void:
if t /= nil then
write(t*.val, ' ');
preorder(t*.left);
preorder(t*.right)
fi
corp
proc inorder(Tree t) void:
if t /= nil then
inorder(t*.left);
write(t*.val, ' ');
inorder(t*.right)
fi
corp
proc postorder(Tree t) void:
if t /= nil then
postorder(t*.left);
postorder(t*.right);
write(t*.val, ' ')
fi
corp
proc levelorder(Tree t) void:
[256]Tree q;
word s, e;
s := 0;
q[s] := t;
e := 1;
while s /= e do
if q[s] /= nil then
q[e] := q[s]*.left;
q[e+1] := q[s]*.right;
e := e+2;
write(q[s]*.val, ' ')
fi;
s := s+1
od
corp
proc main() void:
Tree t;
t := tree(1,
tree(2,
tree(4,
tree(7,nil,nil),
nil),
tree(5,nil,nil)),
tree(3,
tree(6,
tree(8,nil,nil),
tree(9,nil,nil)),
nil));
write("preorder: "); preorder(t); writeln();
write("inorder: "); inorder(t); writeln();
write("postorder: "); postorder(t); writeln();
write("level-order: "); levelorder(t); writeln();
corp

View file

@ -0,0 +1,47 @@
def btree := [1, [2, [4, [7, null, null],
null],
[5, null, null]],
[3, [6, [8, null, null],
[9, null, null]],
null]]
def backtrackingOrder(node, pre, mid, post) {
switch (node) {
match ==null {}
match [value, left, right] {
pre(value)
backtrackingOrder(left, pre, mid, post)
mid(value)
backtrackingOrder(right, pre, mid, post)
post(value)
}
}
}
def levelOrder(root, func) {
var level := [root].diverge()
while (level.size() > 0) {
for node in level.removeRun(0) {
switch (node) {
match ==null {}
match [value, left, right] {
func(value)
level.push(left)
level.push(right)
} } } } }
print("preorder: ")
backtrackingOrder(btree, fn v { print(" ", v) }, fn _ {}, fn _ {})
println()
print("inorder: ")
backtrackingOrder(btree, fn _ {}, fn v { print(" ", v) }, fn _ {})
println()
print("postorder: ")
backtrackingOrder(btree, fn _ {}, fn _ {}, fn v { print(" ", v) })
println()
print("level-order:")
levelOrder(btree, fn v { print(" ", v) })
println()

View file

@ -0,0 +1,51 @@
note
description : "Application for tree traversal demonstration"
output : "[
Prints preorder, inorder, postorder and levelorder traversal of an example binary tree.
]"
author : "Jascha Grübel"
date : "$2014-01-07$"
revision : "$1.0$"
class
APPLICATION
create
make
feature {NONE} -- Initialization
make
-- Run Tree traversal example.
local
tree:NODE
do
create tree.make (1)
tree.set_left_child (create {NODE}.make (2))
tree.set_right_child (create {NODE}.make (3))
tree.left_child.set_left_child (create {NODE}.make (4))
tree.left_child.set_right_child (create {NODE}.make (5))
tree.left_child.left_child.set_left_child (create {NODE}.make (7))
tree.right_child.set_left_child (create {NODE}.make (6))
tree.right_child.left_child.set_left_child (create {NODE}.make (8))
tree.right_child.left_child.set_right_child (create {NODE}.make (9))
Io.put_string ("preorder: ")
tree.print_preorder
Io.put_new_line
Io.put_string ("inorder: ")
tree.print_inorder
Io.put_new_line
Io.put_string ("postorder: ")
tree.print_postorder
Io.put_new_line
Io.put_string ("level-order:")
tree.print_levelorder
Io.put_new_line
end
end -- class APPLICATION

View file

@ -0,0 +1,127 @@
note
description : "A simple node for a binary tree"
libraries : "Relies on LINKED_LIST from EiffelBase"
author : "Jascha Grübel"
date : "$2014-01-07$"
revision : "$1.0$"
implementation : "[
All traversals but the levelorder traversal have been implemented recursively.
The levelorder traversal is solved iteratively.
]"
class
NODE
create
make
feature {NONE} -- Initialization
make (a_value:INTEGER)
-- Creates a node with no children.
do
value := a_value
set_right_child(Void)
set_left_child(Void)
end
feature -- Modification
set_right_child (a_node:NODE)
-- Sets `right_child' to `a_node'.
do
right_child:=a_node
end
set_left_child (a_node:NODE)
-- Sets `left_child' to `a_node'.
do
left_child:=a_node
end
feature -- Representation
print_preorder
-- Recursively prints the value of the node and all its children in preorder
do
Io.put_string (" " + value.out)
if has_left_child then
left_child.print_preorder
end
if has_right_child then
right_child.print_preorder
end
end
print_inorder
-- Recursively prints the value of the node and all its children in inorder
do
if has_left_child then
left_child.print_inorder
end
Io.put_string (" " + value.out)
if has_right_child then
right_child.print_inorder
end
end
print_postorder
-- Recursively prints the value of the node and all its children in postorder
do
if has_left_child then
left_child.print_postorder
end
if has_right_child then
right_child.print_postorder
end
Io.put_string (" " + value.out)
end
print_levelorder
-- Iteratively prints the value of the node and all its children in levelorder
local
l_linked_list:LINKED_LIST[NODE]
l_node:NODE
do
from
create l_linked_list.make
l_linked_list.extend (Current)
until
l_linked_list.is_empty
loop
l_node := l_linked_list.first
if l_node.has_left_child then
l_linked_list.extend (l_node.left_child)
end
if l_node.has_right_child then
l_linked_list.extend (l_node.right_child)
end
Io.put_string (" " + l_node.value.out)
l_linked_list.prune (l_node)
end
end
feature -- Access
value:INTEGER
-- Value stored in the node.
right_child:NODE
-- Reference to right child, possibly void.
left_child:NODE
-- Reference to left child, possibly void.
has_right_child:BOOLEAN
-- Test right child for existence.
do
Result := right_child /= Void
end
has_left_child:BOOLEAN
-- Test left child for existence.
do
Result := left_child /= Void
end
end
-- class NODE

View file

@ -0,0 +1,121 @@
import extensions;
import extensions'routines;
import system'collections;
singleton DummyNode
{
get generic()
= EmptyEnumerable;
}
class Node
{
rprop int Value;
rprop Node Left;
rprop Node Right;
constructor new(int value)
{
Value := value
}
constructor new(int value, Node left)
{
Value := value;
Left := left;
}
constructor new(int value, Node left, Node right)
{
Value := value;
Left := left;
Right := right
}
Preorder = new Enumerable
{
Enumerator enumerator() = CompoundEnumerator.new(
SingleEnumerable.new(Value),
(Left ?? DummyNode).Preorder,
(Right ?? DummyNode).Preorder);
};
Inorder = new Enumerable
{
Enumerator enumerator()
{
if (nil != Left)
{
^ CompoundEnumerator.new(Left.Inorder, SingleEnumerable.new(Value), (Right ?? DummyNode).Inorder)
}
else
{
^ SingleEnumerable.new(Value).enumerator()
}
}
};
Postorder = new Enumerable
{
Enumerator enumerator()
{
if (nil == Left)
{
^ SingleEnumerable.new(Value).enumerator()
}
else if (nil == Right)
{
^ CompoundEnumerator.new(Left.Postorder, SingleEnumerable.new(Value))
}
else
{
^ CompoundEnumerator.new(Left.Postorder, Right.Postorder, SingleEnumerable.new(Value))
}
}
};
LevelOrder = new Enumerable
{
Queue<Node> queue := class Queue<Node>.allocate(4).push:self;
Enumerator enumerator() = new Enumerator
{
bool next() = queue.isNotEmpty();
get()
{
Node item := queue.pop();
Node left := item.Left;
Node right := item.Right;
if (nil != left)
{
queue.push(left)
};
if (nil != right)
{
queue.push(right)
};
^ item.Value
}
reset()
{
NotSupportedException.raise()
}
enumerable() = queue;
};
};
}
public program()
{
var tree := Node.new(1, Node.new(2, Node.new(4, Node.new(7)), Node.new(5)), Node.new(3, Node.new(6, Node.new(8), Node.new(9))));
console.printLine("Preorder :", tree.Preorder);
console.printLine("Inorder :", tree.Inorder);
console.printLine("Postorder :", tree.Postorder);
console.printLine("LevelOrder:", tree.LevelOrder)
}

View file

@ -0,0 +1,36 @@
component BinaryTreeTraversals (Tree, Element);
type Tree;
type Node = Tree;
Tree (LeftTree = Tree, Element, RightTree = Tree) -> Tree;
Leaf (Element) -> Node;
Node (Tree) -> Node;
Item (Node) -> Element;
Preorder (Tree) -> multi (Node);
Inorder (Tree) -> multi (Node);
Postorder (Tree) -> multi (Node);
Level_order(Tree) -> multi (Node);
begin
Tree (Lefttree, Item, Righttree) = Tree: [ Lefttree; Item; Righttree ];
Leaf (anItem) = Tree (null(Tree), anItem, null(Tree) );
Node (aTree) = aTree;
Item (aNode) = aNode.Item;
Preorder (=null(Tree)) = no(Tree);
Preorder (T) = ( T, Preorder (T.Lefttree), Preorder (T.Righttree));
Inorder (=null(Tree)) = no(Tree);
Inorder (T) = ( Inorder (T.Lefttree), T, Inorder (T.Righttree));
Postorder (=null(Tree)) = no(Tree);
Postorder (T) = ( Postorder (T.Lefttree), Postorder (T.Righttree), T);
Level_order(T) = [ Queue = {T};
node = Tree:items(Queue);
[ result(node);
add(Queue, node.Lefttree) when valid(node.Lefttree);
add(Queue, node.Righttree) when valid(node.Righttree);
];
no(Tree);
];
end component BinaryTreeTraversals;

View file

@ -0,0 +1,19 @@
use BinaryTreeTraversals (Tree, integer);
BT = Tree(
Tree(
Tree(Leaf(7), 4, null(Tree)), 2 , Leaf(5)), 1,
Tree(
Tree(Leaf(8), 6, Leaf(9)), 3 ,null(Tree)));
{Item(Preorder(BT))}?
{ 1, 2, 4, 7, 5, 3, 6, 8, 9}
{Item(Inorder(BT))}?
{ 7, 4, 2, 5, 1, 8, 6, 9, 3}
{Item(Postorder(BT))}?
{ 7, 4, 5, 2, 8, 9, 6, 3, 1}
{Item(Level_order(BT))}?
{ 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,42 @@
-module(tree_traversal).
-export([main/0]).
-export([preorder/2, inorder/2, postorder/2, levelorder/2]).
-export([tnode/0, tnode/1, tnode/3]).
-define(NEWLINE, io:format("~n")).
tnode() -> {}.
tnode(V) -> {node, V, {}, {}}.
tnode(V,L,R) -> {node, V, L, R}.
preorder(_,{}) -> ok;
preorder(F,{node,V,L,R}) ->
F(V), preorder(F,L), preorder(F,R).
inorder(_,{}) -> ok;
inorder(F,{node,V,L,R}) ->
inorder(F,L), F(V), inorder(F,R).
postorder(_,{}) -> ok;
postorder(F,{node,V,L,R}) ->
postorder(F,L), postorder(F,R), F(V).
levelorder(_, []) -> [];
levelorder(F, [{}|T]) -> levelorder(F, T);
levelorder(F, [{node,V,L,R}|T]) ->
F(V), levelorder(F, T++[L,R]);
levelorder(F, X) -> levelorder(F, [X]).
main() ->
Tree = tnode(1,
tnode(2,
tnode(4, tnode(7), tnode()),
tnode(5, tnode(), tnode())),
tnode(3,
tnode(6, tnode(8), tnode(9)),
tnode())),
F = fun(X) -> io:format("~p ",[X]) end,
preorder(F, Tree), ?NEWLINE,
inorder(F, Tree), ?NEWLINE,
postorder(F, Tree), ?NEWLINE,
levelorder(F, Tree), ?NEWLINE.

View file

@ -0,0 +1,67 @@
constant VALUE = 1, LEFT = 2, RIGHT = 3
constant tree = {1,
{2,
{4,
{7, 0, 0},
0},
{5, 0, 0}},
{3,
{6,
{8, 0, 0},
{9, 0, 0}},
0}}
procedure preorder(object tree)
if sequence(tree) then
printf(1,"%d ",{tree[VALUE]})
preorder(tree[LEFT])
preorder(tree[RIGHT])
end if
end procedure
procedure inorder(object tree)
if sequence(tree) then
inorder(tree[LEFT])
printf(1,"%d ",{tree[VALUE]})
inorder(tree[RIGHT])
end if
end procedure
procedure postorder(object tree)
if sequence(tree) then
postorder(tree[LEFT])
postorder(tree[RIGHT])
printf(1,"%d ",{tree[VALUE]})
end if
end procedure
procedure lo(object tree, sequence more)
if sequence(tree) then
more &= {tree[LEFT],tree[RIGHT]}
printf(1,"%d ",{tree[VALUE]})
end if
if length(more) > 0 then
lo(more[1],more[2..$])
end if
end procedure
procedure level_order(object tree)
lo(tree,{})
end procedure
puts(1,"preorder: ")
preorder(tree)
puts(1,'\n')
puts(1,"inorder: ")
inorder(tree)
puts(1,'\n')
puts(1,"postorder: ")
postorder(tree)
puts(1,'\n')
puts(1,"level-order: ")
level_order(tree)
puts(1,'\n')

View file

@ -0,0 +1,75 @@
open System
open System.IO
type Tree<'a> =
| Tree of 'a * Tree<'a> * Tree<'a>
| Empty
let rec inorder tree =
seq {
match tree with
| Tree(x, left, right) ->
yield! inorder left
yield x
yield! inorder right
| Empty -> ()
}
let rec preorder tree =
seq {
match tree with
| Tree(x, left, right) ->
yield x
yield! preorder left
yield! preorder right
| Empty -> ()
}
let rec postorder tree =
seq {
match tree with
| Tree(x, left, right) ->
yield! postorder left
yield! postorder right
yield x
| Empty -> ()
}
let levelorder tree =
let rec loop queue =
seq {
match queue with
| [] -> ()
| (Empty::tail) -> yield! loop tail
| (Tree(x, l, r)::tail) ->
yield x
yield! loop (tail @ [l; r])
}
loop [tree]
[<EntryPoint>]
let main _ =
let tree =
Tree (1,
Tree (2,
Tree (4,
Tree (7, Empty, Empty),
Empty),
Tree (5, Empty, Empty)),
Tree (3,
Tree (6,
Tree (8, Empty, Empty),
Tree (9, Empty, Empty)),
Empty))
let show x = printf "%d " x
printf "preorder: "
preorder tree |> Seq.iter show
printf "\ninorder: "
inorder tree |> Seq.iter show
printf "\npostorder: "
postorder tree |> Seq.iter show
printf "\nlevel-order: "
levelorder tree |> Seq.iter show
0

View file

@ -0,0 +1,72 @@
USING: accessors combinators deques dlists fry io kernel
math.parser ;
IN: rosetta.tree-traversal
TUPLE: node data left right ;
CONSTANT: example-tree
T{ node f 1
T{ node f 2
T{ node f 4
T{ node f 7 f f }
f
}
T{ node f 5 f f }
}
T{ node f 3
T{ node f 6
T{ node f 8 f f }
T{ node f 9 f f }
}
f
}
}
: preorder ( node quot: ( data -- ) -- )
[ [ data>> ] dip call ]
[ [ left>> ] dip over [ preorder ] [ 2drop ] if ]
[ [ right>> ] dip over [ preorder ] [ 2drop ] if ]
2tri ; inline recursive
: inorder ( node quot: ( data -- ) -- )
[ [ left>> ] dip over [ inorder ] [ 2drop ] if ]
[ [ data>> ] dip call ]
[ [ right>> ] dip over [ inorder ] [ 2drop ] if ]
2tri ; inline recursive
: postorder ( node quot: ( data -- ) -- )
[ [ left>> ] dip over [ postorder ] [ 2drop ] if ]
[ [ right>> ] dip over [ postorder ] [ 2drop ] if ]
[ [ data>> ] dip call ]
2tri ; inline recursive
: (levelorder) ( dlist quot: ( data -- ) -- )
over deque-empty? [ 2drop ] [
[ dup pop-front ] dip {
[ [ data>> ] dip call drop ]
[ drop left>> [ swap push-back ] [ drop ] if* ]
[ drop right>> [ swap push-back ] [ drop ] if* ]
[ nip (levelorder) ]
} 3cleave
] if ; inline recursive
: levelorder ( node quot: ( data -- ) -- )
[ 1dlist ] dip (levelorder) ; inline
: levelorder2 ( node quot: ( data -- ) -- )
[ 1dlist ] dip
[ dup deque-empty? not ] swap '[
dup pop-front
[ data>> @ ]
[ left>> [ over push-back ] when* ]
[ right>> [ over push-back ] when* ] tri
] while drop ; inline
: main ( -- )
example-tree [ number>string write " " write ] {
[ "preorder: " write preorder nl ]
[ "inorder: " write inorder nl ]
[ "postorder: " write postorder nl ]
[ "levelorder: " write levelorder nl ]
[ "levelorder2: " write levelorder2 nl ]
} 2cleave ;

View file

@ -0,0 +1,69 @@
class Tree
{
readonly Int label
readonly Tree? left
readonly Tree? right
new make (Int label, Tree? left := null, Tree? right := null)
{
this.label = label
this.left = left
this.right = right
}
Void preorder(|Int->Void| func)
{
func(label)
left?.preorder(func) // ?. will not call method if 'left' is null
right?.preorder(func)
}
Void postorder(|Int->Void| func)
{
left?.postorder(func)
right?.postorder(func)
func(label)
}
Void inorder(|Int->Void| func)
{
left?.inorder(func)
func(label)
right?.inorder(func)
}
Void levelorder(|Int->Void| func)
{
Tree[] nodes := [this]
while (nodes.size > 0)
{
Tree cur := nodes.removeAt(0)
func(cur.label)
if (cur.left != null) nodes.add (cur.left)
if (cur.right != null) nodes.add (cur.right)
}
}
}
class Main
{
public static Void main ()
{
tree := Tree(1,
Tree(2, Tree(4, Tree(7)), Tree(5)),
Tree(3, Tree(6, Tree(8), Tree(9))))
List result := [,]
collect := |Int a -> Void| { result.add(a) }
tree.preorder(collect)
echo ("preorder: " + result.join(" "))
result = [,]
tree.inorder(collect)
echo ("inorder: " + result.join(" "))
result = [,]
tree.postorder(collect)
echo ("postorder: " + result.join(" "))
result = [,]
tree.levelorder(collect)
echo ("levelorder: " + result.join(" "))
}
}

View file

@ -0,0 +1,56 @@
\ binary tree (dictionary)
: node ( l r data -- node ) here >r , , , r> ;
: leaf ( data -- node ) 0 0 rot node ;
: >data ( node -- ) @ ;
: >right ( node -- ) cell+ @ ;
: >left ( node -- ) cell+ cell+ @ ;
: preorder ( xt tree -- )
dup 0= if 2drop exit then
2dup >data swap execute
2dup >left recurse
>right recurse ;
: inorder ( xt tree -- )
dup 0= if 2drop exit then
2dup >left recurse
2dup >data swap execute
>right recurse ;
: postorder ( xt tree -- )
dup 0= if 2drop exit then
2dup >left recurse
2dup >right recurse
>data swap execute ;
: max-depth ( tree -- n )
dup 0= if exit then
dup >left recurse
swap >right recurse max 1+ ;
defer depthaction
: depthorder ( depth tree -- )
dup 0= if 2drop exit then
over 0=
if >data depthaction drop
else over 1- over >left recurse
swap 1- swap >right recurse
then ;
: levelorder ( xt tree -- )
swap is depthaction
dup max-depth 0 ?do
i over depthorder
loop drop ;
7 leaf 0 4 node
5 leaf 2 node
8 leaf 9 leaf 6 node
0 3 node 1 node value tree
cr ' . tree preorder \ 1 2 4 7 5 3 6 8 9
cr ' . tree inorder \ 7 4 2 5 1 8 6 9 3
cr ' . tree postorder \ 7 4 5 2 8 9 6 3 1
cr tree max-depth . \ 4
cr ' . tree levelorder \ 1 2 3 4 5 6 7 8 9

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,72 @@
#define NULL 0
Dim Shared As Byte maxnodos = 100
Dim Shared As Byte raiz = 0
Dim Shared As Byte izda = 1
Dim Shared As Byte dcha = 2
Dim Shared As Byte arbol(maxnodos, 3)
Sub crear_arbol()
arbol(1, raiz) = 1
arbol(1, izda) = 2 : arbol(1, dcha) = 3
arbol(2, raiz) = 2
arbol(2, izda) = 4 : arbol(2, dcha) = 5
arbol(3, raiz) = 3
arbol(3, izda) = 6 : arbol(3, dcha) = NULL
arbol(4, raiz) = 4
arbol(4, izda) = 7 : arbol(4, dcha) = NULL
arbol(5, raiz) = 5
arbol(5, izda) = NULL : arbol(5, dcha) = NULL
arbol(6, raiz) = 6
arbol(6, izda) = 8 : arbol(6, dcha) = 9
arbol(7, raiz) = 7
arbol(7, izda) = NULL : arbol(7, dcha) = NULL
arbol(8, raiz) = 8
arbol(8, izda) = NULL : arbol(8, dcha) = NULL
arbol(9, raiz) = 9
arbol(9, izda) = NULL : arbol(9, dcha) = NULL
End Sub
Sub recorrido_preorder(nodo As Byte)
If nodo <> NULL Then
Print arbol(nodo, raiz);
recorrido_preorder(arbol(nodo, izda))
recorrido_preorder(arbol(nodo, dcha))
End If
End Sub
Sub recorrido_postorder(nodo As Byte)
If nodo <> NULL Then
recorrido_postorder(arbol(nodo, izda))
recorrido_postorder(arbol(nodo, dcha))
Print arbol(nodo, raiz);
End If
End Sub
Sub recorrido_inorden(nodo As Byte)
If nodo <> NULL Then
recorrido_inorden(arbol(nodo, izda))
Print arbol(nodo, raiz);
recorrido_inorden(arbol(nodo, dcha))
End If
End Sub
Sub recorrido_ordenXnivel(nodo As Byte)
Dim As Byte actual = 1
Dim As Byte primero_libre = actual + 1
Dim As Byte cola(maxnodos)
cola(actual) = nodo
While cola(actual) <> NULL
If arbol(cola(actual), izda) <> NULL Then
cola(primero_libre) = arbol(cola(actual), izda)
primero_libre += 1
End If
If arbol(cola(actual), dcha) <> NULL Then
cola(primero_libre) = arbol(cola(actual), dcha)
primero_libre += 1
End If
Print arbol(cola(actual), raiz);
actual += 1
Wend
End Sub

View file

@ -0,0 +1,36 @@
data Tree = Empty | Node( value, left, right )
def
preorder( Empty ) = []
preorder( Node(v, l, r) ) = [v] + preorder( l ) + preorder( r )
inorder( Empty ) = []
inorder( Node(v, l, r) ) = inorder( l ) + [v] + inorder( r )
postorder( Empty ) = []
postorder( Node(v, l, r) ) = postorder( l ) + postorder( r ) + [v]
levelorder( x ) =
def
order( [] ) = []
order( Empty : xs ) = order( xs )
order( Node(v, l, r) : xs ) = v : order( xs + [l, r] )
order( [x] )
tree = Node( 1,
Node( 2,
Node( 4,
Node( 7, Empty, Empty ),
Empty ),
Node( 5, Empty, Empty ) ),
Node( 3,
Node( 6,
Node( 8, Empty, Empty ),
Node( 9, Empty, Empty ) ),
Empty ) )
println( preorder(tree) )
println( inorder(tree) )
println( postorder(tree) )
println( levelorder(tree) )

View file

@ -0,0 +1,116 @@
maxnodes%=100 ! set a limit to size of tree
content%=0 ! index of content field
left%=1 ! index of left tree
right%=2 ! index of right tree
DIM tree%(maxnodes%,3) ! create space for tree
'
OPENW 1
CLEARW 1
'
@create_tree
PRINT "Preorder: ";
@preorder_traversal(1)
PRINT ""
PRINT "Inorder: ";
@inorder_traversal(1)
PRINT ""
PRINT "Postorder: ";
@postorder_traversal(1)
PRINT ""
PRINT "Levelorder: ";
@levelorder_traversal(1)
PRINT ""
'
~INP(2)
CLOSEW 1
'
' Define the example tree
'
PROCEDURE create_tree
tree%(1,content%)=1
tree%(1,left%)=2
tree%(1,right%)=3
tree%(2,content%)=2
tree%(2,left%)=4
tree%(2,right%)=5
tree%(3,content%)=3
tree%(3,left%)=6
tree%(3,right%)=0 ! 0 is used for no subtree
tree%(4,content%)=4
tree%(4,left%)=7
tree%(4,right%)=0
tree%(5,content%)=5
tree%(5,left%)=0
tree%(5,right%)=0
tree%(6,content%)=6
tree%(6,left%)=8
tree%(6,right%)=9
tree%(7,content%)=7
tree%(7,left%)=0
tree%(7,right%)=0
tree%(8,content%)=8
tree%(8,left%)=0
tree%(8,right%)=0
tree%(9,content%)=9
tree%(9,left%)=0
tree%(9,right%)=0
RETURN
'
' Preorder traversal from given node
'
PROCEDURE preorder_traversal(node%)
IF node%<>0 ! 0 means there is no node
PRINT tree%(node%,content%);
preorder_traversal(tree%(node%,left%))
preorder_traversal(tree%(node%,right%))
ENDIF
RETURN
'
' Postorder traversal from given node
'
PROCEDURE postorder_traversal(node%)
IF node%<>0 ! 0 means there is no node
postorder_traversal(tree%(node%,left%))
postorder_traversal(tree%(node%,right%))
PRINT tree%(node%,content%);
ENDIF
RETURN
'
' Inorder traversal from given node
'
PROCEDURE inorder_traversal(node%)
IF node%<>0 ! 0 means there is no node
inorder_traversal(tree%(node%,left%))
PRINT tree%(node%,content%);
inorder_traversal(tree%(node%,right%))
ENDIF
RETURN
'
' Level order traversal from given node
'
PROCEDURE levelorder_traversal(node%)
LOCAL nodes%,first_free%,current%
'
' Set up initial queue of nodes
'
DIM nodes%(maxnodes%) ! some working space to store queue of nodes
current%=1
nodes%(current%)=node%
first_free%=current%+1
'
WHILE nodes%(current%)<>0
' add the children of current node onto queue
IF tree%(nodes%(current%),left%)<>0
nodes%(first_free%)=tree%(nodes%(current%),left%)
first_free%=first_free%+1
ENDIF
IF tree%(nodes%(current%),right%)<>0
nodes%(first_free%)=tree%(nodes%(current%),right%)
first_free%=first_free%+1
ENDIF
' print the current node content
PRINT tree%(nodes%(current%),content%);
' advance to next node
current%=current%+1
WEND
RETURN

View file

@ -0,0 +1,86 @@
package main
import "fmt"
type node struct {
value int
left, right *node
}
func (n *node) iterPreorder(visit func(int)) {
if n == nil {
return
}
visit(n.value)
n.left.iterPreorder(visit)
n.right.iterPreorder(visit)
}
func (n *node) iterInorder(visit func(int)) {
if n == nil {
return
}
n.left.iterInorder(visit)
visit(n.value)
n.right.iterInorder(visit)
}
func (n *node) iterPostorder(visit func(int)) {
if n == nil {
return
}
n.left.iterPostorder(visit)
n.right.iterPostorder(visit)
visit(n.value)
}
func (n *node) iterLevelorder(visit func(int)) {
if n == nil {
return
}
for queue := []*node{n}; ; {
n = queue[0]
visit(n.value)
copy(queue, queue[1:])
queue = queue[:len(queue)-1]
if n.left != nil {
queue = append(queue, n.left)
}
if n.right != nil {
queue = append(queue, n.right)
}
if len(queue) == 0 {
return
}
}
}
func main() {
tree := &node{1,
&node{2,
&node{4,
&node{7, nil, nil},
nil},
&node{5, nil, nil}},
&node{3,
&node{6,
&node{8, nil, nil},
&node{9, nil, nil}},
nil}}
fmt.Print("preorder: ")
tree.iterPreorder(visitor)
fmt.Println()
fmt.Print("inorder: ")
tree.iterInorder(visitor)
fmt.Println()
fmt.Print("postorder: ")
tree.iterPostorder(visitor)
fmt.Println()
fmt.Print("level-order: ")
tree.iterLevelorder(visitor)
fmt.Println()
}
func visitor(value int) {
fmt.Print(value, " ")
}

View file

@ -0,0 +1,71 @@
package main
import "fmt"
// flat, level-order representation.
// for node at index k, left child has index 2k, right child has index 2k+1.
// a value of -1 means the node does not exist.
type tree []int
func main() {
t := tree{1, 2, 3, 4, 5, 6, -1, 7, -1, -1, -1, 8, 9}
visitor := func(n int) {
fmt.Print(n, " ")
}
fmt.Print("preorder: ")
t.iterPreorder(visitor)
fmt.Print("\ninorder: ")
t.iterInorder(visitor)
fmt.Print("\npostorder: ")
t.iterPostorder(visitor)
fmt.Print("\nlevel-order: ")
t.iterLevelorder(visitor)
fmt.Println()
}
func (t tree) iterPreorder(visit func(int)) {
var traverse func(int)
traverse = func(k int) {
if k >= len(t) || t[k] == -1 {
return
}
visit(t[k])
traverse(2*k + 1)
traverse(2*k + 2)
}
traverse(0)
}
func (t tree) iterInorder(visit func(int)) {
var traverse func(int)
traverse = func(k int) {
if k >= len(t) || t[k] == -1 {
return
}
traverse(2*k + 1)
visit(t[k])
traverse(2*k + 2)
}
traverse(0)
}
func (t tree) iterPostorder(visit func(int)) {
var traverse func(int)
traverse = func(k int) {
if k >= len(t) || t[k] == -1 {
return
}
traverse(2*k + 1)
traverse(2*k + 2)
visit(t[k])
}
traverse(0)
}
func (t tree) iterLevelorder(visit func(int)) {
for _, n := range t {
if n != -1 {
visit(n)
}
}
}

View file

@ -0,0 +1,35 @@
def preorder;
preorder = { Node node ->
([node] + node.children().collect { preorder(it) }).flatten()
}
def postorder;
postorder = { Node node ->
(node.children().collect { postorder(it) } + [node]).flatten()
}
def inorder;
inorder = { Node node ->
def kids = node.children()
if (kids.empty) [node]
else if (kids.size() == 1 && kids[0].'@right') [node] + inorder(kids[0])
else inorder(kids[0]) + [node] + (kids.size()>1 ? inorder(kids[1]) : [])
}
def levelorder = { Node node ->
def nodeList = []
def level = [node]
while (!level.empty) {
nodeList += level
def nextLevel = level.collect { it.children() }.flatten()
level = nextLevel
}
nodeList
}
class BinaryNodeBuilder extends NodeBuilder {
protected Object postNodeCompletion(Object parent, Object node) {
assert node.children().size() < 3
node
}
}

View file

@ -0,0 +1,10 @@
try {
new BinaryNodeBuilder().'1' {
a {}
b {}
c {}
}
println 'not limited to binary tree\r\n'
} catch (org.codehaus.groovy.transform.powerassert.PowerAssertionError e) {
println 'limited to binary tree\r\n'
}

View file

@ -0,0 +1,17 @@
// 1
// / \
// 2 3
// / \ /
// 4 5 6
// / / \
// 7 8 9
def tree1 = new BinaryNodeBuilder().
'1' {
'2' {
'4' { '7' {} }
'5' {}
}
'3' {
'6' { '8' {}; '9' {} }
}
}

View file

@ -0,0 +1,17 @@
// 1
// / \
// 2 3
// / \ /
// 4 5 6
// \ / \
// 7 8 9
def tree2 = new BinaryNodeBuilder().
'1' {
'2' {
'4' { '7'(right:true) {} }
'5' {}
}
'3' {
'6' { '8' {}; '9' {} }
}
}

View file

@ -0,0 +1,15 @@
def test = { tree ->
println "preorder: ${preorder(tree).collect{it.name()}}"
println "preorder: ${tree.depthFirst().collect{it.name()}}"
println "postorder: ${postorder(tree).collect{it.name()}}"
println "inorder: ${inorder(tree).collect{it.name()}}"
println "level-order: ${levelorder(tree).collect{it.name()}}"
println "level-order: ${tree.breadthFirst().collect{it.name()}}"
println()
}
test(tree1)
test(tree2)

View file

@ -0,0 +1,70 @@
---------------------- TREE TRAVERSAL --------------------
data Tree a
= Empty
| Node
{ value :: a,
left :: Tree a,
right :: Tree a
}
preorder, inorder, postorder, levelorder :: Tree a -> [a]
preorder Empty = []
preorder (Node v l r) = v : preorder l <> preorder r
inorder Empty = []
inorder (Node v l r) = inorder l <> (v : inorder r)
postorder Empty = []
postorder (Node v l r) = postorder l <> postorder r <> [v]
levelorder x = loop [x]
where
loop [] = []
loop (Empty : xs) = loop xs
loop (Node v l r : xs) = v : loop (xs <> [l, r])
--------------------------- TEST -------------------------
tree :: Tree Int
tree =
Node
1
( Node
2
(Node 4 (Node 7 Empty Empty) Empty)
(Node 5 Empty Empty)
)
( Node
3
(Node 6 (Node 8 Empty Empty) (Node 9 Empty Empty))
Empty
)
asciiTree :: String
asciiTree =
unlines
[ " 1",
" / \\",
" / \\",
" / \\",
" 2 3",
" / \\ /",
" 4 5 6",
" / / \\",
" 7 8 9"
]
-------------------------- OUTPUT ------------------------
main :: IO ()
main = do
putStrLn asciiTree
mapM_ putStrLn $
zipWith
( \s xs ->
justifyLeft 14 ' ' (s <> ":")
<> unwords (show <$> xs)
)
["preorder", "inorder", "postorder", "level-order"]
([preorder, inorder, postorder, levelorder] <*> [tree])
where
justifyLeft n c s = take n (s <> replicate n c)

View file

@ -0,0 +1,88 @@
import Data.Bool (bool)
import Data.Tree (Tree (..), drawForest, drawTree, foldTree)
---------------------- TREE TRAVERSAL --------------------
inorder, postorder, preorder :: a -> [[a]] -> [a]
inorder x [] = [x]
inorder x (y : xs) = y <> [x] <> concat xs
postorder x xs = concat xs <> [x]
preorder x xs = x : concat xs
levelOrder :: Tree a -> [a]
levelOrder = concat . levels
levels :: Tree a -> [[a]]
levels tree = go tree []
where
go (Node x xs) a =
let (h, t) = case a of
[] -> ([], [])
(y : ys) -> (y, ys)
in (x : h) : foldr go t xs
nodeCount,
treeDepth,
treeMax,
treeMin,
treeProduct,
treeSum,
treeWidth ::
Int -> [Int] -> Int
nodeCount = const (succ . sum)
treeDepth = const (succ . foldr max 1)
treeMax x xs = maximum (x : xs)
treeMin x xs = minimum (x : xs)
treeProduct x xs = x * product xs
treeSum x xs = x + sum xs
treeWidth _ [] = 1
treeWidth _ xs = sum xs
treeLeaves :: Tree a -> [a]
treeLeaves = foldTree go
where
go x [] = [x]
go _ xs = concat xs
--------------------------- TEST -------------------------
tree :: Tree Int
tree =
Node
1
[ Node 2 [Node 4 [Node 7 []], Node 5 []],
Node 3 [Node 6 [Node 8 [], Node 9 []]]
]
main :: IO ()
main = do
putStrLn $ drawTree $ fmap show tree
mapM_
print
( [foldTree]
<*> [preorder, inorder, postorder]
<*> [tree]
)
print $ levelOrder tree
putStrLn ""
(putStrLn . unlines)
( ( \(k, f) ->
justifyRight 7 ' ' k
<> " -> "
<> justifyLeft 6 ' ' (show $ foldTree f tree)
)
<$> [ ("Count", nodeCount),
("Layers", treeDepth),
("Max", treeMax),
("Min", treeMin),
("Product", treeProduct),
("Sum", treeSum),
("Leaves", treeWidth)
]
)
justifyLeft, justifyRight :: Int -> Char -> String -> String
justifyLeft n c s = take n (s <> replicate n c)
justifyRight n c = (drop . length) <*> (replicate n c <>)

View file

@ -0,0 +1,32 @@
procedure main()
bTree := [1, [2, [4, [7]], [5]], [3, [6, [8], [9]]]]
showTree(bTree, preorder|inorder|postorder|levelorder)
end
procedure showTree(tree, f)
writes(image(f),":\t")
every writes(" ",f(tree)[1])
write()
end
procedure preorder(L)
if \L then suspend L | preorder(L[2|3])
end
procedure inorder(L)
if \L then suspend inorder(L[2]) | L | inorder(L[3])
end
procedure postorder(L)
if \L then suspend postorder(L[2|3]) | L
end
procedure levelorder(L)
if \L then {
queue := [L]
while nextnode := get(queue) do {
every put(queue, \nextnode[2|3])
suspend nextnode
}
}
end

View file

@ -0,0 +1,79 @@
theory Tree
imports Main
begin
datatype 'a tree = Leaf | Node "'a tree" 'a "'a tree"
definition example :: "int tree" where
"example =
Node
(Node
(Node
(Node Leaf 7 Leaf)
4
Leaf
)
2
(Node Leaf 5 Leaf)
)
1
(Node
(Node
(Node Leaf 8 Leaf)
6
(Node Leaf 9 Leaf)
)
3
Leaf
)"
fun preorder :: "'a tree ? 'a list" where
"preorder Leaf = []"
| "preorder (Node l a r) = a # preorder l @ preorder r"
lemma "preorder example = [1, 2, 4, 7, 5, 3, 6, 8, 9]" by code_simp
fun inorder :: "'a tree ? 'a list" where
"inorder Leaf = []"
| "inorder (Node l a r) = inorder l @ [a] @ inorder r"
lemma "inorder example = [7, 4, 2, 5, 1, 8, 6, 9, 3]" by code_simp
fun postorder :: "'a tree ? 'a list" where
"postorder Leaf = []"
| "postorder (Node l a r) = postorder l @ postorder r @ [a]"
lemma "postorder example = [7, 4, 5, 2, 8, 9, 6, 3, 1]" by code_simp
lemma
"set (inorder t) = set (preorder t)"
"set (preorder t) = set (postorder t)"
"set (inorder t) = set (postorder t)"
by(induction t, simp, simp)+
text
For a breadth first search, we will have a queue of the nodes we still
want to visit. The type of the queue is \<^typ>'a tree list.
With each step, summing the sizes of the subtrees in the queue,
the queue gets smaller. Thus, the breadth first search terminates.
Isabelle cannot figure out this termination argument automatically,
so we provide some help by defining what the size of a tree is.
fun tree_size :: "'a tree ? nat" where
"tree_size Leaf = 1"
| "tree_size (Node l _ r) = 1 + tree_size l + tree_size r"
function (sequential) bfs :: "'a tree list ? 'a list" where
"bfs [] = []"
| "bfs (Leaf#q) = bfs q"
| "bfs ((Node l a r)#q) = a # bfs (q @ [l,r])"
by pat_completeness auto
termination bfs
by(relation "measure (?qs. sum_list (map tree_size qs))") simp+
fun levelorder :: "'a tree ? 'a list" where
"levelorder t = bfs [t]"
lemma "levelorder example = [1, 2, 3, 4, 5, 6, 7, 8, 9]" by code_simp
end

View file

@ -0,0 +1,4 @@
preorder=: ]S:0
postorder=: ([:; postorder&.>@}.) , >@{.
levelorder=: ;@({::L:1 _~ [: (/: #@>) <S:1@{::)
inorder=: ([:; inorder&.>@(''"_`(1&{)@.(1<#))) , >@{. , [:; inorder&.>@}.@}.

View file

@ -0,0 +1,53 @@
dataorder=: /:@data reorder ]
levelorder=: /:@depth@parent reorder ]
inorder=: inperm@parent reorder ]
inperm=:3 :0
chil=. childinds y
node=. {.I.(= i.@#) y
todo=. i.0 2
r=. i.0
whilst. (#todo)+.0<:node do.
if. 0 <: node do.
if. 0 <: {.ch=. node{chil do.
todo=. todo, node,{:ch
node=. {.ch
else.
r=. r, node
node=. _1 end.
else.
r=. r, {.ch=. {: todo
todo=. }: todo
node=. {:ch end. end.
r
)
postorder=: postperm@parent reorder ]
postperm=:3 :0
chil=. 0,1+childinds y
todo=. 1+I.(= i.@#) y
r=. i.0
whilst. (#todo) do.
node=. {: todo
todo=. }: todo
if. 0 < node do.
if. #ch=. (node{chil)-.0 do.
todo=. todo,(-node),|.ch
else.
r=. r, <:node end.
else.
r=. r, <:|node end. end.
)
preorder=: preperm@parent reorder ]
preperm=:3 :0
chil=. childinds y
todo=. I.(= i.@#) y
r=. i.0
whilst. (#todo) do.
r=. r,node=. {: todo
todo=. }: todo
if. #ch=. (node{chil)-._1 do.
todo=. todo,|.ch end. end.
r
)

View file

@ -0,0 +1,12 @@
levelorder dataorder example
1 2 3 4 5 6 7 8 9
0 0 0 1 1 2 3 5 5
inorder dataorder example
7 4 2 5 1 8 6 9 3
1 2 4 2 4 6 8 6 4
preorder dataorder example
1 2 4 7 5 3 6 8 9
0 0 1 2 1 0 5 6 6
postorder dataorder example
7 4 5 2 8 9 6 3 1
1 3 3 8 6 6 7 8 8

View file

@ -0,0 +1,5 @@
N2=: conjunction def '(<m),(<n),<y'
N1=: adverb def '(<m),<y'
L=: adverb def '<m'
tree=: 1 N2 (2 N2 (4 N1 (7 L)) 5 L) 3 N1 6 N2 (8 L) 9 L

View file

@ -0,0 +1,2 @@
preorder tree
1 2 4 7 5 3 6 8 9

View file

@ -0,0 +1,2 @@
postorder tree
7 4 5 2 8 9 6 3 1

View file

@ -0,0 +1,2 @@
inorder tree
7 4 2 5 1 8 6 9 3

View file

@ -0,0 +1,2 @@
levelorder tree
1 2 3 4 5 6 7 8 9

View file

@ -0,0 +1 @@
tree=: 1 N2 (2 N2 (4 N1 (7 L)) (5 L)) (3 N1 (6 N2 (8 L) (9 L)))

View file

@ -0,0 +1 @@
example=:1 8 3 4 7 5 9 6 2,: 0 7 0 8 3 8 7 2 0

View file

@ -0,0 +1,13 @@
depth=: +/@((~: , (~: i.@#@{.)~) {:@,)@({~^:a:)
reorder=:4 :0
'data parent'=. y
data1=. x{data
parent1=. x{data1 i. parent{data
if. 0=L.y do. data1,:parent1 else. data1;parent1 end.
)
data=:3 :'data[''data parent''=. y'
parent=:3 :'parent[''data parent''=. y'
childinds=: [: <:@(2&{.@-.&> #\) (</. #\)`(]~.)`(a:"0)}~

View file

@ -0,0 +1,87 @@
import java.util.*;
public class TreeTraversal {
static class Node<T> {
T value;
Node<T> left;
Node<T> right;
Node(T value) {
this.value = value;
}
void visit() {
System.out.print(this.value + " ");
}
}
static enum ORDER {
PREORDER, INORDER, POSTORDER, LEVEL
}
static <T> void traverse(Node<T> node, ORDER order) {
if (node == null) {
return;
}
switch (order) {
case PREORDER:
node.visit();
traverse(node.left, order);
traverse(node.right, order);
break;
case INORDER:
traverse(node.left, order);
node.visit();
traverse(node.right, order);
break;
case POSTORDER:
traverse(node.left, order);
traverse(node.right, order);
node.visit();
break;
case LEVEL:
Queue<Node<T>> queue = new LinkedList<>();
queue.add(node);
while(!queue.isEmpty()){
Node<T> next = queue.remove();
next.visit();
if(next.left!=null)
queue.add(next.left);
if(next.right!=null)
queue.add(next.right);
}
}
}
public static void main(String[] args) {
Node<Integer> one = new Node<Integer>(1);
Node<Integer> two = new Node<Integer>(2);
Node<Integer> three = new Node<Integer>(3);
Node<Integer> four = new Node<Integer>(4);
Node<Integer> five = new Node<Integer>(5);
Node<Integer> six = new Node<Integer>(6);
Node<Integer> seven = new Node<Integer>(7);
Node<Integer> eight = new Node<Integer>(8);
Node<Integer> nine = new Node<Integer>(9);
one.left = two;
one.right = three;
two.left = four;
two.right = five;
three.left = six;
four.left = seven;
six.left = eight;
six.right = nine;
traverse(one, ORDER.PREORDER);
System.out.println();
traverse(one, ORDER.INORDER);
System.out.println();
traverse(one, ORDER.POSTORDER);
System.out.println();
traverse(one, ORDER.LEVEL);
}
}

View file

@ -0,0 +1,126 @@
import java.util.function.Consumer;
import java.util.Queue;
import java.util.LinkedList;
class TreeTraversal {
static class EmptyNode {
void accept(Visitor aVisitor) {}
void accept(LevelOrder aVisitor, Queue<EmptyNode> data) {}
}
static class Node<T> extends EmptyNode {
T data;
EmptyNode left = new EmptyNode();
EmptyNode right = new EmptyNode();
Node(T data) {
this.data = data;
}
Node<T> left(Node<?> aNode) {
this.left = aNode;
return this;
}
Node<T> right(Node<?> aNode) {
this.right = aNode;
return this;
}
void accept(Visitor aVisitor) {
aVisitor.visit(this);
}
void accept(LevelOrder aVisitor, Queue<EmptyNode> data) {
aVisitor.visit(this, data);
}
}
static abstract class Visitor {
Consumer<Node<?>> action;
Visitor(Consumer<Node<?>> action) {
this.action = action;
}
abstract <T> void visit(Node<T> aNode);
}
static class PreOrder extends Visitor {
PreOrder(Consumer<Node<?>> action) {
super(action);
}
<T> void visit(Node<T> aNode) {
action.accept(aNode);
aNode.left.accept(this);
aNode.right.accept(this);
}
}
static class InOrder extends Visitor {
InOrder(Consumer<Node<?>> action) {
super(action);
}
<T> void visit(Node<T> aNode) {
aNode.left.accept(this);
action.accept(aNode);
aNode.right.accept(this);
}
}
static class PostOrder extends Visitor {
PostOrder(Consumer<Node<?>> action) {
super(action);
}
<T> void visit(Node<T> aNode) {
aNode.left.accept(this);
aNode.right.accept(this);
action.accept(aNode);
}
}
static class LevelOrder extends Visitor {
LevelOrder(Consumer<Node<?>> action) {
super(action);
}
<T> void visit(Node<T> aNode) {
Queue<EmptyNode> queue = new LinkedList<>();
queue.add(aNode);
do {
queue.remove().accept(this, queue);
} while (!queue.isEmpty());
}
<T> void visit(Node<T> aNode, Queue<EmptyNode> queue) {
action.accept(aNode);
queue.add(aNode.left);
queue.add(aNode.right);
}
}
public static void main(String[] args) {
Node<Integer> tree = new Node<Integer>(1)
.left(new Node<Integer>(2)
.left(new Node<Integer>(4)
.left(new Node<Integer>(7)))
.right(new Node<Integer>(5)))
.right(new Node<Integer>(3)
.left(new Node<Integer>(6)
.left(new Node<Integer>(8))
.right(new Node<Integer>(9))));
Consumer<Node<?>> print = aNode -> System.out.print(aNode.data + " ");
tree.accept(new PreOrder(print));
System.out.println();
tree.accept(new InOrder(print));
System.out.println();
tree.accept(new PostOrder(print));
System.out.println();
tree.accept(new LevelOrder(print));
System.out.println();
}
}

View file

@ -0,0 +1,40 @@
function BinaryTree(value, left, right) {
this.value = value;
this.left = left;
this.right = right;
}
BinaryTree.prototype.preorder = function(f) {this.walk(f,['this','left','right'])}
BinaryTree.prototype.inorder = function(f) {this.walk(f,['left','this','right'])}
BinaryTree.prototype.postorder = function(f) {this.walk(f,['left','right','this'])}
BinaryTree.prototype.walk = function(func, order) {
for (var i in order)
switch (order[i]) {
case "this": func(this.value); break;
case "left": if (this.left) this.left.walk(func, order); break;
case "right": if (this.right) this.right.walk(func, order); break;
}
}
BinaryTree.prototype.levelorder = function(func) {
var queue = [this];
while (queue.length != 0) {
var node = queue.shift();
func(node.value);
if (node.left) queue.push(node.left);
if (node.right) queue.push(node.right);
}
}
// convenience function for creating a binary tree
function createBinaryTreeFromArray(ary) {
var left = null, right = null;
if (ary[1]) left = createBinaryTreeFromArray(ary[1]);
if (ary[2]) right = createBinaryTreeFromArray(ary[2]);
return new BinaryTree(ary[0], left, right);
}
var tree = createBinaryTreeFromArray([1, [2, [4, [7]], [5]], [3, [6, [8],[9]]]]);
print("*** preorder ***"); tree.preorder(print);
print("*** inorder ***"); tree.inorder(print);
print("*** postorder ***"); tree.postorder(print);
print("*** levelorder ***"); tree.levelorder(print);

View file

@ -0,0 +1,89 @@
(function () {
function preorder(n) {
return [n[v]].concat(
n[l] ? preorder(n[l]) : []
).concat(
n[r] ? preorder(n[r]) : []
);
}
function inorder(n) {
return (
n[l] ? inorder(n[l]) : []
).concat(
n[v]
).concat(
n[r] ? inorder(n[r]) : []
);
}
function postorder(n) {
return (
n[l] ? postorder(n[l]) : []
).concat(
n[r] ? postorder(n[r]) : []
).concat(
n[v]
);
}
function levelorder(n) {
return (function loop(x) {
return x.length ? (
x[0] ? (
[x[0][v]].concat(
loop(
x.slice(1).concat(
[x[0][l], x[0][r]]
)
)
)
) : loop(x.slice(1))
) : [];
})([n]);
}
var v = 0,
l = 1,
r = 2,
tree = [1,
[2,
[4,
[7]
],
[5]
],
[3,
[6,
[8],
[9]
]
]
],
lstTest = [["Traversal", "Nodes visited"]].concat(
[preorder, inorder, postorder, levelorder].map(
function (f) {
return [f.name, f(tree)];
}
)
);
// [[a]] -> bool -> s -> s
function wikiTable(lstRows, blnHeaderRow, strStyle) {
return '{| class="wikitable" ' + (
strStyle ? 'style="' + strStyle + '"' : ''
) + lstRows.map(function (lstRow, iRow) {
var strDelim = ((blnHeaderRow && !iRow) ? '!' : '|');
return '\n|-\n' + strDelim + ' ' + lstRow.map(function (v) {
return typeof v === 'undefined' ? ' ' : v;
}).join(' ' + strDelim + strDelim + ' ');
}).join('') + '\n|}';
}
return wikiTable(lstTest, true) + '\n\n' + JSON.stringify(lstTest);
})();

View file

@ -0,0 +1,3 @@
[["Traversal","Nodes visited"],
["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]],["levelorder",[1,2,3,4,5,6,7,8,9]]]

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,128 @@
(() => {
"use strict";
// preorder :: a -> [[a]] -> [a]
const preorder = x =>
xs => [x, ...xs.flat()];
// inorder :: a -> [[a]] -> [a]
const inorder = x =>
xs => Boolean(xs.length) ? (
[...xs[0], x, ...xs.slice(1).flat()]
) : [x];
// postorder :: a -> [[a]] -> [a]
const postorder = x =>
xs => [...xs.flat(), x];
// levelOrder :: Tree a -> [a]
const levelOrder = tree =>
levels(tree).flat();
// ------------------------TEST------------------------
// main :: IO ()
const main = () => {
const tree = Node(1)([
Node(2)([
Node(4)([
Node(7)([])
]),
Node(5)([])
]),
Node(3)([
Node(6)([
Node(8)([]),
Node(9)([])
])
])
]);
// Generated by code in Rosetta Code
// task: 'Visualize a tree'
console.log([
" + 4 - 7",
" + 2 ¦",
" ¦ + 5",
" 1 ¦",
" ¦ + 8",
" + 3 - 6 ¦",
" + 9"
].join("\n"));
[preorder, inorder, postorder]
.forEach(f => console.log(
justifyRight(11)(" ")(`${f.name}:`),
foldTree(f)(
tree
)
));
console.log(
`levelOrder: ${levelOrder(tree)}`
);
};
// ---------------------- TREES ----------------------
// Node :: a -> [Tree a] -> Tree a
const Node = v =>
// Constructor for a Tree node which connects a
// value of some kind to a list of zero or
// more child trees.
xs => ({
type: "Node",
root: v,
nest: xs || []
});
// foldTree :: (a -> [b] -> b) -> Tree a -> b
const foldTree = f => {
// The catamorphism on trees. A summary
// value obtained by a depth-first fold.
const go = tree => f(
tree.root
)(
tree.nest.map(go)
);
return go;
};
// levels :: Tree a -> [[a]]
const levels = tree => {
// A list of lists, grouping the root
// values of each level of the tree.
const go = (a, node) => {
const [h, ...t] = 0 < a.length ? a : [
[]
];
return [
[node.root, ...h],
...node.nest.reduceRight(go, t)
];
};
return go([], tree);
};
// --------------------- GENERIC ---------------------
// justifyRight :: Int -> Char -> String -> String
const justifyRight = n =>
// The string s, preceded by enough padding (with
// the character c) to reach the string length n.
c => s => Boolean(s) ? (
s.padStart(n, c)
) : "";
// MAIN ---
return main();
})();

View file

@ -0,0 +1,26 @@
def preorder:
if length == 0 then empty
else .[0], (.[1]|preorder), (.[2]|preorder)
end;
def inorder:
if length == 0 then empty
else (.[1]|inorder), .[0] , (.[2]|inorder)
end;
def postorder:
if length == 0 then empty
else (.[1] | postorder), (.[2]|postorder), .[0]
end;
# Helper functions for levelorder:
# Produce a stream of the first elements
def heads: map( .[0] | select(. != null)) | .[];
# Produce a stream of the left/right branches:
def tails:
if length == 0 then empty
else [map ( .[1], .[2] ) | .[] | select( . != null)]
end;
def levelorder: [.] | recurse( tails ) | heads;

View file

@ -0,0 +1,17 @@
def task:
# [node, left, right]
def atree: [1, [2, [4, [7,[],[]],
[]],
[5, [],[]]],
[3, [6, [8,[],[]],
[9,[],[]]],
[]]] ;
"preorder: \( [atree|preorder ])",
"inorder: \( [atree|inorder ])",
"postorder: \( [atree|postorder ])",
"levelorder: \( [atree|levelorder])"
;
task

View file

@ -0,0 +1,26 @@
tree = Any[1, Any[2, Any[4, Any[7, Any[],
Any[]],
Any[]],
Any[5, Any[],
Any[]]],
Any[3, Any[6, Any[8, Any[],
Any[]],
Any[9, Any[],
Any[]]],
Any[]]]
preorder(t, f) = if !isempty(t)
f(t[1]); preorder(t[2], f); preorder(t[3], f)
end
inorder(t, f) = if !isempty(t)
inorder(t[2], f); f(t[1]); inorder(t[3], f)
end
postorder(t, f) = if !isempty(t)
postorder(t[2], f); postorder(t[3], f); f(t[1])
end
levelorder(t, f) = while !isempty(t)
t = mapreduce(x -> isa(x, Number) ? (f(x); []) : x, vcat, t)
end

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 @@
fun main(args: Array<String>) {
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()
}
}
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

@ -0,0 +1,34 @@
{def walk
{def walk.r
{lambda {:o :t}
{if {W.equal? :t nil}
then
else {if {W.equal? :o preorder} then {A.get 0 :t} else}
{walk.r :order {A.get 1 :t}}
{if {W.equal? :o inorder} then {A.get 0 :t} else}
{walk.r :order {A.get 2 :t}}
{if {W.equal? :o postorder} then {A.get 0 :t} else} }}}
{lambda {:o :t}
{S.replace \s by space in {walk.r :o :t}}}}
{def sort
{lambda {:o :t} {S.sort :o {walk preorder :t}}}}
{def T
{A.new 1
{A.new 2
{A.new 4
{A.new 7 nil nil} nil}
{A.new 5 nil nil}}
{A.new 3
{A.new 6
{A.new 8 nil nil}
{A.new 9 nil nil}} nil}}}
{walk preorder {T}} -> 1 2 4 7 5 3 6 8 9
{walk inorder {T}} -> 7 4 2 5 1 8 6 9 3
{walk postorder {T}} -> 7 4 5 2 8 9 6 3 1
{sort < {T}} -> 1 2 3 4 5 6 7 8 9
{sort > {T}} -> 9 8 7 6 5 4 3 2 1

View file

@ -0,0 +1,28 @@
-- parent script "BinaryTreeNode"
property _val, _left, _right
on new (me, val)
me._val = val
return me
end
on getValue (me)
return me._val
end
on setLeft (me, node)
me._left = node
end
on setRight (me, node)
me._right = node
end
on getLeft (me)
return me._left
end
on getRight (me)
return me._right
end

View file

@ -0,0 +1,51 @@
-- parent script "BinaryTreeTraversal"
on inOrder (me, node, l)
if voidP(l) then l = []
if voidP(node) then return l
if not voidP(node.getLeft()) then l = me.inOrder(node.getLeft(), l)
l.add(node)
if not voidP(node.getRight()) then l = me.inOrder(node.getRight(), l)
return l
end
on preOrder (me, node, l)
if voidP(l) then l = []
if voidP(node) then return l
l.add(node)
if not voidP(node.getLeft()) then l = me.preOrder(node.getLeft(), l)
if not voidP(node.getRight()) then l = me.preOrder(node.getRight(), l)
return l
end
on postOrder (me, node, l)
if voidP(l) then l = []
if voidP(node) then return l
if not voidP(node.getLeft()) then l = me.postOrder(node.getLeft(), l)
if not voidP(node.getRight()) then l = me.postOrder(node.getRight(), l)
l.add(node)
return l
end
on levelOrder (me, node)
l = []
queue = [node]
repeat while queue.count
node = queue[1]
queue.deleteAt(1)
l.add(node)
if not voidP(node.getLeft()) then queue.add(node.getLeft())
if not voidP(node.getRight()) then queue.add(node.getRight())
end repeat
return l
end
-- print utility function
on serialize (me, l)
str = ""
repeat with node in l
put node.getValue()&" " after str
end repeat
delete the last char of str
return str
end

View file

@ -0,0 +1,20 @@
-- create the tree
l = []
repeat with i = 1 to 10
l[i] = script("BinaryTreeNode").new(i)
end repeat
l[6].setLeft (l[8])
l[6].setRight(l[9])
l[3].setLeft (l[6])
l[4].setLeft (l[7])
l[2].setLeft (l[4])
l[2].setRight(l[5])
l[1].setLeft (l[2])
l[1].setRight(l[3])
-- print traversal results
trav = script("BinaryTreeTraversal")
put "preorder: " & trav.serialize(trav.preOrder(l[1]))
put "inorder: " & trav.serialize(trav.inOrder(l[1]))
put "postorder: " & trav.serialize(trav.postOrder(l[1]))
put "level-order: " & trav.serialize(trav.levelOrder(l[1]))

View file

@ -0,0 +1,57 @@
; nodes are [data left right], use "first" to get data
to node.left :node
if empty? butfirst :node [output []]
output first butfirst :node
end
to node.right :node
if empty? butfirst :node [output []]
if empty? butfirst butfirst :node [output []]
output first butfirst butfirst :node
end
to max :a :b
output ifelse :a > :b [:a] [:b]
end
to tree.depth :tree
if empty? :tree [output 0]
output 1 + max tree.depth node.left :tree tree.depth node.right :tree
end
to pre.order :tree :action
if empty? :tree [stop]
invoke :action first :tree
pre.order node.left :tree :action
pre.order node.right :tree :action
end
to in.order :tree :action
if empty? :tree [stop]
in.order node.left :tree :action
invoke :action first :tree
in.order node.right :tree :action
end
to post.order :tree :action
if empty? :tree [stop]
post.order node.left :tree :action
post.order node.right :tree :action
invoke :action first :tree
end
to at.depth :n :tree :action
if empty? :tree [stop]
ifelse :n = 1 [invoke :action first :tree] [
at.depth :n-1 node.left :tree :action
at.depth :n-1 node.right :tree :action
]
end
to level.order :tree :action
for [i 1 [tree.depth :tree]] [at.depth :i :tree :action]
end
make "tree [1 [2 [4 [7]]
[5]]
[3 [6 [8]
[9]]]]
pre.order :tree [(type ? "| |)] (print)
in.order :tree [(type ? "| |)] (print)
post.order :tree [(type ? "| |)] (print)
level.order :tree [(type ? "| |)] (print)

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,35 @@
local function depth_first(tr, a, b, c, flat_list)
for _, val in ipairs({a, b, c}) do
if type(tr[val]) == "table" then
depth_first(tr[val], a, b, c, flat_list)
elseif type(tr[val]) ~= "nil" then
table.insert(flat_list, tr[val])
end -- if
end -- for
return flat_list
end
local function flatten_pre_order(tr) return depth_first(tr, 1, 2, 3, {}) end
local function flatten_in_order(tr) return depth_first(tr, 2, 1, 3, {}) end
local function flatten_post_order(tr) return depth_first(tr, 2, 3, 1, {}) end
local function flatten_level_order(tr)
local flat_list, queue = {}, {tr}
while next(queue) do -- while queue is not empty
local node = table.remove(queue, 1) -- dequeue
if type(node) == "table" then
table.insert(flat_list, node[1])
table.insert(queue, node[2]) -- enqueue
table.insert(queue, node[3]) -- enqueue
else
table.insert(flat_list, node)
end -- if
end -- while
return flat_list
end
-- Example
local tree = {1, {2, {4, 7}, 5}, {3, {6, 8, 9}}}
print("Pre order: " .. table.concat(flatten_pre_order(tree), " "))
print("In order: " .. table.concat(flatten_in_order(tree), " "))
print("Post order: " .. table.concat(flatten_post_order(tree), " "))
print("Level order: " .. table.concat(flatten_level_order(tree), " "))

View file

@ -0,0 +1,59 @@
Module CheckIt {
Null=(,)
Tree=((((Null,7,Null),4,Null),2,(Null,5,Null)),1,(((Null,8,Null),6,(Null,9,Null)),3,Null))
Module preorder (T) {
Print "preorder: ";
printtree(T)
Print
sub printtree(T)
Print T#val(1);" ";
If len(T#val(0))>0 then printtree(T#val(0))
If len(T#val(2))>0 then printtree(T#val(2))
end sub
}
preorder Tree
Module inorder (T) {
Print "inorder: ";
printtree(T)
Print
sub printtree(T)
If len(T#val(0))>0 then printtree(T#val(0))
Print T#val(1);" ";
If len(T#val(2))>0 then printtree(T#val(2))
end sub
}
inorder Tree
Module postorder (T) {
Print "postorder: ";
printtree(T)
Print
sub printtree(T)
If len(T#val(0))>0 then printtree(T#val(0))
If len(T#val(2))>0 then printtree(T#val(2))
Print T#val(1);" ";
end sub
}
postorder Tree
Module level_order (T) {
Print "level-order: ";
Stack New {
printtree(T)
if empty then exit
Read T
Loop
}
Print
sub printtree(T)
If Len(T)>0 then
Print T#val(1);" ";
Data T#val(0), T#val(2)
end if
end sub
}
level_order Tree
}
CheckIt

Some files were not shown because too many files have changed in this diff Show more