Commit 69d9d73fa7eb4db81a0c191395368f5adfb1984c

Authored by Georg Hopp
1 parent da3ff341

and now also utilize the TR_TREE_FIND macro.

... ... @@ -3,6 +3,7 @@ nobase_include_HEADERS = trbase.h \
3 3 tr/commons.h \
4 4 tr/interface.h \
5 5 tr/memory.h \
  6 + tr/tree_macros.h \
6 7 tr/interface/class.h \
7 8 tr/interface/indexable.h \
8 9 tr/interface/observer.h \
... ...
  1 +/**
  2 + * \file
  3 + *
  4 + * \author Georg Hopp
  5 + *
  6 + * \copyright
  7 + * Copyright © 2012 Georg Hopp
  8 + *
  9 + * This program is free software: you can redistribute it and/or modify
  10 + * it under the terms of the GNU General Public License as published by
  11 + * the Free Software Foundation, either version 3 of the License, or
  12 + * (at your option) any later version.
  13 + *
  14 + * This program is distributed in the hope that it will be useful,
  15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17 + * GNU General Public License for more details.
  18 + *
  19 + * You should have received a copy of the GNU General Public License
  20 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
  21 + */
  22 +
  23 +#ifndef __TR_TREE_MACROS_H__
  24 +#define __TR_TREE_MACROS_H__
  25 +
  26 +#include "trbase.h"
  27 +
  28 +#define TR_TREE_RIGHT(node) (NULL!=(node)?(node)->right:NULL)
  29 +#define TR_TREE_LEFT(node) (NULL!=(node)?(node)->left:NULL)
  30 +#define TR_TREE_PARENT(node) (NULL!=(node)?(node)->parent:NULL)
  31 +
  32 +#define TR_TREE_CHILD(node) \
  33 + (NULL==TR_TREE_RIGHT((node))?TR_TREE_LEFT((node)):TR_TREE_RIGHT((node)))
  34 +
  35 +#define TR_TREE_SIBLING(node) \
  36 + (NULL!=TR_TREE_PARENT((node))? \
  37 + ((node)==TR_TREE_PARENT((node))->left? \
  38 + TR_TREE_PARENT((node))->right: \
  39 + TR_TREE_PARENT((node))->left): \
  40 + NULL)
  41 +
  42 +#define TR_TREE_GRANDPARENT(node) (TR_TREE_PARENT((node))->parent)
  43 +
  44 +#define TR_TREE_UNCLE(node) \
  45 + ((node)->parent == (node)->parent->parent->left? \
  46 + (node)->parent->parent->right: \
  47 + (node)->parent->parent->left)
  48 +
  49 +#define TR_TREE_REPLACE_NODE(root, node1, node2) \
  50 + if (NULL != (node1)->parent) { \
  51 + if ((node1) == (node1)->parent->left) { \
  52 + (node1)->parent->left = (node2); \
  53 + } else { \
  54 + (node1)->parent->right = (node2); \
  55 + } \
  56 + } else { \
  57 + *(root) = (node2); \
  58 + } \
  59 + if (NULL != (node2)) { \
  60 + (node2)->parent = (node1)->parent; \
  61 + }
  62 +
  63 +#define TR_TREE_ROT_RCLD_right(node) ((node)->left)
  64 +#define TR_TREE_ROT_RCLD_left(node) ((node)->right)
  65 +
  66 +#define TR_TREE_ROTATE(lr, root, node) \
  67 + if (NULL != (node)) { \
  68 + void * stPar = node->parent; \
  69 + void * relCld = TR_TREE_ROT_RCLD_##lr(node); \
  70 + void * relCCld = TR_TREE_ROT_RCLD_##lr(node)->lr; \
  71 + void * nLeft_p = &TR_TREE_ROT_RCLD_##lr(node); \
  72 + if (NULL != relCCld) { \
  73 + TR_TREE_ROT_RCLD_##lr(node)->lr->parent = node; \
  74 + } \
  75 + TR_TREE_ROT_RCLD_##lr(node)->lr = node; \
  76 + if (NULL != node->parent) { \
  77 + if (node->parent->left == node) { \
  78 + node->parent->left = relCld; \
  79 + } else { \
  80 + node->parent->right = relCld; \
  81 + } \
  82 + } else { \
  83 + *(root) = relCld; \
  84 + } \
  85 + node->parent = relCld; \
  86 + TR_TREE_ROT_RCLD_##lr(node)->parent = stPar; \
  87 + *(void**)nLeft_p = relCCld; \
  88 + }
  89 +
  90 +typedef enum {rbBlack=1, rbRed=2} TR_rbColor;
  91 +
  92 +#define TR_TREE_NODE_BLACK(node) (NULL == (node) || rbBlack == (node)->color)
  93 +#define TR_TREE_NODE_RED(node) (NULL == (node) || rbRed == (node)->color)
  94 +#define TR_TREE_NODE_STRICT_BLACK(node) (NULL != (node) && rbBlack == (node)->color)
  95 +#define TR_TREE_NODE_STRICT_RED(node) (NULL != (node) && rbRed == (node)->color)
  96 +
  97 +#define TR_TREE_INORDER_SUCC(node, succ) \
  98 + succ = (node)->right; \
  99 + while (NULL != succ->left) { \
  100 + succ = succ->left; \
  101 + }
  102 +/*
  103 + * Find data in a tree.
  104 + * Attention: This will change node, so normally you need to copy
  105 + * it before using this macro.
  106 + * Also be aware that found needs to be a valid lvalue and an integer.
  107 + */
  108 +#define TR_TREE_FIND(node, search, found, comp) \
  109 + (found) = -1; \
  110 + if ((node)) { \
  111 + while(1) { \
  112 + (found) = (comp)((node)->data, (search)); \
  113 + if (0 != (found)) { \
  114 + if (! ((node)->left || (node)->right)) { \
  115 + break; \
  116 + } \
  117 + if (0 < (found)) { \
  118 + (node) = (node)->left; \
  119 + } else { \
  120 + (node) = (node)->right; \
  121 + } \
  122 + } else { \
  123 + break; \
  124 + } \
  125 + } \
  126 + }
  127 +
  128 +#endif // __TR_TREE_MACROS_H__
  129 +
  130 +// vim: set ts=4 sw=4:
