Browse Source

Merge branch 'tree_alloc' of gitea:cameron/cs241-project into tree_alloc

Thomas Johnson 5 months ago
parent
commit
5e08be3839
1 changed files with 85 additions and 24 deletions
  1. 85
    24
      tree_alloc.c

+ 85
- 24
tree_alloc.c View File

@@ -160,30 +160,91 @@ void repair_tree_after_insert(TreeAlloc **root_ptr, TreeAlloc *ta) {
160 160
 	}
161 161
 }
162 162
 
163
-// TODO: Rewrite for self-balancing tree.
164
-void remove_node(TreeAlloc** root_ptr, TreeAlloc* node) {
165
-  TreeAlloc *replace = NULL;
166
-  if (node->left == NULL) {
167
-    replace = node->right;
168
-  } else if (node->right != NULL) {
169
-    replace = node->right;
170
-    TreeAlloc *head = node->left;
171
-    while (head->right != NULL) {
172
-      head = head->right;
173
-    }
174
-    head->right = head->parent->right;
175
-    head->right->parent = head;
176
-  }
177
-  if (node->parent == NULL) {
178
-    replace->parent = NULL;
179
-    *root_ptr = replace;
180
-  } else {
181
-    if (node == node->parent->left) {
182
-      node->parent->left = replace;
183
-    } else {
184
-      node->parent->right = replace;
185
-    }
186
-  }
163
+void replace_node(TreeAlloc **root_ptr, TreeAlloc *node, TreeAlloc *replace) {
164
+	if (!node->parent) {
165
+		*root_ptr = replace;
166
+	} else {
167
+		if (node == node->parent->left)
168
+			node->parent->left = replace;
169
+		else 
170
+			node->parent->right = replace;
171
+	}
172
+	if (!replace) replace->parent = node->parent;
173
+}
174
+
175
+void repair_after_remove(TreeAlloc **root_ptr, TreeAlloc *node) {
176
+	if (node->color == COLOR_RED) {
177
+		node->color = COLOR_BLACK;
178
+	} else {
179
+		TreeAlloc *sibling = get_sibling(node);
180
+		if (sibling->color == COLOR_RED) {
181
+			if (node->parent->left == node)
182
+				rotate_left(root_ptr, node->parent);
183
+			else
184
+				rotate_right(root_ptr, node->parent);
185
+			node->parent->parent->color = node->parent->color = COLOR_BLACK;
186
+		} 
187
+
188
+		if (sibling->left->color == COLOR_BLACK && sibling->right->color == COLOR_BLACK) {
189
+			node->color = COLOR_BLACK;
190
+			sibling->color = COLOR_RED;
191
+			repair_after_remove(root_ptr, parent);
192
+		} else {
193
+			if (node->parent->left == node && sibling->right->color == COLOR_BLACK) {
194
+				rotate_right(root_ptr, sibling);
195
+				sibling = get_sibling(node);
196
+				sibling->color = COLOR_RED;
197
+				sibling->right->color = COLOR_RED;
198
+
199
+				rotate_left(root_ptr, parent);
200
+				node->color = get_sibling(node->parent)->color = COLOR_BLACK;
201
+			} else if (node->parent->right == node && sibling->left->color == COLOR_BLACK) {
202
+				rotate_left(root_ptr, sibling);
203
+				sibling = get_sibling(node);
204
+				sibling->color = COLOR_RED;
205
+				sibling->left->color = COLOR_RED;
206
+
207
+				rotate_right(root_ptr, sibling);
208
+				node->color = get_sibling(node->parent)->color = COLOR_BLACK;
209
+			}
210
+			node->parent->color ^= node->parent->parent->color;
211
+			node->parent->parent->color ^= node->parent->color;
212
+			node->parent->color ^= node->parent->parent->color;
213
+		}
214
+	}
215
+}
216
+
217
+void remove_node(TreeAlloc **root_ptr, TreeAlloc *node) {
218
+	char do_repair = 0;
219
+	TreeAlloc *replace;
220
+	TreeAlloc *parent = node->parent;
221
+	if (!node->left) {
222
+		replace = node->right;
223
+		do_fix = node->color == COLOR_BLACK;
224
+		replace_node(root_ptr, node, replace);
225
+	} else if (!node->right) {
226
+		replace = node->left;
227
+		do_fix = node->color == COLOR_BLACK;
228
+		replace_node(root_ptr, node, replace);
229
+	} else {
230
+		TreeAlloc *tmp = node->right;
231
+		while (tmp->left) tmp = tmp->left;
232
+		replace = tmp->right;
233
+		do_fix = tmp == COLOR_BLACK;
234
+		if (tmp != node->right) {
235
+			replace_node(root_ptr, tmp, replace);
236
+			tmp->right = node->right;
237
+			node->right->parent = tmp;
238
+		}
239
+		replace_node(root_ptr, node, tmp);
240
+		tmp->color = node->color;
241
+		tmp->left = node->left;
242
+		node->left->parent = tmp;
243
+	}
244
+
245
+	if (do_repair) {
246
+		repair_after_remove(root_ptr, replace);
247
+	}
187 248
 }
188 249
 
189 250
 

Loading…
Cancel
Save