-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathbinary_trees_ex
executable file
·109 lines (86 loc) · 2.24 KB
/
binary_trees_ex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#!/bin/bash
#
# Example inspired by Equivalent Binary Trees from the Go tutorial
# (https://go.dev/tour/concurrency/8).
readonly DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
. ${DIR}/../gobash
function Tree() {
local -r val="${1}"
local -r left="${2:-$NULL}"
local -r right="${3:-$NULL}"
shift 1
[ -z "${val}" ] && return $EC
make_ $FUNCNAME \
"left" "$left" \
"val" "$val" \
"right" "$right"
}
function Tree_add() {
local -r t="${1}"
local -r n="${2}"
shift 2
local prev="$NULL"
local curr="$t"
while ! is_null "$curr"; do
prev="$curr"
if [ $($curr val) -lt $($n val) ]; then
curr=$($curr right)
else
curr=$($curr left)
fi
done
if [ $($prev val) -lt $($n val) ]; then
$prev right "$n"
else
$prev left "$n"
fi
}
function _tree_walk() {
local -r t="${1}"
local -r ch="${2}"
shift 2
$ch send "$($t val)"
local l=$($t left)
if ! is_null "$l"; then
_tree_walk "$l" "$ch"
fi
local r=$($t right)
if ! is_null "$r"; then
_tree_walk "$r" "$ch"
fi
}
function Tree_walk() {
local -r t="${1}"
local -r ch="${2}"
shift 2
_tree_walk "$t" "$ch"
$ch close
}
function tree_new() {
local -i k="${1}"
shift 1
[ -z "${k}" ] && return $EC
local t=$NULL
local -i i
# Do not use shuf (not in Mac).
for i in $(seq 1 10 | awk 'BEGIN {srand();} {print rand(), $0;}' | sort -n | cut -d' ' -f2-); do
local val=$(( ${i} * 1000 ))
local n=$(Tree "${val}" )
if is_null "$t"; then
t="$n"
else
$t add "$n"
fi
done
echo "$t"
}
echo "Construct a tree."
t=$(tree_new 1)
echo "Create a channel and walk a tree."
ch=$(Chan)
( $t walk "$ch" ) &
echo "Start receiving data."
while :; do
if ! $ch recv; then break; fi
done
wait