Chapter #12 Examples in Oz
% Utility functions
proc {While Expr Stmt}
if {Expr} then {Stmt} {While Expr Stmt} end
end
fun {TreeKey tree(key:Key ...)} Key end
fun {TreeParent tree(parent:Parent ...)} Parent end
fun {TreeLeft tree(left:Left ...)} Left end
fun {TreeRight tree(right:Right ...)} Right end
fun {TreeData tree(data:Data ...)} Data end
fun {TreeRoot T}
case T
of tree(parent:Parent ...) then
if @Parent == nil then
T
else
{TreeRoot @Parent}
end
else nil
end
end
proc {SetParent X}
case X
of tree(left:Left right:Right ...) then
case @Left
of tree(parent:Parent ...) then Parent := X
else skip
end
case @Right
of tree(parent:Parent ...) then Parent := X
else skip
end
else skip
end
end
TestTree = {NewCell tree(key:{NewCell 20}
parent:{NewCell nil}
left :{NewCell tree(key:{NewCell 10}
parent:{NewCell _}
left:{NewCell nil}
right:{NewCell nil}
data:{NewCell a})}
right :{NewCell tree(key:{NewCell 30}
parent:{NewCell _}
left:{NewCell nil}
right:{NewCell nil}
data:{NewCell c})}
data:{NewCell b})}
{SetParent @TestTree}
% 12.1 InOrderTreeWalk
proc {InOrderTreeWalk X}
case X
of tree(key:Key left:Left right:Right ...) then
{InOrderTreeWalk @Left}
{Browse 'InOrderTreeWalk'#@Key}
{InOrderTreeWalk @Right}
[] nil then skip
end
end
{InOrderTreeWalk @TestTree}
% 12.2 TreeSearch
fun {TreeSearch X K}
case X
of nil then X
[] tree(key:Key left:Left right:Right ...) then
if K == @Key then
X
else
if K < @Key then
{TreeSearch @Left K}
else
{TreeSearch @Right K}
end
end
end
end
{Browse 'TreeSearch'#@{TreeData {TreeSearch @TestTree 10}}}
% 12.2 IterativeTreeSearch
fun {IterativeTreeSearch X K}
Y = {NewCell X}
in
{While
fun {$}
case @Y
of nil then false
[] tree(key:Key ...) then K \= @Key
end
end
proc {$}
case @Y
of tree(key:Key left:Left right:Right ...) then
if K < @Key then
Y := @Left
else
Y := @Right
end
end
end}
@Y
end
{Browse 'TreeSearch'#@{TreeData {IterativeTreeSearch @TestTree 10}}}
% 12.2 TreeMinimum
fun {TreeMinimum X}
case X
of nil then nil
[] tree(left:Left ...) then
if @Left \= nil then
{TreeMinimum @Left}
else
X
end
end
end
{Browse 'TreeMinimum'#@{TreeKey {TreeMinimum @TestTree}}}
% 12.2 TreeMaximum
fun {TreeMaximum X}
case X
of nil then nil
[] tree(right:Right ...) then
if @Right \= nil then
{TreeMaximum @Right}
else
X
end
end
end
{Browse 'TreeMaximum'#@{TreeKey {TreeMaximum @TestTree}}}
% 12.2 TreeSuccessor
fun {TreeSuccessor X}
fun {ParentSuccessor X Y}
case Y
of tree(right:Right ...) then
if X == @Right then
{ParentSuccessor @Right X}
else
Y
end
[] nil then nil
end
end
in
case X
of tree(right:Right parent:Parent ...) then
if @Right \= nil then
{TreeMinimum @Right}
else
{ParentSuccessor X @Parent}
end
else nil
end
end
{Browse 'TreeSuccessor'#@{TreeKey {TreeSuccessor @TestTree}}}
% 12.2 TreePredecessor
fun {TreePredecessor X}
fun {ParentPredecessor X Y}
case Y
of tree(left:Left ...) then
if X == @Left then
{ParentPredecessor @Left X}
else
Y
end
[] nil then nil
end
end
in
case X
of tree(left:Left parent:Parent ...) then
if @Left \= nil then
{TreeMaximum @Left}
else
{ParentPredecessor X @Parent}
end
else nil
end
end
{Browse 'TreePredecessor'#@{TreeKey {TreePredecessor {TreeSuccessor @TestTree}}}}
% 12.3 TreeInsert
fun {TreeInsert T Z}
Y = {NewCell nil}
X = {NewCell {TreeRoot T}}
in
{While
fun {$} @X \= nil end
proc {$}
Y := @X
if @{TreeKey Z} < @{TreeKey @X} then
X := @{TreeLeft @X}
else
X := @{TreeRight @X}
end
end}
{TreeParent Z} := @Y
if (T \= nil) then
if @Y == nil then
{TreeParent {TreeRoot T}} := @Z
elseif @{TreeKey Z} < @{TreeKey @Y} then
{TreeLeft @Y} := Z
else
{TreeRight @Y} := Z
end
{TreeRoot T}
else
Z
end
end
{Browse 'TreeInsert'}
TestTree := {TreeInsert nil tree(key:{NewCell 5} parent:{NewCell nil} left:{NewCell nil} right:{NewCell nil} data:{NewCell a})}
TestTree := {TreeInsert @TestTree tree(key:{NewCell 10} parent:{NewCell nil} left:{NewCell nil} right:{NewCell nil} data:{NewCell b})}
TestTree := {TreeInsert @TestTree tree(key:{NewCell 15} parent:{NewCell nil} left:{NewCell nil} right:{NewCell nil} data:{NewCell c})}
TestTree := {TreeInsert @TestTree tree(key:{NewCell 20} parent:{NewCell nil} left:{NewCell nil} right:{NewCell nil} data:{NewCell d})}
TestTree := {TreeInsert @TestTree tree(key:{NewCell 25} parent:{NewCell nil} left:{NewCell nil} right:{NewCell nil} data:{NewCell e})}
TestTree := {TreeInsert @TestTree tree(key:{NewCell 30} parent:{NewCell nil} left:{NewCell nil} right:{NewCell nil} data:{NewCell f})}
TestTree := {TreeInsert @TestTree tree(key:{NewCell 35} parent:{NewCell nil} left:{NewCell nil} right:{NewCell nil} data:{NewCell g})}
{InOrderTreeWalk @TestTree}
% 12.3 TreeDelete
fun {TreeDelete T Z}
X = {NewCell _}
Y = {NewCell _}
Root = _
in
if @{TreeLeft Z} == nil orelse @{TreeRight Z} == nil then
Y := Z
else
Y := {TreeSuccessor Z}
end
if @{TreeLeft @Y} \= nil then
X := @{TreeLeft @Y}
else
X := @{TreeRight @Y}
end
if @X \= nil then
{TreeParent @X} := @{TreeParent @Y}
end
if @{TreeParent @Y} == nil then
Root = @X
else
Root = {TreeRoot @Y}
if @Y == @{TreeLeft @{TreeParent @Y}} then
{TreeLeft @{TreeParent @Y}} := @X
else
{TreeRight @{TreeParent @Y}} := @X
end
end
if @Y \= Z then
{TreeKey Z} := @{TreeKey @Y}
{TreeData Z} := @{TreeData @Y}
end
Root
end
{Browse 'TreeDelete'}
TestTree := {TreeDelete @TestTree {TreeSearch @TestTree 5}}
TestTree := {TreeDelete @TestTree {TreeSearch @TestTree 15}}
TestTree := {TreeDelete @TestTree {TreeSearch @TestTree 25}}
TestTree := {TreeDelete @TestTree {TreeSearch @TestTree 35}}
{InOrderTreeWalk @TestTree}
|