Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/lib/librecsort/rs-splay.c
1808 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 1996-2011 AT&T Intellectual Property *
5
* and is licensed under the *
6
* Eclipse Public License, Version 1.0 *
7
* by AT&T Intellectual Property *
8
* *
9
* A copy of the License is available at *
10
* http://www.eclipse.org/org/documents/epl-v10.html *
11
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12
* *
13
* Information and Software Systems Research *
14
* AT&T Research *
15
* Florham Park NJ *
16
* *
17
* Phong Vo <[email protected]> *
18
* Glenn Fowler <[email protected]> *
19
* *
20
***********************************************************************/
21
/* Splay sort
22
**
23
** Written by Kiem-Phong Vo (08/24/96).
24
*/
25
26
#include "rshdr.h"
27
28
typedef struct rssplay_s
29
{ Rsobj_t* root;
30
} Rssplay_t;
31
32
#if __STD_C
33
static int splayinsert(Rs_t* rs, reg Rsobj_t* obj)
34
#else
35
static int splayinsert(rs, obj)
36
Rs_t* rs;
37
reg Rsobj_t* obj;
38
#endif
39
{
40
reg int cmp;
41
reg Rsobj_t *r, *root, *t, *l;
42
Rsobj_t link;
43
reg Rssplay_t* splay = (Rssplay_t*)rs->methdata;
44
45
obj->equal = NIL(Rsobj_t*);
46
OBJHEAD(obj);
47
48
if(!(root = splay->root))
49
{ obj->left = obj->right = NIL(Rsobj_t*);
50
splay->root = obj;
51
return 0;
52
}
53
54
OBJCMP(obj,root,cmp);
55
if(cmp == 0)
56
{ EQUAL(root,obj,t);
57
return 0;
58
}
59
else if(cmp > 0)
60
{ if(!root->right)
61
{ obj->left = root;
62
obj->right = NIL(Rsobj_t*);
63
splay->root = obj;
64
return 0;
65
}
66
}
67
else
68
{ if(!root->left)
69
{ obj->right = root;
70
obj->left = NIL(Rsobj_t*);
71
splay->root = obj;
72
return 0;
73
}
74
}
75
76
for(l = r = &link;; )
77
{ if(cmp < 0)
78
{ if((t = root->left))
79
{ OBJCMP(obj,t,cmp);
80
if(cmp < 0)
81
{ RROTATE(root,t);
82
RLINK(r,root);
83
if(!(root = root->left))
84
goto no_root;
85
}
86
else if(cmp == 0)
87
{ RROTATE(root,t);
88
goto has_root;
89
}
90
else
91
{ LLINK(l,t);
92
RLINK(r,root);
93
if(!(root = t->right))
94
goto no_root;
95
}
96
}
97
else
98
{ RLINK(r,root);
99
goto no_root;
100
}
101
}
102
else /*if(cmp > 0)*/
103
{ if((t = root->right))
104
{ OBJCMP(obj,t,cmp);
105
if(cmp > 0)
106
{ LROTATE(root,t);
107
LLINK(l,root);
108
if(!(root = root->right))
109
goto no_root;
110
}
111
else if(cmp == 0)
112
{ LROTATE(root,t);
113
goto has_root;
114
}
115
else
116
{ RLINK(r,t);
117
LLINK(l,root);
118
if(!(root = t->left))
119
goto no_root;
120
}
121
}
122
else
123
{ LLINK(l,root);
124
goto no_root;
125
}
126
}
127
OBJCMP(obj,root,cmp);
128
if(cmp == 0)
129
goto has_root;
130
}
131
132
has_root:
133
EQUAL(root,obj,t);
134
135
l->right = root->left;
136
r->left = root->right;
137
138
root->left = link.right;
139
root->right = link.left;
140
splay->root = root;
141
return 0;
142
143
no_root:
144
l->right = NIL(Rsobj_t*);
145
r->left = NIL(Rsobj_t*);
146
147
obj->left = link.right;
148
obj->right = link.left;
149
splay->root = obj;
150
return 0;
151
}
152
153
#if __STD_C
154
static Rsobj_t* flatten(reg Rsobj_t* r)
155
#else
156
static Rsobj_t* flatten(r)
157
reg Rsobj_t* r;
158
#endif
159
{ reg Rsobj_t *t, *p, *list;
160
161
/* find smallest element and make it head of list */
162
while((t = r->left) )
163
RROTATE(r,t);
164
165
/* flatten tree */
166
for(list = p = r, r = r->right;; p = r, r = r->right)
167
{ if(!r)
168
{ list->left = p;
169
return list;
170
}
171
else if((t = r->left) )
172
{ do RROTATE(r,t);
173
while((t = r->left) );
174
175
p->right = r;
176
}
177
}
178
}
179
180
#if __STD_C
181
static Rsobj_t* splaylist(Rs_t* rs)
182
#else
183
static Rsobj_t* splaylist(rs)
184
Rs_t* rs;
185
#endif
186
{
187
reg Rsobj_t* list;
188
reg Rssplay_t* splay = (Rssplay_t*)rs->methdata;
189
190
if (!splay->root)
191
return NIL(Rsobj_t*);
192
list = flatten(splay->root);
193
splay->root = NIL(Rsobj_t*);
194
195
return list;
196
}
197
198
/* public method */
199
static Rsmethod_t _Rssplay =
200
{ splayinsert,
201
splaylist,
202
sizeof(Rssplay_t),
203
RS_MTSPLAY,
204
"splay",
205
"Splay tree sort."
206
};
207
208
__DEFINE__(Rsmethod_t*, Rssplay, &_Rssplay);
209
210
#ifdef NoF
211
NoF(rssplay)
212
#endif
213
214