... ...
... ... @@ -98,6 +98,30 @@ newElement(size_t size)
98 98 return element;
99 99 }
100 100
  101 +static
  102 +int
  103 +_memSegmentFindCompare(const void * a, const void * b)
  104 +{
  105 + struct memSegment * _a = (struct memSegment *)a;
  106 + size_t _b = *(size_t *)b;
  107 +
  108 + /*
  109 + * find the smallest bigger or equal size segment
  110 + */
  111 + return _a->size < _b ? -1
  112 + : _a->size > _b && _a->left && _a->left->size >= _b ? 1 : 0;
  113 +}
  114 +
  115 +static
  116 +int
  117 +_memSegmentCompare(const void * a, const void * b)
  118 +{
  119 + size_t _a = ((struct memSegment *)a)->size;
  120 + size_t _b = ((struct memSegment *)b)->size;
  121 +
  122 + return _a < _b ? -1 : _a > _b ? 1 : 0;
  123 +}
  124 +
101 125 /**
102 126 * find element in tree
103 127 */
... ... @@ -105,23 +129,11 @@ static
105 129 struct memSegment *
106 130 findElement(struct memSegment * tree, size_t size)
107 131 {
108   - struct memSegment * fitting = NULL;
109   -
110   - while (NULL != tree) {
111   - if (tree->size == size) {
112   - fitting = tree;
113   - break;
114   - }
  132 + int found;
115 133
116   - if (size > tree->size) {
117   - tree = tree->right;
118   - } else {
119   - fitting = tree;
120   - tree = tree->left;
121   - }
122   - }
  134 + TR_TREE_FIND(tree, &size, found, _memSegmentFindCompare);
123 135
124   - return fitting;
  136 + return found == 0 ? tree : NULL;
125 137 }
126 138
127 139 /**
... ... @@ -135,6 +147,7 @@ insertElement(struct memSegment ** tree, struct memSegment * element)
135 147 struct memSegment * new_node = NULL;
136 148 struct memSegment * u;
137 149 struct memSegment * g;
  150 + int found;
138 151
139 152 element->next = NULL;
140 153 element->last = NULL;
... ... @@ -144,42 +157,35 @@ insertElement(struct memSegment ** tree, struct memSegment * element)
144 157 element->left = NULL;
145 158 element->right = NULL;
146 159
  160 + TR_TREE_FIND(node, element, found, _memSegmentCompare);
  161 +
147 162 // if tree is empty it's simple... :)
148 163 if (NULL == node) {
149 164 *tree = node = new_node = element;
150   - } else {
151   - // normal binary tree add....
152   - while (NULL != node) {
153   - if (element->size < node->size) {
154   - if (NULL == node->left) {
155   - node->left = element;
156   - node->left->parent = node;
157   - new_node = node = node->left;
158   - break;
159   - } else {
160   - node = node->left;
161   - }
162   - } else if (element->size > node->size) {
163   - if (NULL == node->right) {
164   - node->right = element;
165   - node->right->parent = node;
166   - new_node = node = node->right;
167   - break;
168   - } else {
169   - node = node->right;
170   - }
171   - } else {
172   - if (NULL == node->next) {
173   - node->next = element;
174   - node->last = element;
175   - } else {
176   - node->last->next = element;
177   - node->last = element;
178   - }
179   - return node;
180   - }
181   - }
182   - }
  165 + } else {
  166 + // normal binary tree add....
  167 + if (found == 0) {
  168 + if (NULL == node->next) {
  169 + node->next = element;
  170 + node->last = element;
  171 + } else {
  172 + node->last->next = element;
  173 + node->last = element;
  174 + }
  175 + return node;
  176 + } else {
  177 + if (0 < found) {
  178 + node->left = element;
  179 + node->left->parent = node;
  180 + new_node = node = node->left;
  181 + } else {
  182 + node->right = element;
  183 + node->right->parent = node;
  184 + new_node = node = node->right;
  185 +
  186 + }
  187 + }
  188 + }
183 189
184 190 if (NULL != new_node) {
185 191 /*
... ... @@ -250,50 +256,43 @@ deleteElement(struct memSegment ** tree, struct memSegment * element)
250 256 struct memSegment * del_node;
251 257 struct memSegment * child;
252 258 struct memSegment * s;
  259 + int found;
253 260
254 261 // find the relevant node and it's parent
255   - while (NULL != node) {
256   -
257   - if (element->size < node->size) {
258   - node = node->left;
259   - } else if (element->size > node->size) {
260   - node = node->right;
261   - } else {
262   - if (NULL != node->next) {
263   - if (NULL != node->parent) {
264   - if (node == node->parent->left) {
265   - node->parent->left = node->next;
266   - } else {
267   - node->parent->right = node->next;
268   - }
269   - } else {
270   - *tree = node->next;
271   - }
  262 + TR_TREE_FIND(node, element, found, _memSegmentCompare);
272 263
273   - if (NULL != node->left) {
274   - node->left->parent = node->next;
275   - }
  264 + //while (node) {
  265 + if (found != 0) {
  266 + return NULL;
  267 + } else {
  268 + if (NULL != node->next) {
  269 + if (NULL != node->parent) {
  270 + if (node == node->parent->left) {
  271 + node->parent->left = node->next;
  272 + } else {
  273 + node->parent->right = node->next;
  274 + }
  275 + } else {
  276 + *tree = node->next;
  277 + }
276 278
277   - if (NULL != node->right) {
278   - node->right->parent = node->next;
279   - }
280   -
281   - node->next->last = node->last;
282   - node->next->color = node->color;
283   - node->next->parent = node->parent;
284   - node->next->left = node->left;
285   - node->next->right = node->right;
286   -
287   - return node;
288   - }
289   - break;
290   - }
291   - }
  279 + if (NULL != node->left) {
  280 + node->left->parent = node->next;
  281 + }
292 282
293   - // element not found
294   - if (NULL == node) {
295   - return node;
296   - }
  283 + if (NULL != node->right) {
  284 + node->right->parent = node->next;
  285 + }
  286 +
  287 + node->next->last = node->last;
  288 + node->next->color = node->color;
  289 + node->next->parent = node->parent;
  290 + node->next->left = node->left;
  291 + node->next->right = node->right;
  292 +
  293 + return node;
  294 + }
  295 + }
297 296
298 297 del_node = node;
299 298
... ...
Please register or login to post a comment