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,6 +3,7 @@ nobase_include_HEADERS = trbase.h \
3 tr/commons.h \ 3 tr/commons.h \
4 tr/interface.h \ 4 tr/interface.h \
5 tr/memory.h \ 5 tr/memory.h \
  6 + tr/tree_macros.h \
6 tr/interface/class.h \ 7 tr/interface/class.h \
7 tr/interface/indexable.h \ 8 tr/interface/indexable.h \
8 tr/interface/observer.h \ 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,6 +98,30 @@ newElement(size_t size)
98 return element; 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 * find element in tree 126 * find element in tree
103 */ 127 */
@@ -105,23 +129,11 @@ static @@ -105,23 +129,11 @@ static
105 struct memSegment * 129 struct memSegment *
106 findElement(struct memSegment * tree, size_t size) 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,6 +147,7 @@ insertElement(struct memSegment ** tree, struct memSegment * element)
135 struct memSegment * new_node = NULL; 147 struct memSegment * new_node = NULL;
136 struct memSegment * u; 148 struct memSegment * u;
137 struct memSegment * g; 149 struct memSegment * g;
  150 + int found;
138 151
139 element->next = NULL; 152 element->next = NULL;
140 element->last = NULL; 153 element->last = NULL;
@@ -144,42 +157,35 @@ insertElement(struct memSegment ** tree, struct memSegment * element) @@ -144,42 +157,35 @@ insertElement(struct memSegment ** tree, struct memSegment * element)
144 element->left = NULL; 157 element->left = NULL;
145 element->right = NULL; 158 element->right = NULL;
146 159
  160 + TR_TREE_FIND(node, element, found, _memSegmentCompare);
  161 +
147 // if tree is empty it's simple... :) 162 // if tree is empty it's simple... :)
148 if (NULL == node) { 163 if (NULL == node) {
149 *tree = node = new_node = element; 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 if (NULL != new_node) { 190 if (NULL != new_node) {
185 /* 191 /*
@@ -250,50 +256,43 @@ deleteElement(struct memSegment ** tree, struct memSegment * element) @@ -250,50 +256,43 @@ deleteElement(struct memSegment ** tree, struct memSegment * element)
250 struct memSegment * del_node; 256 struct memSegment * del_node;
251 struct memSegment * child; 257 struct memSegment * child;
252 struct memSegment * s; 258 struct memSegment * s;
  259 + int found;
253 260
254 // find the relevant node and it's parent 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 del_node = node; 297 del_node = node;
299 298
Please register or login to post a comment