mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-30 01:44:37 +00:00
108 lines
2.7 KiB
Nim
108 lines
2.7 KiB
Nim
discard """
|
|
file: "tbintree.nim"
|
|
output: "helloworld99110223"
|
|
"""
|
|
type
|
|
TBinaryTree[T] = object # TBinaryTree is a generic type with
|
|
# with generic param ``T``
|
|
le, ri: ref TBinaryTree[T] # left and right subtrees; may be nil
|
|
data: T # the data stored in a node
|
|
PBinaryTree*[A] = ref TBinaryTree[A] # type that is exported
|
|
|
|
proc newNode*[T](data: T): PBinaryTree[T] =
|
|
# constructor for a node
|
|
new(result)
|
|
result.data = data
|
|
|
|
proc add*[Ty](root: var PBinaryTree[Ty], n: PBinaryTree[Ty]) =
|
|
# insert a node into the tree
|
|
if root == nil:
|
|
root = n
|
|
else:
|
|
var it = root
|
|
while it != nil:
|
|
# compare the data items; uses the generic ``cmp`` proc that works for
|
|
# any type that has a ``==`` and ``<`` operator
|
|
var c = cmp(n.data, it.data)
|
|
if c < 0:
|
|
if it.le == nil:
|
|
it.le = n
|
|
return
|
|
it = it.le
|
|
else:
|
|
if it.ri == nil:
|
|
it.ri = n
|
|
return
|
|
it = it.ri
|
|
|
|
proc add*[Ty](root: var PBinaryTree[Ty], data: Ty) =
|
|
# convenience proc:
|
|
add(root, newNode(data))
|
|
|
|
proc find*[Ty2](b: PBinaryTree[Ty2], data: Ty2): bool =
|
|
# for testing this needs to be recursive, so that the
|
|
# instantiated type is checked for proper tyGenericInst envelopes
|
|
if b == nil:
|
|
result = false
|
|
else:
|
|
var c = cmp(data, b.data)
|
|
if c < 0: result = find(b.le, data)
|
|
elif c > 0: result = find(b.ri, data)
|
|
else: result = true
|
|
|
|
iterator preorder*[T](root: PBinaryTree[T]): T =
|
|
# Preorder traversal of a binary tree.
|
|
# Since recursive iterators are not yet implemented,
|
|
# this uses an explicit stack:
|
|
var stack: seq[PBinaryTree[T]] = @[root]
|
|
while stack.len > 0:
|
|
var n = stack.pop()
|
|
while n != nil:
|
|
yield n.data
|
|
add(stack, n.ri) # push right subtree onto the stack
|
|
n = n.le # and follow the left pointer
|
|
|
|
iterator items*[T](root: PBinaryTree[T]): T =
|
|
## Inorder traversal of the binary tree.
|
|
var stack: seq[PBinaryTree[T]] = @[]
|
|
var n = root
|
|
while true:
|
|
while n != nil:
|
|
add(stack, n)
|
|
n = n.le
|
|
if stack.len > 0:
|
|
n = stack.pop()
|
|
yield n.data
|
|
n = n.ri
|
|
if stack.len == 0 and n == nil: break
|
|
|
|
proc debug[T](a: PBinaryTree[T]) =
|
|
if a != nil:
|
|
debug(a.le)
|
|
echo a.data
|
|
debug(a.ri)
|
|
|
|
when isMainModule:
|
|
var
|
|
root: PBinaryTree[string]
|
|
x = newNode("hello")
|
|
add(root, x)
|
|
add(root, "world")
|
|
if find(root, "world"):
|
|
for str in items(root):
|
|
stdout.write(str)
|
|
else:
|
|
stdout.writeLine("BUG")
|
|
|
|
var
|
|
r2: PBinaryTree[int]
|
|
add(r2, newNode(110))
|
|
add(r2, 223)
|
|
add(r2, 99)
|
|
for y in items(r2):
|
|
stdout.write(y)
|
|
|
|
#OUT helloworld99110223
|
|
|
|
|