Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
C
crystal
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
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
Show 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)
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
(
ke
y
!=
0
);
assert
(
entr
y
!=
0
);
struct
RBNode
*
node
=
cry_malloc
(
struct
RBNode
);
node
->
color
=
color
;
node
->
parent
=
parent
;
node
->
key
=
key
;
node
->
data
=
data
;
node
->
entry
=
entry
;
node
->
left
=
0
;
node
->
right
=
0
;
...
...
@@ -54,7 +53,7 @@ rb_node_new(enum RBNodeColor color, struct RBNode* parent, const_pointer key, po
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
);
...
...
@@ -67,15 +66,12 @@ rb_tree_clear(struct RBTree* tree, cry_free_funptr free_key, cry_free_funptr fre
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
);
if
(
free_key
!=
0
)
free_key
(
cry_cast
(
pointer
,
node
->
key
));
if
(
free_data
!=
0
)
free_data
(
node
->
data
);
if
(
free_entry
!=
0
)
free_entry
(
cry_cast
(
pointer
,
node
->
entry
));
cry_free
(
node
);
}
...
...
@@ -83,14 +79,14 @@ rb_node_free(struct RBNode* node, cry_free_funptr free_key, cry_free_funptr free
struct
RBNode
*
rb_tree_lookup
(
struct
RBTree
*
tree
,
const_pointer
ke
y
)
rb_tree_lookup
(
struct
RBTree
*
tree
,
const_pointer
entr
y
)
{
assert
(
tree
!=
0
&&
ke
y
!=
0
);
assert
(
tree
!=
0
&&
entr
y
!=
0
);
struct
RBNode
*
node
=
tree
->
root
;
while
(
node
!=
0
)
{
int
result
=
tree
->
compare
(
key
,
node
->
ke
y
);
int
result
=
tree
->
compare
(
entry
,
node
->
entr
y
);
if
(
result
<
0
)
node
=
node
->
left
;
...
...
@@ -295,31 +291,31 @@ rb_remedy_double_black(struct RBTree* tree, struct RBNode* node_x, 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
&&
ke
y
!=
0
);
assert
(
tree
!=
0
&&
entr
y
!=
0
);
struct
RBNode
*
node
=
tree
->
root
;
struct
RBNode
*
current_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
;
return
tree
->
root
;
}
// general node insertion for binary search tree
while
(
current_node
==
0
)
{
int
result
=
tree
->
compare
(
key
,
node
->
ke
y
);
int
result
=
tree
->
compare
(
entry
,
node
->
entr
y
);
if
(
result
<
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
node
=
node
->
left
;
}
else
if
(
result
>
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
node
=
node
->
right
;
}
else
{
...
...
@@ -356,16 +352,16 @@ rb_remove_external_node(struct RBNode* node)
struct
RBNode
*
rb_tree_remove
(
struct
RBTree
*
tree
,
const_pointer
ke
y
)
rb_tree_remove
(
struct
RBTree
*
tree
,
const_pointer
entr
y
)
{
assert
(
tree
!=
0
&&
ke
y
!=
0
);
assert
(
tree
!=
0
&&
entr
y
!=
0
);
struct
RBNode
*
node
=
0
;
struct
RBNode
*
current_node
=
0
;
struct
RBNode
*
data_node
=
0
;
// search for a node with the same
ke
y within the binary tree
current_node
=
rb_tree_lookup
(
tree
,
ke
y
);
// search for a node with the same
entr
y within the binary tree
current_node
=
rb_tree_lookup
(
tree
,
entr
y
);
if
(
current_node
==
0
)
return
current_node
;
...
...
@@ -377,14 +373,9 @@ rb_tree_remove(struct RBTree* tree, const_pointer key)
node
=
node
->
left
;
// swap its entry information
const_pointer
tmp_key
=
node
->
key
;
pointer
tmp_data
=
node
->
data
;
node
->
key
=
current_node
->
key
;
node
->
data
=
current_node
->
data
;
current_node
->
key
=
tmp_key
;
current_node
->
data
=
tmp_data
;
const_pointer
tmp_entry
=
node
->
entry
;
node
->
entry
=
current_node
->
entry
;
current_node
->
entry
=
tmp_entry
;
data_node
=
node
;
node
=
rb_remove_external_node
(
node
);
...
...
@@ -410,5 +401,3 @@ rb_tree_remove(struct RBTree* tree, const_pointer key)
return
data_node
;
}
src/structures/red_black_tree.h
View file @
f9456069
...
...
@@ -24,8 +24,7 @@
enum
RBNodeColor
{
RED
,
BLACK
};
struct
RBNode
{
const_pointer
key
;
pointer
data
;
const_pointer
entry
;
enum
RBNodeColor
color
;
struct
RBNode
*
parent
;
struct
RBNode
*
left
;
...
...
@@ -45,14 +44,14 @@ struct RBTree {
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
ke
y
);
struct
RBNode
*
rb_tree_insert
(
struct
RBTree
*
tree
,
const_pointer
key
,
pointer
value
);
struct
RBNode
*
rb_tree_remove
(
struct
RBTree
*
tree
,
const_pointer
ke
y
);
struct
RBNode
*
rb_tree_lookup
(
struct
RBTree
*
tree
,
const_pointer
entr
y
);
struct
RBNode
*
rb_tree_insert
(
struct
RBTree
*
tree
,
const_pointer
entry
);
struct
RBNode
*
rb_tree_remove
(
struct
RBTree
*
tree
,
const_pointer
entr
y
);
struct
RBNode
*
rb_node_new
(
enum
RBNodeColor
color
,
struct
RBNode
*
parent
,
const_pointer
key
,
pointer
data
);
void
rb_node_free
(
struct
RBNode
*
node
,
cry_free_funptr
free_key
,
cry_free_funptr
free_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
entry_key
);
...
...
test/red_black_tree.c
View file @
f9456069
...
...
@@ -12,7 +12,7 @@ test_red_black_tree_initialization(const_pointer data)
assert
(
tree
->
nodes
==
0
);
assert
(
rb_tree_lookup
(
tree
,
"unknown_key"
)
==
0
);
rb_tree_clear
(
tree
,
0
,
0
);
rb_tree_clear
(
tree
,
0
);
cry_free
(
tree
);
}
...
...
@@ -26,7 +26,7 @@ test_red_black_tree_insertion(const_pointer data)
assert
(
tree
->
nodes
==
0
);
while
(
*
keys
>
0
)
{
assert
(
rb_tree_insert
(
tree
,
keys
,
cry_cast
(
int
*
,
keys
)
)
!=
0
);
assert
(
rb_tree_insert
(
tree
,
keys
)
!=
0
);
++
keys
;
}
...
...
@@ -38,12 +38,12 @@ test_red_black_tree_insertion(const_pointer data)
struct
RBNode
*
node
=
rb_tree_lookup
(
tree
,
keys
);
assert
(
node
!=
0
);
assert
(
node
->
ke
y
==
keys
);
assert
(
node
->
entr
y
==
keys
);
++
keys
;
}
rb_tree_clear
(
tree
,
0
,
0
);
rb_tree_clear
(
tree
,
0
);
cry_free
(
tree
);
}
...
...
@@ -58,7 +58,7 @@ test_red_black_tree_removal(const_pointer list)
assert
(
tree
->
nodes
==
0
);
while
(
*
keys
>
0
)
{
assert
(
rb_tree_insert
(
tree
,
keys
,
cry_cast
(
int
*
,
keys
)
)
!=
0
);
assert
(
rb_tree_insert
(
tree
,
keys
)
!=
0
);
++
keys
;
}
...
...
@@ -68,33 +68,33 @@ test_red_black_tree_removal(const_pointer list)
// remove 3
data
=
rb_tree_remove
(
tree
,
keys
+
4
);
assert
(
data
!=
0
&&
data
->
ke
y
==
keys
+
4
);
rb_node_free
(
data
,
0
,
0
);
assert
(
data
!=
0
&&
data
->
entr
y
==
keys
+
4
);
rb_node_free
(
data
,
0
);
// remove 12
data
=
rb_tree_remove
(
tree
,
keys
+
2
);
assert
(
data
!=
0
&&
data
->
ke
y
==
keys
+
2
);
rb_node_free
(
data
,
0
,
0
);
assert
(
data
!=
0
&&
data
->
entr
y
==
keys
+
2
);
rb_node_free
(
data
,
0
);
// remove 17
data
=
rb_tree_remove
(
tree
,
keys
+
9
);
assert
(
data
!=
0
&&
data
->
ke
y
==
keys
+
9
);
rb_node_free
(
data
,
0
,
0
);
assert
(
data
!=
0
&&
data
->
entr
y
==
keys
+
9
);
rb_node_free
(
data
,
0
);
// remove 18
data
=
rb_tree_remove
(
tree
,
keys
+
7
);
assert
(
data
!=
0
&&
data
->
ke
y
==
keys
+
7
);
rb_node_free
(
data
,
0
,
0
);
assert
(
data
!=
0
&&
data
->
entr
y
==
keys
+
7
);
rb_node_free
(
data
,
0
);
// remove 15
data
=
rb_tree_remove
(
tree
,
keys
+
3
);
assert
(
data
!=
0
&&
data
->
ke
y
==
keys
+
3
);
rb_node_free
(
data
,
0
,
0
);
assert
(
data
!=
0
&&
data
->
entr
y
==
keys
+
3
);
rb_node_free
(
data
,
0
);
// remove 16
data
=
rb_tree_remove
(
tree
,
keys
+
8
);
assert
(
data
!=
0
&&
data
->
ke
y
==
keys
+
8
);
rb_node_free
(
data
,
0
,
0
);
assert
(
data
!=
0
&&
data
->
entr
y
==
keys
+
8
);
rb_node_free
(
data
,
0
);
// contains 4
assert
(
rb_tree_lookup
(
tree
,
keys
)
!=
0
);
...
...
@@ -108,7 +108,7 @@ test_red_black_tree_removal(const_pointer list)
// contains 14
assert
(
rb_tree_lookup
(
tree
,
keys
+
6
)
!=
0
);
rb_tree_clear
(
tree
,
0
,
0
);
rb_tree_clear
(
tree
,
0
);
cry_free
(
tree
);
}
...
...
tools/graphview.c
View file @
f9456069
...
...
@@ -27,7 +27,7 @@ file_parse_red_black_tree(FILE* file)
case
'+'
:
integer
=
cry_malloc
(
int
);
*
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
);
cry_free
(
integer
);
}
...
...
@@ -38,7 +38,7 @@ file_parse_red_black_tree(FILE* file)
if
(
(
node
=
rb_tree_remove
(
tree
,
&
tmp
))
==
0
)
fprintf
(
stderr
,
"Value %d is not in tree.
\n
"
,
tmp
);
else
rb_node_free
(
node
,
cry_free
,
0
);
rb_node_free
(
node
,
cry_free
);
break
;
default:
...
...
@@ -58,7 +58,7 @@ red_black_tree_graph(Agraph_t* graph, struct RBNode* node)
{
char
key
[
32
];
snprintf
(
key
,
sizeof
(
key
),
"%d"
,
*
cry_cast
(
int
*
,
node
->
ke
y
));
snprintf
(
key
,
sizeof
(
key
),
"%d"
,
*
cry_cast
(
int
*
,
node
->
entr
y
));
Agnode_t
*
n
=
agnode
(
graph
,
key
);
agset
(
n
,
"label"
,
key
);
...
...
@@ -72,7 +72,7 @@ red_black_tree_graph(Agraph_t* graph, struct RBNode* node)
Agnode_t
*
child
=
red_black_tree_graph
(
graph
,
node
->
left
);
agedge
(
graph
,
n
,
child
);
}
else
{
snprintf
(
key
,
sizeof
(
key
),
"%d_left"
,
*
cry_cast
(
int
*
,
node
->
ke
y
));
snprintf
(
key
,
sizeof
(
key
),
"%d_left"
,
*
cry_cast
(
int
*
,
node
->
entr
y
));
Agnode_t
*
child
=
agnode
(
graph
,
key
);
agsafeset
(
child
,
"shape"
,
"point"
,
""
);
agedge
(
graph
,
n
,
child
);
...
...
@@ -82,7 +82,7 @@ red_black_tree_graph(Agraph_t* graph, struct RBNode* node)
Agnode_t
*
child
=
red_black_tree_graph
(
graph
,
node
->
right
);
agedge
(
graph
,
n
,
child
);
}
else
{
snprintf
(
key
,
sizeof
(
key
),
"%d_right"
,
*
cry_cast
(
int
*
,
node
->
ke
y
));
snprintf
(
key
,
sizeof
(
key
),
"%d_right"
,
*
cry_cast
(
int
*
,
node
->
entr
y
));
Agnode_t
*
child
=
agnode
(
graph
,
key
);
agsafeset
(
child
,
"shape"
,
"point"
,
""
);
agedge
(
graph
,
n
,
child
);
...
...
@@ -104,7 +104,7 @@ graph_generator(FILE* opfile, GVC_t* gvc, const char* graphtype)
if
(
tree
->
root
!=
0
)
red_black_tree_graph
(
graph
,
tree
->
root
);
rb_tree_clear
(
tree
,
free
,
0
);
rb_tree_clear
(
tree
,
free
);
cry_free
(
tree
);
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