Mercurial > hg > GearsTemplate
view src/llrb/llrb.c @ 81:dc6f665bb753
implement delete(tail call). do not work
author | Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 11 Dec 2015 15:06:20 +0900 |
parents | 099d85f9d371 |
children | c13575c3dbe9 |
line wrap: on
line source
#include <stdio.h> #include "llrbContext.h" #include "origin_cs.h" extern void allocator(struct Context* context); extern void compare(struct Context* context, struct Tree* tree, int key1, int key2); extern int num; __code put(struct Context* context, struct Tree* tree, struct Node* root, struct Allocate* allocate) { allocate->size = sizeof(struct Node); allocator(context); stack_push(context->code_stack, &context->next); tree->root = &context->data[context->dataNum]->node; if (root) { tree->current = root; compare(context, tree, tree->current->key, context->data[Node]->node.key); goto meta(context, Replace); } goto meta(context, Insert); } __code put_stub(struct Context* context) { goto put(context, &context->data[Tree]->tree, context->data[Tree]->tree.root, &context->data[Allocate]->allocate); } __code replaceNode(struct Context* context, struct Tree* tree, struct Node* oldNode, struct Node* newNode, int result) { *newNode = *oldNode; if (result == EQ) { newNode->value = context->data[Node]->node.value; stack_pop(context->code_stack, &context->next); goto meta(context, context->next); } else if (result == GT) { tree->current = oldNode->right; newNode->right = context->heap; } else { tree->current = oldNode->left; newNode->left = context->heap; } allocator(context); if (tree->current) { tree->current->parent = newNode; compare(context, tree, tree->current->key, context->data[Node]->node.key); goto meta(context, Replace); } tree->current = newNode; goto meta(context, Insert); } __code replaceNode_stub(struct Context* context) { goto replaceNode(context, &context->data[Tree]->tree, context->data[Tree]->tree.current, &context->data[context->dataNum]->node, context->data[Tree]->tree.result); } __code insertNode(struct Context* context, struct Tree* tree, struct Node* node, struct Node* newNode) { node->color = Red; *newNode = *node; newNode->parent = tree->current; tree->current = newNode; goto meta(context, InsertCase1); } __code insertNode_stub(struct Context* context) { goto insertNode(context, &context->data[Tree]->tree, &context->data[Node]->node, &context->data[context->dataNum]->node); } __code insertCase1(struct Context* context, struct Tree* tree, struct Node* current) { if (current->parent) goto meta(context, InsertCase2); tree->root->color = Black; tree->current = 0; stack_pop(context->code_stack, &context->next); goto meta(context, context->next); } __code insert1_stub(struct Context* context) { goto insertCase1(context, &context->data[Tree]->tree, context->data[Tree]->tree.current); } __code insertCase2(struct Context* context, struct Node* current) { if (current->parent->color == Black) { stack_pop(context->code_stack, &context->next); goto meta(context, context->next); } goto meta(context, InsertCase3); } __code insert2_stub(struct Context* context) { goto insertCase2(context, context->data[Tree]->tree.current); } __code insertCase3(struct Context* context, struct Tree* tree, struct Node* current) { struct Node* uncle; struct Node* grandparent = current->parent->parent; if (grandparent->left == current->parent) uncle = grandparent->right; else uncle = grandparent->left; if (uncle && (uncle->color == Red)) { current->parent->color = Black; uncle->color = Black; grandparent->color = Red; tree->current = grandparent; goto meta(context, InsertCase1); } goto meta(context, InsertCase4); } __code insert3_stub(struct Context* context) { goto insertCase3(context, &context->data[Tree]->tree, context->data[Tree]->tree.current); } __code insertCase4(struct Context* context, struct Node* current) { struct Node* grandparent = current->parent->parent; if ((current == current->parent->right) && (current->parent == grandparent->left)) { context->next = InsertCase4_1; stack_push(context->code_stack, &context->next); goto meta(context, RotateL); } else if ((current == current->parent->left) && (current->parent == grandparent->right)) { context->next = InsertCase4_2; stack_push(context->code_stack, &context->next); goto meta(context, RotateR); } goto meta(context, InsertCase5); } __code insert4_stub(struct Context* context) { goto insertCase4(context, context->data[Tree]->tree.current); } __code insertCase4_1(struct Context* context, struct Tree* tree) { tree->current = tree->current->left; goto meta(context, InsertCase5); } __code insert4_1_stub(struct Context* context) { goto insertCase4_1(context, &context->data[Tree]->tree); } __code insertCase4_2(struct Context* context, struct Tree* tree) { tree->current = tree->current->right; goto meta(context, InsertCase5); } __code insert4_2_stub(struct Context* context) { goto insertCase4_2(context, &context->data[Tree]->tree); } __code insertCase5(struct Context* context, struct Tree* tree, struct Node* current) { current->parent->color = Black; current->parent->parent->color = Red; tree->current = current->parent->parent; context->next = InsertCase5_1; stack_push(context->code_stack, &context->next); if ((current == current->parent->left) && (current->parent == current->parent->parent->left)) goto meta(context, RotateR); else goto meta(context, RotateL); } __code insert5_stub(struct Context* context) { goto insertCase5(context, &context->data[Tree]->tree, context->data[Tree]->tree.current); } __code insertCase5_1(struct Context* context, struct Tree* tree) { tree->current = NULL; stack_pop(context->code_stack, &context->next); goto meta(context, context->next); } __code insert5_1_stub(struct Context* context) { goto insertCase5_1(context, &context->data[context->dataNum]->tree); } __code rotateLeft(struct Context* context, struct Node* node, struct Tree* tree) { struct Node* tmp = node->right; if (node->parent) { if (node == node->parent->left) node->parent->left = tmp; else node->parent->right = tmp; } else { tree->root = tmp; } if (tmp) tmp->parent = node->parent; node->right = tmp->left; if (tmp->left) tmp->left->parent = node; tmp->left = node; node->parent = tmp; tree->current = tmp; stack_pop(context->code_stack, &context->next); goto meta(context, context->next); } __code rotateLeft_stub(struct Context* context) { goto rotateLeft(context, context->data[Tree]->tree.current, &context->data[Tree]->tree); } __code rotateRight(struct Context* context, struct Node* node, struct Tree* tree) { struct Node* tmp = node->left; if (node->parent) { if (node == node->parent->left) node->parent->left = tmp; else node->parent->right = tmp; } else { tree->root = tmp; } if (tmp) tmp->parent = node->parent; node->left = tmp->right; if (tmp->right) tmp->right->parent = node; tmp->right = node; node->parent = tmp; tree->current = tmp; stack_pop(context->code_stack, &context->next); goto meta(context, context->next); } __code rotateRight_stub(struct Context* context) { goto rotateRight(context, context->data[Tree]->tree.current, &context->data[Tree]->tree); } __code get(struct Context* context, struct Tree* tree) { if (tree->root) { tree->current = tree->root; goto meta(context, Search); } stack_pop(context->code_stack, &context->next); goto meta(context, context->next); } __code get_stub(struct Context* context) { goto get(context, &context->data[Tree]->tree); } __code search(struct Context* context, struct Tree* tree, struct Node* node) { compare(context, tree, tree->current->key, node->key); if (tree->result == EQ) { *node = *tree->current; goto meta(context, context->next); } else if (tree->result == GT) { tree->current = tree->current->right; } else { tree->current = tree->current->left; } if (tree->current) goto meta(context, Search); stack_pop(context->code_stack, &context->next); goto meta(context, context->next); } __code search_stub(struct Context* context) { goto search(context, &context->data[Tree]->tree, &context->data[Node]->node); } __code delete(struct Context* context, struct Tree* tree) { if (tree->root) { stack_push(context->code_stack, &context->next); context->next = Delete1; goto meta(context, Get); } goto meta(context, context->next); } __code delete_stub(struct Context* context) { goto delete(context, &context->data[Tree]->tree); } __code delete1(struct Context* context, struct Tree* tree, struct Allocate* allocate) { allocate->size = sizeof(struct Node); allocator(context); struct Node* root = tree->root; tree->root = &context->data[context->dataNum]->node; tree->current = root; compare(context, tree, tree->current->key, context->data[Node]->node.key); goto meta(context, Replace_d1); } __code delete1_stub(struct Context* context) { goto delete1(context, &context->data[Tree]->tree, &context->data[Allocate]->allocate); } __code delete2(struct Context* context, struct Node* current) { if (current->color == Black) { struct Node* child = current->right == NULL ? current->left : current->right; current->color = child == NULL ? Black : child->color; goto meta(context, DeleteCase1); } goto meta(context, Delete3); } __code delete2_stub(struct Context* context) { goto delete2(context, context->data[Tree]->tree.current); } __code delete3(struct Context* context, struct Tree* tree, struct Node* current) { struct Node* tmp = current->right == NULL ? current->left : current->right; if (current->parent) { if (current == current->parent->left) current->parent->left = tmp; else current->parent->right = tmp; } else { tree->root = tmp; } if (tmp) tmp->parent = current->parent; if (current->parent == NULL && tmp) tmp->color = Black; current == current->parent->left ? (current->parent->left = NULL) : (current->parent->right = NULL); stack_pop(context->code_stack, &context->next); goto meta(context, context->next); } __code delete3_stub(struct Context* context) { goto delete3(context, &context->data[Tree]->tree, context->data[Tree]->tree.current); } __code replaceNodeForDelete1(struct Context* context, struct Tree* tree, struct Node* oldNode, struct Node* newNode, int result) { *newNode = *oldNode; if (result == EQ) goto meta(context, Replace_d2); else if (result == GT) tree->current = newNode->right; else tree->current = newNode->left; tree->current->parent = newNode; if (tree->current->left == NULL && tree->current->right == NULL) goto meta(context, Delete2); if (result == GT) newNode->right = context->heap; else if (result == LT) newNode->left = context->heap; allocator(context); compare(context, tree, tree->current->key, context->data[Node]->node.key); goto meta(context, Replace_d1); } __code replaceNodeForDelete1_stub(struct Context* context) { goto replaceNodeForDelete1(context, &context->data[Tree]->tree, context->data[Tree]->tree.current, &context->data[context->dataNum]->node, context->data[Tree]->tree.result); } __code replaceNodeForDelete2(struct Context* context, struct Tree* tree, struct Node* newNode) { if (tree->current->left && tree->current->right) { newNode->left->parent = newNode; tree->current = newNode->left; newNode->left = context->heap; tree->deleted = newNode; allocator(context); tree->current->parent = newNode; goto meta(context, FindMax1); } goto meta(context, Delete2); } __code replaceNodeForDelete2_stub(struct Context* context) { goto replaceNodeForDelete2(context, &context->data[Tree]->tree, &context->data[context->dataNum]->node); } __code findMax1(struct Context* context, struct Tree* tree, struct Node* oldNode, struct Node* newNode) { *newNode = *oldNode; if (newNode->right) goto meta(context, FindMax2); tree->deleted->key = newNode->key; tree->deleted->value = newNode->value; tree->current = newNode; goto meta(context, Delete2); } __code findMax1_stub(struct Context* context) { goto findMax1(context, &context->data[Tree]->tree, context->data[Tree]->tree.current, &context->data[context->dataNum]->node); } __code findMax2(struct Context* context, struct Tree* tree, struct Node* oldNode, struct Node* newNode) { *newNode = *oldNode; if (newNode->right->right) { tree->current = newNode->right; newNode->right = context->heap; allocator(context); tree->current->parent = newNode; goto meta(context, FindMax2); } tree->deleted->key = newNode->right->key; tree->deleted->value = newNode->right->value; tree->current = newNode; goto meta(context, Delete2); } __code findMax2_stub(struct Context* context) { goto findMax2(context, &context->data[Tree]->tree, context->data[Tree]->tree.current, &context->data[context->dataNum]->node); } __code deleteCase1(struct Context* context, struct Node* current) { if (current->parent) goto meta(context, DeleteCase2); goto meta(context, Delete3); } __code deleteCase1_stub(struct Context* context) { goto deleteCase1(context, context->data[Tree]->tree.current); } __code deleteCase2(struct Context* context, struct Tree* tree, struct Node* current) { struct Node* sibling = current == current->parent->left ? current->parent->right : current->parent->left; if ((sibling == NULL ? Black : sibling->color) == Red) { current->parent->color = Red; sibling->color = Black; current == current->parent->left ? (current->parent->left = context->heap) : (current->parent->right = context->heap); allocator(context); context->data[context->dataNum]->node = *sibling; tree->current = current->parent; context->next = DeleteCase3; stack_push(context->code_stack, &context->next); if (current == current->parent->left) goto meta(context, RotateL); else goto meta(context, RotateR); } goto meta(context, DeleteCase3); } __code deleteCase2_stub(struct Context* context) { goto deleteCase2(context, &context->data[Tree]->tree, context->data[Tree]->tree.current); } __code deleteCase3(struct Context* context, struct Tree* tree, struct Node* current) { struct Node* sibling = current == current->parent->left ? current->parent->right : current->parent->left; if (current->parent->color == Black && (sibling == NULL ? Black : sibling->color) == Black && (sibling->left == NULL ? Black : sibling->left->color) == Black && (sibling->right == NULL ? Black : sibling->right->color) == Black) { sibling->color = Red; tree->current = current->parent; goto meta(context, DeleteCase1); } goto meta(context, DeleteCase4); } __code deleteCase3_stub(struct Context* context) { goto deleteCase3(context, &context->data[Tree]->tree, context->data[Tree]->tree.current); } __code deleteCase4(struct Context* context, struct Node* current) { struct Node* sibling = current == current->parent->left ? current->parent->right : current->parent->left; if (current->parent->color == Red && (sibling == NULL ? Black : sibling->color) == Black && (sibling->left == NULL ? Black : sibling->left->color) == Black && (sibling->right == NULL ? Black : sibling->right->color) == Black) { sibling->color = Red; current->parent->color = Black; goto meta(context, Delete3); } goto meta(context, DeleteCase5); } __code deleteCase4_stub(struct Context* context) { goto deleteCase4(context, context->data[Tree]->tree.current); } __code deleteCase5(struct Context* context, struct Tree* tree, struct Node* current) { struct Node* sibling = current == current->parent->left ? current->parent->right : current->parent->left; sibling->parent = current->parent; if (current == current->parent->left && (sibling == NULL ? Black : sibling->color) == Black && (sibling->left == NULL ? Black : sibling->left->color) == Red && (sibling->right == NULL ? Black : sibling->right->color) == Black) { sibling->color = Red; sibling->left->color = Black; sibling == sibling->parent->left ? (sibling->parent->left = context->heap) : (sibling->parent->right = context->heap); allocator(context); struct Node* tmp = &context->data[context->dataNum]->node; *tmp = *sibling; tmp->parent = current; tmp->left = context->heap; allocator(context); context->data[context->dataNum]->node = *sibling->left; context->data[context->dataNum]->node.parent = tmp; tree->current = tmp; context->next = DeleteCase6; stack_push(context->code_stack, &context->next); goto meta(context, RotateR); } else if (current == current->parent->right && (sibling == NULL ? Black : sibling->color) == Black && (sibling->left == NULL ? Black : sibling->left->color) == Black && (sibling->right == NULL ? Black : sibling->right->color) == Red) { sibling->color = Red; sibling->right->color = Black; sibling == sibling->parent->left ? (sibling->parent->left = context->heap) : (sibling->parent->right = context->heap); allocator(context); struct Node* tmp = &context->data[context->dataNum]->node; *tmp = *sibling; tmp->parent = current; tmp->right = context->heap; allocator(context); context->data[context->dataNum]->node = *sibling->right; context->data[context->dataNum]->node.parent = tmp; tree->current = tmp; context->next = DeleteCase6; stack_push(context->code_stack, &context->next); goto meta(context, RotateL); } goto meta(context, DeleteCase6); } __code deleteCase5_stub(struct Context* context) { goto deleteCase5(context, &context->data[Tree]->tree, context->data[Tree]->tree.current); } __code deleteCase6(struct Context* context, struct Tree* tree, struct Node* current) { struct Node* sibling = current == current->parent->left ? current->parent->right : current->parent->left; sibling == sibling->parent->left ? (sibling->parent->left = context->heap) : (sibling->parent->right = context->heap); allocator(context); struct Node* tmp = &context->data[context->dataNum]->node; *tmp = *sibling; tmp->parent = current; tmp->color = current->parent->color; current->parent->color = Black; context->next = Delete3; stack_push(context->code_stack, &context->next); if (current == current->parent->left) { tmp->right->color = Black; tree->current = current->parent; goto meta(context, RotateL); } else { tmp->left->color = Black; tree->current = current->parent; goto meta(context, RotateR); } } __code deleteCase6_stub(struct Context* context) { goto deleteCase6(context, &context->data[Tree]->tree, context->data[Tree]->tree.current); }