Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
10
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
Chris Müller
crystal
Commits
f9456069
Commit
f9456069
authored
Oct 28, 2012
by
Chris Müller
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
lib: red-black trees uses now only an entry field for compares.
parent
acac3e7d
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
54 additions
and
66 deletions
+54
-66
src/structures/red_black_tree.c
src/structures/red_black_tree.c
+23
-34
src/structures/red_black_tree.h
src/structures/red_black_tree.h
+7
-8
test/red_black_tree.c
test/red_black_tree.c
+18
-18
tools/graphview.c
tools/graphview.c
+6
-6
No files found.
src/structures/red_black_tree.c
View file @
f9456069
...
@@ -37,15 +37,14 @@ rb_tree_new(cry_ordering_funptr compare)
...
@@ -37,15 +37,14 @@ rb_tree_new(cry_ordering_funptr compare)
struct
RBNode
*
struct
RBNode
*
rb_node_new
(
enum
RBNodeColor
color
,
struct
RBNode
*
parent
,
const_pointer
key
,
pointer
data
)
rb_node_new
(
enum
RBNodeColor
color
,
struct
RBNode
*
parent
,
const_pointer
entry
)
{
{
assert
(
k
ey
!=
0
);
assert
(
e
ntr
y
!=
0
);
struct
RBNode
*
node
=
cry_malloc
(
struct
RBNode
);
struct
RBNode
*
node
=
cry_malloc
(
struct
RBNode
);
node
->
color
=
color
;
node
->
color
=
color
;
node
->
parent
=
parent
;
node
->
parent
=
parent
;
node
->
key
=
key
;
node
->
entry
=
entry
;
node
->
data
=
data
;
node
->
left
=
0
;
node
->
left
=
0
;
node
->
right
=
0
;
node
->
right
=
0
;
...
@@ -54,7 +53,7 @@ rb_node_new(enum RBNodeColor color, struct RBNode* parent, const_pointer key, po
...
@@ -54,7 +53,7 @@ rb_node_new(enum RBNodeColor color, struct RBNode* parent, const_pointer key, po
void
void
rb_tree_clear
(
struct
RBTree
*
tree
,
cry_free_funptr
free_
key
,
cry_free_funptr
free_data
)
rb_tree_clear
(
struct
RBTree
*
tree
,
cry_free_funptr
free_
entry
)
{
{
assert
(
tree
!=
0
);
assert
(
tree
!=
0
);
...
@@ -67,15 +66,12 @@ rb_tree_clear(struct RBTree* tree, cry_free_funptr free_key, cry_free_funptr fre
...
@@ -67,15 +66,12 @@ rb_tree_clear(struct RBTree* tree, cry_free_funptr free_key, cry_free_funptr fre
void
void
rb_node_free
(
struct
RBNode
*
node
,
cry_free_funptr
free_
key
,
cry_free_funptr
free_data
)
rb_node_free
(
struct
RBNode
*
node
,
cry_free_funptr
free_
entry
)
{
{
assert
(
node
!=
0
);
assert
(
node
!=
0
);
if
(
free_key
!=
0
)
if
(
free_entry
!=
0
)
free_key
(
cry_cast
(
pointer
,
node
->
key
));
free_entry
(
cry_cast
(
pointer
,
node
->
entry
));
if
(
free_data
!=
0
)
free_data
(
node
->
data
);
cry_free
(
node
);
cry_free
(
node
);
}
}
...
@@ -83,14 +79,14 @@ rb_node_free(struct RBNode* node, cry_free_funptr free_key, cry_free_funptr free
...
@@ -83,14 +79,14 @@ rb_node_free(struct RBNode* node, cry_free_funptr free_key, cry_free_funptr free
struct
RBNode
*
struct
RBNode
*
rb_tree_lookup
(
struct
RBTree
*
tree
,
const_pointer
k
ey
)
rb_tree_lookup
(
struct
RBTree
*
tree
,
const_pointer
e
ntr
y
)
{
{
assert
(
tree
!=
0
&&
k
ey
!=
0
);
assert
(
tree
!=
0
&&
e
ntr
y
!=
0
);
struct
RBNode
*
node
=
tree
->
root
;
struct
RBNode
*
node
=
tree
->
root
;
while
(
node
!=
0
)
{
while
(
node
!=
0
)
{
int
result
=
tree
->
compare
(
k
ey
,
node
->
k
ey
);
int
result
=
tree
->
compare
(
e
ntr
y
,
node
->
e
ntr
y
);
if
(
result
<
0
)
if
(
result
<
0
)
node
=
node
->
left
;
node
=
node
->
left
;
...
@@ -295,31 +291,31 @@ rb_remedy_double_black(struct RBTree* tree, struct RBNode* node_x, struct RBNode
...
@@ -295,31 +291,31 @@ rb_remedy_double_black(struct RBTree* tree, struct RBNode* node_x, struct RBNode
struct
RBNode
*
struct
RBNode
*
rb_tree_insert
(
struct
RBTree
*
tree
,
const_pointer
key
,
pointer
value
)
rb_tree_insert
(
struct
RBTree
*
tree
,
const_pointer
entry
)
{
{
assert
(
tree
!=
0
&&
k
ey
!=
0
);
assert
(
tree
!=
0
&&
e
ntr
y
!=
0
);
struct
RBNode
*
node
=
tree
->
root
;
struct
RBNode
*
node
=
tree
->
root
;
struct
RBNode
*
current_node
=
0
;
struct
RBNode
*
current_node
=
0
;
if
(
node
==
0
)
{
if
(
node
==
0
)
{
tree
->
root
=
rb_node_new
(
BLACK
,
0
,
key
,
value
);
tree
->
root
=
rb_node_new
(
BLACK
,
0
,
entry
);
tree
->
nodes
+=
1
;
tree
->
nodes
+=
1
;
return
tree
->
root
;
return
tree
->
root
;
}
}
// general node insertion for binary search tree
// general node insertion for binary search tree
while
(
current_node
==
0
)
{
while
(
current_node
==
0
)
{
int
result
=
tree
->
compare
(
k
ey
,
node
->
k
ey
);
int
result
=
tree
->
compare
(
e
ntr
y
,
node
->
e
ntr
y
);
if
(
result
<
0
)
{
if
(
result
<
0
)
{
if
(
node
->
left
==
0
)
if
(
node
->
left
==
0
)
current_node
=
node
->
left
=
rb_node_new
(
RED
,
node
,
key
,
value
);
current_node
=
node
->
left
=
rb_node_new
(
RED
,
node
,
entry
);
else
else
node
=
node
->
left
;
node
=
node
->
left
;
}
else
if
(
result
>
0
)
{
}
else
if
(
result
>
0
)
{
if
(
node
->
right
==
0
)
if
(
node
->
right
==
0
)
current_node
=
node
->
right
=
rb_node_new
(
RED
,
node
,
key
,
value
);
current_node
=
node
->
right
=
rb_node_new
(
RED
,
node
,
entry
);
else
else
node
=
node
->
right
;
node
=
node
->
right
;
}
else
{
}
else
{
...
@@ -356,16 +352,16 @@ rb_remove_external_node(struct RBNode* node)
...
@@ -356,16 +352,16 @@ rb_remove_external_node(struct RBNode* node)
struct
RBNode
*
struct
RBNode
*
rb_tree_remove
(
struct
RBTree
*
tree
,
const_pointer
k
ey
)
rb_tree_remove
(
struct
RBTree
*
tree
,
const_pointer
e
ntr
y
)
{
{
assert
(
tree
!=
0
&&
k
ey
!=
0
);
assert
(
tree
!=
0
&&
e
ntr
y
!=
0
);
struct
RBNode
*
node
=
0
;
struct
RBNode
*
node
=
0
;
struct
RBNode
*
current_node
=
0
;
struct
RBNode
*
current_node
=
0
;
struct
RBNode
*
data_node
=
0
;
struct
RBNode
*
data_node
=
0
;
// search for a node with the same
k
ey within the binary tree
// search for a node with the same e
ntr
y within the binary tree
current_node
=
rb_tree_lookup
(
tree
,
k
ey
);
current_node
=
rb_tree_lookup
(
tree
,
e
ntr
y
);
if
(
current_node
==
0
)
if
(
current_node
==
0
)
return
current_node
;
return
current_node
;
...
@@ -377,14 +373,9 @@ rb_tree_remove(struct RBTree* tree, const_pointer key)
...
@@ -377,14 +373,9 @@ rb_tree_remove(struct RBTree* tree, const_pointer key)
node
=
node
->
left
;
node
=
node
->
left
;
// swap its entry information
// swap its entry information
const_pointer
tmp_key
=
node
->
key
;
const_pointer
tmp_entry
=
node
->
entry
;
pointer
tmp_data
=
node
->
data
;
node
->
entry
=
current_node
->
entry
;
current_node
->
entry
=
tmp_entry
;
node
->
key
=
current_node
->
key
;
node
->
data
=
current_node
->
data
;
current_node
->
key
=
tmp_key
;
current_node
->
data
=
tmp_data
;
data_node
=
node
;
data_node
=
node
;
node
=
rb_remove_external_node
(
node
);
node
=
rb_remove_external_node
(
node
);
...
@@ -410,5 +401,3 @@ rb_tree_remove(struct RBTree* tree, const_pointer key)
...
@@ -410,5 +401,3 @@ rb_tree_remove(struct RBTree* tree, const_pointer key)
return
data_node
;
return
data_node
;
}
}
src/structures/red_black_tree.h
View file @
f9456069
...
@@ -24,8 +24,7 @@
...
@@ -24,8 +24,7 @@
enum
RBNodeColor
{
RED
,
BLACK
};
enum
RBNodeColor
{
RED
,
BLACK
};
struct
RBNode
{
struct
RBNode
{
const_pointer
key
;
const_pointer
entry
;
pointer
data
;
enum
RBNodeColor
color
;
enum
RBNodeColor
color
;
struct
RBNode
*
parent
;
struct
RBNode
*
parent
;
struct
RBNode
*
left
;
struct
RBNode
*
left
;
...
@@ -45,14 +44,14 @@ struct RBTree {
...
@@ -45,14 +44,14 @@ struct RBTree {
struct
RBTree
*
rb_tree_new
(
cry_ordering_funptr
compare
);
struct
RBTree
*
rb_tree_new
(
cry_ordering_funptr
compare
);
void
rb_tree_clear
(
struct
RBTree
*
tree
,
cry_free_funptr
free_key
,
cry_free_funptr
free_data
);
void
rb_tree_clear
(
struct
RBTree
*
tree
,
cry_free_funptr
free_key
);
struct
RBNode
*
rb_tree_lookup
(
struct
RBTree
*
tree
,
const_pointer
k
ey
);
struct
RBNode
*
rb_tree_lookup
(
struct
RBTree
*
tree
,
const_pointer
e
ntr
y
);
struct
RBNode
*
rb_tree_insert
(
struct
RBTree
*
tree
,
const_pointer
key
,
pointer
value
);
struct
RBNode
*
rb_tree_insert
(
struct
RBTree
*
tree
,
const_pointer
entry
);
struct
RBNode
*
rb_tree_remove
(
struct
RBTree
*
tree
,
const_pointer
k
ey
);
struct
RBNode
*
rb_tree_remove
(
struct
RBTree
*
tree
,
const_pointer
e
ntr
y
);
struct
RBNode
*
rb_node_new
(
enum
RBNodeColor
color
,
struct
RBNode
*
parent
,
const_pointer
key
,
pointer
data
);
struct
RBNode
*
rb_node_new
(
enum
RBNodeColor
color
,
struct
RBNode
*
parent
,
const_pointer
entry
);
void
rb_node_free
(
struct
RBNode
*
node
,
cry_free_funptr
free_key
,
cry_free_funptr
free_data
);
void
rb_node_free
(
struct
RBNode
*
node
,
cry_free_funptr
entry_key
);
...
...
test/red_black_tree.c
View file @
f9456069
...
@@ -12,7 +12,7 @@ test_red_black_tree_initialization(const_pointer data)
...
@@ -12,7 +12,7 @@ test_red_black_tree_initialization(const_pointer data)
assert
(
tree
->
nodes
==
0
);
assert
(
tree
->
nodes
==
0
);
assert
(
rb_tree_lookup
(
tree
,
"unknown_key"
)
==
0
);
assert
(
rb_tree_lookup
(
tree
,
"unknown_key"
)
==
0
);
rb_tree_clear
(
tree
,
0
,
0
);
rb_tree_clear
(
tree
,
0
);
cry_free
(
tree
);
cry_free
(
tree
);
}
}
...
@@ -26,7 +26,7 @@ test_red_black_tree_insertion(const_pointer data)
...
@@ -26,7 +26,7 @@ test_red_black_tree_insertion(const_pointer data)
assert
(
tree
->
nodes
==
0
);
assert
(
tree
->
nodes
==
0
);
while
(
*
keys
>
0
)
{
while
(
*
keys
>
0
)
{
assert
(
rb_tree_insert
(
tree
,
keys
,
cry_cast
(
int
*
,
keys
)
)
!=
0
);
assert
(
rb_tree_insert
(
tree
,
keys
)
!=
0
);
++
keys
;
++
keys
;
}
}
...
@@ -38,12 +38,12 @@ test_red_black_tree_insertion(const_pointer data)
...
@@ -38,12 +38,12 @@ test_red_black_tree_insertion(const_pointer data)
struct
RBNode
*
node
=
rb_tree_lookup
(
tree
,
keys
);
struct
RBNode
*
node
=
rb_tree_lookup
(
tree
,
keys
);
assert
(
node
!=
0
);
assert
(
node
!=
0
);
assert
(
node
->
k
ey
==
keys
);
assert
(
node
->
e
ntr
y
==
keys
);
++
keys
;
++
keys
;
}
}
rb_tree_clear
(
tree
,
0
,
0
);
rb_tree_clear
(
tree
,
0
);
cry_free
(
tree
);
cry_free
(
tree
);
}
}
...
@@ -58,7 +58,7 @@ test_red_black_tree_removal(const_pointer list)
...
@@ -58,7 +58,7 @@ test_red_black_tree_removal(const_pointer list)
assert
(
tree
->
nodes
==
0
);
assert
(
tree
->
nodes
==
0
);
while
(
*
keys
>
0
)
{
while
(
*
keys
>
0
)
{
assert
(
rb_tree_insert
(
tree
,
keys
,
cry_cast
(
int
*
,
keys
)
)
!=
0
);
assert
(
rb_tree_insert
(
tree
,
keys
)
!=
0
);
++
keys
;
++
keys
;
}
}
...
@@ -68,33 +68,33 @@ test_red_black_tree_removal(const_pointer list)
...
@@ -68,33 +68,33 @@ test_red_black_tree_removal(const_pointer list)
// remove 3
// remove 3
data
=
rb_tree_remove
(
tree
,
keys
+
4
);
data
=
rb_tree_remove
(
tree
,
keys
+
4
);
assert
(
data
!=
0
&&
data
->
k
ey
==
keys
+
4
);
assert
(
data
!=
0
&&
data
->
e
ntr
y
==
keys
+
4
);
rb_node_free
(
data
,
0
,
0
);
rb_node_free
(
data
,
0
);
// remove 12
// remove 12
data
=
rb_tree_remove
(
tree
,
keys
+
2
);
data
=
rb_tree_remove
(
tree
,
keys
+
2
);
assert
(
data
!=
0
&&
data
->
k
ey
==
keys
+
2
);
assert
(
data
!=
0
&&
data
->
e
ntr
y
==
keys
+
2
);
rb_node_free
(
data
,
0
,
0
);
rb_node_free
(
data
,
0
);
// remove 17
// remove 17
data
=
rb_tree_remove
(
tree
,
keys
+
9
);
data
=
rb_tree_remove
(
tree
,
keys
+
9
);
assert
(
data
!=
0
&&
data
->
k
ey
==
keys
+
9
);
assert
(
data
!=
0
&&
data
->
e
ntr
y
==
keys
+
9
);
rb_node_free
(
data
,
0
,
0
);
rb_node_free
(
data
,
0
);
// remove 18
// remove 18
data
=
rb_tree_remove
(
tree
,
keys
+
7
);
data
=
rb_tree_remove
(
tree
,
keys
+
7
);
assert
(
data
!=
0
&&
data
->
k
ey
==
keys
+
7
);
assert
(
data
!=
0
&&
data
->
e
ntr
y
==
keys
+
7
);
rb_node_free
(
data
,
0
,
0
);
rb_node_free
(
data
,
0
);
// remove 15
// remove 15
data
=
rb_tree_remove
(
tree
,
keys
+
3
);
data
=
rb_tree_remove
(
tree
,
keys
+
3
);
assert
(
data
!=
0
&&
data
->
k
ey
==
keys
+
3
);
assert
(
data
!=
0
&&
data
->
e
ntr
y
==
keys
+
3
);
rb_node_free
(
data
,
0
,
0
);
rb_node_free
(
data
,
0
);
// remove 16
// remove 16
data
=
rb_tree_remove
(
tree
,
keys
+
8
);
data
=
rb_tree_remove
(
tree
,
keys
+
8
);
assert
(
data
!=
0
&&
data
->
k
ey
==
keys
+
8
);
assert
(
data
!=
0
&&
data
->
e
ntr
y
==
keys
+
8
);
rb_node_free
(
data
,
0
,
0
);
rb_node_free
(
data
,
0
);
// contains 4
// contains 4
assert
(
rb_tree_lookup
(
tree
,
keys
)
!=
0
);
assert
(
rb_tree_lookup
(
tree
,
keys
)
!=
0
);
...
@@ -108,7 +108,7 @@ test_red_black_tree_removal(const_pointer list)
...
@@ -108,7 +108,7 @@ test_red_black_tree_removal(const_pointer list)
// contains 14
// contains 14
assert
(
rb_tree_lookup
(
tree
,
keys
+
6
)
!=
0
);
assert
(
rb_tree_lookup
(
tree
,
keys
+
6
)
!=
0
);
rb_tree_clear
(
tree
,
0
,
0
);
rb_tree_clear
(
tree
,
0
);
cry_free
(
tree
);
cry_free
(
tree
);
}
}
...
...
tools/graphview.c
View file @
f9456069
...
@@ -27,7 +27,7 @@ file_parse_red_black_tree(FILE* file)
...
@@ -27,7 +27,7 @@ file_parse_red_black_tree(FILE* file)
case
'+'
:
case
'+'
:
integer
=
cry_malloc
(
int
);
integer
=
cry_malloc
(
int
);
*
integer
=
atoi
(
buffer
+
2
);
*
integer
=
atoi
(
buffer
+
2
);
if
(
rb_tree_insert
(
tree
,
integer
,
0
)
==
0
)
{
if
(
rb_tree_insert
(
tree
,
integer
)
==
0
)
{
fprintf
(
stderr
,
"Value %d already added.
\n
"
,
*
integer
);
fprintf
(
stderr
,
"Value %d already added.
\n
"
,
*
integer
);
cry_free
(
integer
);
cry_free
(
integer
);
}
}
...
@@ -38,7 +38,7 @@ file_parse_red_black_tree(FILE* file)
...
@@ -38,7 +38,7 @@ file_parse_red_black_tree(FILE* file)
if
(
(
node
=
rb_tree_remove
(
tree
,
&
tmp
))
==
0
)
if
(
(
node
=
rb_tree_remove
(
tree
,
&
tmp
))
==
0
)
fprintf
(
stderr
,
"Value %d is not in tree.
\n
"
,
tmp
);
fprintf
(
stderr
,
"Value %d is not in tree.
\n
"
,
tmp
);
else
else
rb_node_free
(
node
,
cry_free
,
0
);
rb_node_free
(
node
,
cry_free
);
break
;
break
;
default:
default:
...
@@ -58,7 +58,7 @@ red_black_tree_graph(Agraph_t* graph, struct RBNode* node)
...
@@ -58,7 +58,7 @@ red_black_tree_graph(Agraph_t* graph, struct RBNode* node)
{
{
char
key
[
32
];
char
key
[
32
];
snprintf
(
key
,
sizeof
(
key
),
"%d"
,
*
cry_cast
(
int
*
,
node
->
k
ey
));
snprintf
(
key
,
sizeof
(
key
),
"%d"
,
*
cry_cast
(
int
*
,
node
->
e
ntr
y
));
Agnode_t
*
n
=
agnode
(
graph
,
key
);
Agnode_t
*
n
=
agnode
(
graph
,
key
);
agset
(
n
,
"label"
,
key
);
agset
(
n
,
"label"
,
key
);
...
@@ -72,7 +72,7 @@ red_black_tree_graph(Agraph_t* graph, struct RBNode* node)
...
@@ -72,7 +72,7 @@ red_black_tree_graph(Agraph_t* graph, struct RBNode* node)
Agnode_t
*
child
=
red_black_tree_graph
(
graph
,
node
->
left
);
Agnode_t
*
child
=
red_black_tree_graph
(
graph
,
node
->
left
);
agedge
(
graph
,
n
,
child
);
agedge
(
graph
,
n
,
child
);
}
else
{
}
else
{
snprintf
(
key
,
sizeof
(
key
),
"%d_left"
,
*
cry_cast
(
int
*
,
node
->
k
ey
));
snprintf
(
key
,
sizeof
(
key
),
"%d_left"
,
*
cry_cast
(
int
*
,
node
->
e
ntr
y
));
Agnode_t
*
child
=
agnode
(
graph
,
key
);
Agnode_t
*
child
=
agnode
(
graph
,
key
);
agsafeset
(
child
,
"shape"
,
"point"
,
""
);
agsafeset
(
child
,
"shape"
,
"point"
,
""
);
agedge
(
graph
,
n
,
child
);
agedge
(
graph
,
n
,
child
);
...
@@ -82,7 +82,7 @@ red_black_tree_graph(Agraph_t* graph, struct RBNode* node)
...
@@ -82,7 +82,7 @@ red_black_tree_graph(Agraph_t* graph, struct RBNode* node)
Agnode_t
*
child
=
red_black_tree_graph
(
graph
,
node
->
right
);
Agnode_t
*
child
=
red_black_tree_graph
(
graph
,
node
->
right
);
agedge
(
graph
,
n
,
child
);
agedge
(
graph
,
n
,
child
);
}
else
{
}
else
{
snprintf
(
key
,
sizeof
(
key
),
"%d_right"
,
*
cry_cast
(
int
*
,
node
->
k
ey
));
snprintf
(
key
,
sizeof
(
key
),
"%d_right"
,
*
cry_cast
(
int
*
,
node
->
e
ntr
y
));
Agnode_t
*
child
=
agnode
(
graph
,
key
);
Agnode_t
*
child
=
agnode
(
graph
,
key
);
agsafeset
(
child
,
"shape"
,
"point"
,
""
);
agsafeset
(
child
,
"shape"
,
"point"
,
""
);
agedge
(
graph
,
n
,
child
);
agedge
(
graph
,
n
,
child
);
...
@@ -104,7 +104,7 @@ graph_generator(FILE* opfile, GVC_t* gvc, const char* graphtype)
...
@@ -104,7 +104,7 @@ graph_generator(FILE* opfile, GVC_t* gvc, const char* graphtype)
if
(
tree
->
root
!=
0
)
if
(
tree
->
root
!=
0
)
red_black_tree_graph
(
graph
,
tree
->
root
);
red_black_tree_graph
(
graph
,
tree
->
root
);
rb_tree_clear
(
tree
,
free
,
0
);
rb_tree_clear
(
tree
,
free
);
cry_free
(
tree
);
cry_free
(
tree
);
if
(
graph
!=
0
)
{
if
(
graph
!=
0
)
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment