Mercurial > hg > GearsTemplate
changeset 77:618c03f25108
implement insert(tail recursion)
author | Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 27 Nov 2015 02:14:25 +0900 |
parents | 7ad6d1502a03 |
children | 765ee56d68f1 099d85f9d371 |
files | src/llrb/llrb.c src/llrb/llrbContext.c src/llrb/llrbContext.h src/llrb/main.c |
diffstat | 4 files changed, 155 insertions(+), 47 deletions(-) [+] |
line wrap: on
line diff
--- a/src/llrb/llrb.c Tue Nov 17 16:59:48 2015 +0900 +++ b/src/llrb/llrb.c Fri Nov 27 02:14:25 2015 +0900 @@ -29,15 +29,12 @@ } __code replaceNode(struct Context* context, struct Tree* tree, struct Node* oldNode, struct Node* newNode, int result) { - stack_push(context->node_stack, &newNode); - *newNode = *oldNode; if (result == 0) { - stack_pop(context->node_stack, &tree->current); newNode->value = context->data[Node]->node.value; - goto meta(context, Balance1); + goto meta(context, SetRoot); } else if (result == 1) { tree->current = oldNode->right; newNode->right = context->heap; @@ -49,11 +46,12 @@ allocator(context); if (tree->current) { + tree->current->parent = newNode; compare(context, tree, tree->current->key, context->data[Node]->node.key); goto meta(context, Replace); } - - stack_pop(context->node_stack, &tree->current); + + tree->current = newNode; goto meta(context, Insert); } @@ -62,15 +60,10 @@ } __code balance1(struct Context* context, struct Node* current) { - if (current->right) - if (current->right->color == Red) { - context->next = Balance2; - - stack_push(context->code_stack, &context->next); - goto meta(context, RotateL); - } - - goto meta(context, Balance2); + if (current->parent == 0) + goto meta(context, SetRoot); + else + goto meta(context, Balance2); } __code balance1_stub(struct Context* context) { @@ -78,47 +71,110 @@ } __code balance2(struct Context* context, struct Node* current) { - if (current->left) - if (current->left->left) - if (current->left->color == Red && current->left->left->color == Red) { - context->next = Balance3; - - stack_push(context->code_stack, &context->next); - goto meta(context, RotateR); - } - - goto meta(context, Balance3); + if (current->parent->color == Black) + goto meta(context, SetRoot); + else + goto meta(context, Balance3); } __code balance2_stub(struct Context* context) { goto balance2(context, context->data[Tree]->tree.current); } -__code balance3(struct Context* context, struct Node* current){ - if (current->right && current->left) - if (current->right->color == Red && current->left->color == Red) { - context->next = FixUp; +__code balance3(struct Context* context, struct Tree* tree, struct Node* current) { + struct Node* uncle; + struct Node* grandparent = current->parent->parent; - stack_push(context->code_stack, &context->next); - goto meta(context, ColorFlip); - } + if (grandparent == 0) + uncle = 0; + + if (grandparent->left == current->parent) + uncle = grandparent->right; + else + uncle = grandparent->left; - goto meta(context, FixUp); + if ((uncle != 0) && (uncle->color == Red)) { + current->parent->color = Black; + uncle->color = Black; + grandparent->color = Red; + tree->current = grandparent; + goto meta(context, Balance1); + } else { + goto meta(context, Balance4); + } } __code balance3_stub(struct Context* context) { - goto balance3(context, context->data[Tree]->tree.current); + goto balance3(context, context->data[Tree], context->data[Tree]->tree.current); +} + +__code balance4(struct Context* context, struct Node* current) { + struct Node* grandparent = current->parent->parent; + + if ((current == current->parent->right) && (current->parent == grandparent->left)) { + context->next = Balance4_1; + + stack_push(context->code_stack, &context->next); + goto meta(context, RotateL); + } else if ((current == current->parent->left) && (current->parent == grandparent->right)) { + context->next = Balance4_2; + + stack_push(context->code_stack, &context->next); + goto meta(context, RotateR); + } + + goto meta(context, Balance5); +} + +__code balance4_stub(struct Context* context) { + goto balance4(context, context->data[Tree]->tree.current); +} + +__code balance4_1(struct Context* context, struct Tree* tree) { + tree->current = tree->current->left; + goto meta(context, Balance5); +} + +__code balance4_1_stub(struct Context* context) { + goto balance4_1(context, context->data[Tree]); +} + +__code balance4_2(struct Context* context, struct Tree* tree) { + tree->current = tree->current->right; + goto meta(context, Balance5); +} + +__code balance4_2_stub(struct Context* context) { + goto balance4_2(context, context->data[Tree]); +} + +__code balance5(struct Context* context, struct Tree* tree, struct Node* current) { + current->parent->color = Black; + current->parent->parent->color = Red; + + context->next = SetRoot; + + stack_push(context->code_stack, &context->next); + tree->current = current->parent->parent; + + if ((current == current->parent->left) && (current->parent == current->parent->parent->left)) + goto meta(context, RotateR); + else + goto meta(context, RotateL); +} + +__code balance5_stub(struct Context* context) { + goto balance5(context, context->data[Tree], context->data[Tree]->tree.current); } __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; - if (tree->root) - goto meta(context, Balance1); - - tree->current = newNode; - goto meta(context, SetRoot); + goto meta(context, Balance1); } __code insertNode_stub(struct Context* context) { @@ -127,10 +183,26 @@ __code rotateLeft(struct Context* context, struct Node* node, struct Tree* tree) { struct Node* tmp = node->right; + + if (node->parent == 0) { + tree->root = tmp; + } else { + if (node == node->parent->left) + node->parent->left = tmp; + else + node->parent->right = tmp; + } + + if (tmp != 0) + tmp->parent = node->parent; + node->right = tmp->left; + + if (tmp->left != 0) + tmp->left->parent = node; + tmp->left = node; - tmp->color = node->color; - node->color = Red; + node->parent = tmp; tree->current = tmp; stack_pop(context->code_stack, &context->next); @@ -143,11 +215,27 @@ __code rotateRight(struct Context* context, struct Node* node, struct Tree* tree) { struct Node* tmp = node->left; + + if (node->parent == 0) { + tree->root = tmp; + } else { + if (node == node->parent->left) + node->parent->left = tmp; + else + node->parent->right = tmp; + } + + if (tmp != 0) + tmp->parent = node->parent; + node->left = tmp->right; + + if (tmp->right != 0) + tmp->right->parent = node; + tmp->right = node; - tmp->color = node->color; - node->color = Red; - context->data[Tree]->tree.current = tmp; + node->parent = tmp; + tree->current = tmp; stack_pop(context->code_stack, &context->next); goto meta(context, context->next); @@ -191,6 +279,11 @@ } __code setRoot(struct Context* context, struct Tree* tree, struct Node* node) { + if(node->parent) { + tree->current = tree->current->parent; + goto meta(context, SetRoot); + } + tree->root = node; tree->root->color = Black; tree->current = 0;
--- a/src/llrb/llrbContext.c Tue Nov 17 16:59:48 2015 +0900 +++ b/src/llrb/llrbContext.c Fri Nov 27 02:14:25 2015 +0900 @@ -22,6 +22,10 @@ extern __code balance1_stub(struct Context*); extern __code balance2_stub(struct Context*); extern __code balance3_stub(struct Context*); +extern __code balance4_stub(struct Context*); +extern __code balance4_1_stub(struct Context*); +extern __code balance4_2_stub(struct Context*); +extern __code balance5_stub(struct Context*); extern __code setRoot_stub(struct Context*); extern __code get_stub(struct Context*); extern __code findMin_stub(struct Context*); @@ -66,6 +70,10 @@ context->code[Balance1] = balance1_stub; context->code[Balance2] = balance2_stub; context->code[Balance3] = balance3_stub; + context->code[Balance4] = balance4_stub; + context->code[Balance4_1] = balance4_1_stub; + context->code[Balance4_2] = balance4_2_stub; + context->code[Balance5] = balance5_stub; context->code[SetRoot] = setRoot_stub; context->code[Get] = get_stub; context->code[Delete] = delete_stub;
--- a/src/llrb/llrbContext.h Tue Nov 17 16:59:48 2015 +0900 +++ b/src/llrb/llrbContext.h Fri Nov 27 02:14:25 2015 +0900 @@ -27,6 +27,10 @@ Balance1, Balance2, Balance3, + Balance4, + Balance4_1, + Balance4_2, + Balance5, Get, FindMin, Delete, @@ -80,15 +84,18 @@ int result; } tree; struct Node { + // need to tree enum Code next; int key; // comparable data segment int value; + struct Node* left; + struct Node* right; + // need to balancing enum Color { Red, Black, } color; - struct Node* left; - struct Node* right; + struct Node* parent; } node; struct Allocate { enum Code next;