Unit BinTree; Interface Const TOTAL_NODES = 100; Type BTreeStr = String[40]; ShiftSet = (TiltL_Tilt, neutral, TiltR_Tilt); BinData = Record Key : BTreeStr; End; BinPtr = ^Bin_Tree_Rec; Bin_Tree_Rec = Record BTreeData : BinData; Shift : ShiftSet; TiltL, TiltR : BinPtr; End; BTreeRec = Array[1..TOTAL_NODES] of BinData; Procedure Ins_BinTree (Var Rt : BinPtr; Node : BinData); Function Srch_BinTree (Rt : BinPtr; Node : BinData; Index1 : Word) : Word; Procedure BSortArray (Var Rt : BinPtr; Var SortNode : BTreeRec; Var Index : Word); Procedure Del_BinTree (Var Rt : BinPtr; Node : BinData; Var DelFlag : Boolean); Implementation Procedure Move_TiltR(Var Rt : BinPtr); Var Ptr1, Ptr2 : BinPtr; Begin Ptr1 := Rt^.TiltR; If Ptr1^.Shift = TiltR_Tilt Then Begin Rt^.TiltR := Ptr1^.TiltL; Ptr1^.TiltL := Rt; Rt^.Shift := neutral; Rt := Ptr1 End Else Begin Ptr2 := Ptr1^.TiltL; Ptr1^.TiltL := Ptr2^.TiltR; Ptr2^.TiltR := Ptr1; Rt^.TiltR := Ptr2^.TiltL; Ptr2^.TiltL := Rt; If Ptr2^.Shift = TiltL_Tilt Then Ptr1^.Shift := TiltR_Tilt Else Ptr1^.Shift := neutral; If Ptr2^.Shift = TiltR_Tilt Then Rt^.Shift := TiltL_Tilt Else Rt^.Shift := neutral; Rt := Ptr2 End; Rt^.Shift := neutral End; Procedure Move_TiltL(Var Rt : BinPtr); Var Ptr1, Ptr2 : BinPtr; Begin Ptr1 := Rt^.TiltL; If Ptr1^.Shift = TiltL_Tilt Then Begin Rt^.TiltL := Ptr1^.TiltR; Ptr1^.TiltR := Rt; Rt^.Shift := neutral; Rt := Ptr1 End Else Begin Ptr2 := Ptr1^.TiltR; Ptr1^.TiltR := Ptr2^.TiltL; Ptr2^.TiltL := Ptr1; Rt^.TiltL := Ptr2^.TiltR; Ptr2^.TiltR := Rt; If Ptr2^.Shift = TiltR_Tilt Then Ptr1^.Shift := TiltL_Tilt Else Ptr1^.Shift := neutral; If Ptr2^.Shift = TiltL_Tilt Then Rt^.Shift := TiltR_Tilt Else Rt^.Shift := neutral; Rt := Ptr2; End; Rt^.Shift := neutral End; Procedure Ins_Bin(Var Rt : BinPtr; Node : BinData; Var InsOK : Boolean); Begin If Rt = NIL Then Begin New(Rt); With Rt^ Do Begin BTreeData := Node; TiltL := NIL; TiltR := NIL; Shift := neutral End; InsOK := TRUE End Else If Node.Key <= Rt^.BTreeData.Key Then Begin Ins_Bin(Rt^.TiltL, Node, InsOK); If InsOK Then Case Rt^.Shift Of TiltL_Tilt : Begin Move_TiltL(Rt); InsOK := FALSE End; neutral : Rt^.Shift := TiltL_Tilt; TiltR_Tilt : Begin Rt^.Shift := neutral; InsOK := FALSE End; End; End Else Begin Ins_Bin(Rt^.TiltR, Node, InsOK); If InsOK Then Case Rt^.Shift Of TiltL_Tilt : Begin Rt^.Shift := neutral; InsOK := FALSE End; neutral : Rt^.Shift := TiltR_Tilt; TiltR_Tilt : Begin Move_TiltR(Rt); InsOK := FALSE End; End; End; End; Procedure Ins_BinTree(Var Rt : BinPtr; Node : BinData); Var Ins_ok : Boolean; Begin Ins_ok := FALSE; Ins_Bin(Rt, Node, Ins_ok) End; Function Srch_BinTree(Rt : BinPtr; Node : BinData; Index1 : Word) : Word; Var Index : Word; Begin Index := 0; While (Rt <> NIL) AND (Index < Index1) Do If Node.Key > Rt^.BTreeData.Key Then Rt := Rt^.TiltR Else if Node.Key < Rt^.BTreeData.Key Then Rt := Rt^.TiltL Else Begin Inc(Index); Rt := Rt^.TiltL End; Srch_BinTree := Index End; Procedure Tvrs_Tree (Var Rt : BinPtr; Var SortNode : BTreeRec; Var Index : Word); Begin If Rt <> NIL Then Begin Tvrs_Tree(Rt^.TiltL, SortNode, Index); Inc(Index); If Index <= TOTAL_NODES Then SortNode[Index].Key := Rt^.BTreeData.Key; Tvrs_Tree(Rt^.TiltR, SortNode, Index); End; End; Procedure BSortArray (Var Rt : BinPtr; Var SortNode : BTreeRec; Var Index : Word); Begin Index := 0; Tvrs_Tree(Rt, SortNode, Index); End; Procedure Shift_TiltR (Var Rt : BinPtr; Var DelFlag : Boolean); Var Ptr1, Ptr2 : BinPtr; balnc2, balnc3 : ShiftSet; Begin Case Rt^.Shift Of TiltL_Tilt : Rt^.Shift := neutral; neutral : Begin Rt^.Shift := TiltR_Tilt; DelFlag := FALSE End; TiltR_Tilt : Begin Ptr1 := Rt^.TiltR; balnc2 := Ptr1^.Shift; If NOT (balnc2 = TiltL_Tilt) Then Begin Rt^.TiltR := Ptr1^.TiltL; Ptr1^.TiltL := Rt; If balnc2 = neutral Then Begin Rt^.Shift := TiltR_Tilt; Ptr1^.Shift := TiltL_Tilt; DelFlag := FALSE End Else Begin Rt^.Shift := neutral; Ptr1^.Shift := neutral; End; Rt := Ptr1 End Else Begin Ptr2 := Ptr1^.TiltL; balnc3 := Ptr2^.Shift; Ptr1^.TiltL := Ptr2^.TiltR; Ptr2^.TiltR := Ptr1; Rt^.TiltR := Ptr2^.TiltL; Ptr2^.TiltL := Rt; If balnc3 = TiltL_Tilt Then Ptr1^.Shift := TiltR_Tilt Else Ptr1^.Shift := neutral; If balnc3 = TiltR_Tilt Then Rt^.Shift := TiltL_Tilt Else Rt^.Shift := neutral; Rt := Ptr2; Ptr2^.Shift := neutral; End; End; End; End; Procedure Shift_TiltL (Var Rt : BinPtr; Var DelFlag : Boolean); Var Ptr1, Ptr2 : BinPtr; balnc2, balnc3 : ShiftSet; Begin Case Rt^.Shift Of TiltR_Tilt : Rt^.Shift := neutral; neutral : Begin Rt^.Shift := TiltL_Tilt; DelFlag := False End; TiltL_Tilt : Begin Ptr1 := Rt^.TiltL; balnc2 := Ptr1^.Shift; If NOT (balnc2 = TiltR_Tilt) Then Begin Rt^.TiltL := Ptr1^.TiltR; Ptr1^.TiltR := Rt; If balnc2 = neutral Then Begin Rt^.Shift := TiltL_Tilt; Ptr1^.Shift := TiltR_Tilt; DelFlag := FALSE End Else Begin Rt^.Shift := neutral; Ptr1^.Shift := neutral; End; Rt := Ptr1 End Else Begin Ptr2 := Ptr1^.TiltR; balnc3 := Ptr2^.Shift; Ptr1^.TiltR := Ptr2^.TiltL; Ptr2^.TiltL := Ptr1; Rt^.TiltL := Ptr2^.TiltR; Ptr2^.TiltR := Rt; If balnc3 = TiltR_Tilt Then Ptr1^.Shift := TiltL_Tilt Else Ptr1^.Shift := neutral; If balnc3 = TiltL_Tilt Then Rt^.Shift := TiltR_Tilt Else Rt^.Shift := neutral; Rt := Ptr2; Ptr2^.Shift := neutral; End; End; End; End; Procedure Kill_Lo_Nodes (Var Rt, Ptr : BinPtr; Var DelFlag : Boolean); Begin If Ptr^.TiltR = NIL Then Begin Rt^.BTreeData := Ptr^.BTreeData; Ptr := Ptr^.TiltL; DelFlag := TRUE End Else Begin Kill_Lo_Nodes(Rt, Ptr^.TiltR, DelFlag); If DelFlag Then Shift_TiltL(Ptr,DelFlag); End; End; Procedure Del_Bin(Var Rt : BinPtr; Node : BinData; Var DelFlag : Boolean); Var Ptr : BinPtr; Begin If Rt = NIL Then DelFlag := False Else If Node.Key < Rt^.BTreeData.Key Then Begin Del_Bin(Rt^.TiltL, Node, DelFlag); If DelFlag Then Shift_TiltR(Rt, DelFlag); End Else Begin If Node.Key > Rt^.BTreeData.Key Then Begin Del_Bin(Rt^.TiltR, Node, DelFlag); If DelFlag Then Shift_TiltL(Rt, DelFlag); End Else Begin Ptr := Rt; If Rt^.TiltR = NIL Then Begin Rt := Rt^.TiltL; DelFlag := TRUE; Dispose(Ptr); End Else If Rt^.TiltL = NIL Then Begin Rt := Rt^.TiltR; DelFlag := TRUE; Dispose(Ptr); End Else Begin Kill_Lo_Nodes(Rt, Rt^.TiltL, DelFlag); If DelFlag Then Shift_TiltR(Rt, DelFlag); Dispose(Rt^.TiltL); End; End; End; End; Procedure Del_BinTree (Var Rt : BinPtr; Node : BinData; Var DelFlag : Boolean); Begin DelFlag := FALSE; Del_Bin(Rt, Node, DelFlag) End; End.