1 //////////////////////////////////////////////////////////////////////////////
4 // ADLib, Prop and their related set of tools and documentation are in the
5 // public domain. The author(s) of this software reserve no copyrights on
6 // the source code and any code generated using the tools. You are encouraged
7 // to use ADLib and Prop to develop software, in both academic and commercial
8 // settings, and are free to incorporate any part of ADLib and Prop into
11 // Although you are under no obligation to do so, we strongly recommend that
12 // you give away all software developed using our tools.
14 // We also ask that credit be given to us when ADLib and/or Prop are used in
15 // your programs, and that this notice be preserved intact in all the source
18 // This software is still under development and we welcome any suggestions
19 // and help from the users.
23 //////////////////////////////////////////////////////////////////////////////
28 ///////////////////////////////////////////////////////////////////////////
30 // The algorithm implemented here is in Gonnet's\cite{Algorithms}.
31 ///////////////////////////////////////////////////////////////////////////
33 #include <AD/trees/trees.h>
35 template <class K
, class V
>
36 class Pagoda
: public BinaryTree
<K
,V
> {
37 Pagoda(const Pagoda
& p
);
39 TrNode
<K
,V
> * merge_tree(TrNode
<K
,V
> *, TrNode
<K
,V
> *);
43 ///////////////////////////////////////////////////////////////////
44 // Constructors and destructor
45 ///////////////////////////////////////////////////////////////////
49 ///////////////////////////////////////////////////////////////////
51 ///////////////////////////////////////////////////////////////////
52 void clear() { clear2(); }
53 BinaryNode
* insert(const K
&, const V
&);
54 BinaryNode
* min() const { return tree_root
; }
56 Bool
remove(const K
&) { error("Pagoda::remove"); }
59 ////////////////////////////////////////////////////////////////////////
60 // Implementation of the template methods
61 /////////////////////////////////////////////////////////////////////////
63 /////////////////////////////////////////////////////////////////////////
64 // The most basic operation of pagodas is merging two trees
65 /////////////////////////////////////////////////////////////////////////
66 template <class K
, class V
>
67 TrNode
<K
,V
> * Pagoda
<K
,V
>::merge_tree(TrNode
<K
,V
> * a
, TrNode
<K
,V
> * b
)
68 { if (a
== 0) return b
;
70 TrNode
<K
,V
> * bot_a
, * bot_b
, * r
, * temp
;
71 bot_a
= (TrNode
<K
,V
>*)a
->R
; a
->R
= 0;
72 bot_b
= (TrNode
<K
,V
>*)b
->L
; b
->L
= 0;
74 while (bot_a
!= 0 && bot_b
!= 0) {
75 if (compare(bot_a
->key
, bot_b
->key
) > 0) {
76 temp
= (TrNode
<K
,V
>*)bot_a
->R
;
77 if (r
== 0) bot_a
->R
= bot_a
;
78 else { bot_a
->R
= r
->R
; r
->R
= bot_a
; }
79 r
= bot_a
; bot_a
= temp
;
81 temp
= (TrNode
<K
,V
>*)bot_b
->L
;
82 if (r
== 0) bot_b
->L
= bot_b
;
83 else { bot_b
->L
= r
->L
; r
->L
= bot_b
; }
84 r
= bot_b
; bot_b
= temp
;
87 if (bot_b
== 0) { a
->R
= r
->R
; r
->R
= bot_a
; return a
; }
88 else { b
->L
= r
->L
; r
->L
= bot_b
; return b
; }
91 /////////////////////////////////////////////////////////////////////////
93 /////////////////////////////////////////////////////////////////////////
94 template <class K
, class V
>
95 BinaryNode
* Pagoda
<K
,V
>::insert(const K
& key
, const V
& value
)
96 { TrNode
<K
,V
> * P
= new TrNode
<K
,V
>(key
,value
);
99 tree_root
= merge_tree((TrNode
<K
,V
>*)tree_root
,P
);
103 /////////////////////////////////////////////////////////////////////////
105 /////////////////////////////////////////////////////////////////////////
106 template <class K
, class V
>
107 Bool Pagoda
<K
,V
>::delete_min()
109 TrNode
<K
,V
> * P
= (TrNode
<K
,V
>*)tree_root
;
111 if (P
->L
== P
) l
= 0;
112 else { for (l
= P
->L
; l
->L
!= P
; l
= l
->L
); l
->L
= P
->L
; }
113 if (P
->R
== P
) r
= 0;
114 else { for (r
= P
->R
; r
->R
!= P
; r
= r
->R
); r
->R
= P
->R
; }
115 tree_root
= merge_tree((TrNode
<K
,V
>*)l
,(TrNode
<K
,V
>*)r
);