Mercurial > hg > Papers > 2016 > atton-ipsjpro
changeset 43:fae89e4e6163 paper_submit
Add rbtree source
author | Yasutaka Higa <e115763@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 08 Jul 2016 11:17:21 +0900 |
parents | 208740c1f020 |
children | 452ac26cb3c7 |
files | paper/vmpcbc.pdf paper/vmpcbc.tex |
diffstat | 2 files changed, 352 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/paper/vmpcbc.tex Thu Jul 07 19:32:23 2016 +0900 +++ b/paper/vmpcbc.tex Fri Jul 08 11:17:21 2016 +0900 @@ -5,6 +5,8 @@ \usepackage[dvipdfmx]{graphicx} \usepackage{latexsym} \usepackage{listings} +\usepackage[font=bf,skip=\baselineskip]{caption} +\captionsetup[lstlisting]{font={small,tt}} \lstset{ language={C}, basicstyle={\scriptsize}, @@ -617,7 +619,356 @@ \end{thebibliography} -\appendix % TODO: red-black tree のコード +\appendix + +% {{{ CbCで記述された赤黒木のコード + +\section{CbCで記述された赤黒木のコード} +CbCで記述された赤黒木のソースコードをCode\ref{src:rbtree-full} に示す。 + + +\begin{lstlisting}[ caption={CbCで記述された赤黒木}, label=src:rbtree-full ] +enum Relational { + EQ, + GT, + LT, +}; + +enum UniqueData { + Allocate, + Tree, + Node, +}; + +struct Context { + enum Code next; + int codeNum; + __code (**code) (struct Context*); + void* heapStart; + void* heap; + long heapLimit; + int dataNum; + stack_ptr code_stack; + stack_ptr node_stack; + union Data **data; +}; + +union Data { + struct Comparable { // inteface + enum Code compare; + union Data* data; + } compare; + struct Count { + enum Code next; + long i; + } count; + struct Tree { + enum Code next; + struct Node* root; + struct Node* current; + struct Node* deleted; + 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; + } node; + struct Allocate { + enum Code next; + long size; + } allocate; +}; + + +__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); + + context->next = StackClear; + 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; + stack_push(context->node_stack, &newNode); + + 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; + } + + context->data[Allocate]->allocate.size = sizeof(struct Node); + allocator(context); + + if (tree->current) { + compare(context, tree, tree->current->key, context->data[Node]->node.key); + goto meta(context, Replace); + } + + 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; + + 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 (!isEmpty(context->node_stack)) + goto meta(context, InsertCase2); + + tree->root->color = Black; + + 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) { + struct Node* parent; + stack_pop(context->node_stack, &parent); + + if (parent->color == Black) { + stack_pop(context->code_stack, &context->next); + goto meta(context, context->next); + } + + stack_push(context->node_stack, &parent); + 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* parent; + struct Node* uncle; + struct Node* grandparent; + + stack_pop(context->node_stack, &parent); + stack_pop(context->node_stack, &grandparent); + + if (grandparent->left == parent) + uncle = grandparent->right; + else + uncle = grandparent->left; + + if (uncle && (uncle->color == Red)) { + parent->color = Black; + uncle->color = Black; + grandparent->color = Red; + tree->current = grandparent; + goto meta(context, InsertCase1); + } + + stack_push(context->node_stack, &grandparent); + stack_push(context->node_stack, &parent); + + 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 Tree* tree, struct Node* current) { + struct Node* parent; + struct Node* grandparent; + + stack_pop(context->node_stack, &parent); + stack_pop(context->node_stack, &grandparent); + + stack_push(context->node_stack, &grandparent); + + tree->current = parent; + + if ((current == parent->right) && (parent == grandparent->left)) { + context->next = InsertCase4_1; + + stack_push(context->code_stack, &context->next); + goto meta(context, RotateL); + } else if ((current == parent->left) && (parent == grandparent->right)) { + context->next = InsertCase4_2; + + stack_push(context->code_stack, &context->next); + goto meta(context, RotateR); + } + + stack_push(context->node_stack, &parent); + tree->current = current; + goto meta(context, InsertCase5); +} + +__code insert4_stub(struct Context* context) { + goto insertCase4(context, &context->data[Tree]->tree, context->data[Tree]->tree.current); +} + +__code insertCase4_1(struct Context* context, struct Tree* tree) { + stack_push(context->node_stack, &tree->current); + 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) { + stack_push(context->node_stack, &tree->current); + 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) { + struct Node* parent; + struct Node* grandparent; + + stack_pop(context->node_stack, &parent); + stack_pop(context->node_stack, &grandparent); + + parent->color = Black; + grandparent->color = Red; + + tree->current = grandparent; + + if ((current == parent->left) && (parent == grandparent->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 rotateLeft(struct Context* context, struct Node* node, struct Tree* tree) { + struct Node* tmp = node->right; + struct Node* parent = 0; + + stack_pop(context->node_stack, &parent); + + if (parent) { + if (node == parent->left) + parent->left = tmp; + else + parent->right = tmp; + } else { + tree->root = tmp; + } + + stack_push(context->node_stack, &parent); + + node->right = tmp->left; + tmp->left = node; + 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; + struct Node* parent = 0; + + stack_pop(context->node_stack, &parent); + + if (parent) { + if (node == parent->left) + parent->left = tmp; + else + parent->right = tmp; + } else { + tree->root = tmp; + } + + stack_push(context->node_stack, &parent); + + node->left = tmp->right; + tmp->right = node; + 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 stackClear(struct Context* context, stack_ptr node_stack, struct Tree* tree) { + if (stack_pop(node_stack, &tree->current) == 0) + goto meta(context, StackClear); + + tree->current = 0; + + stack_pop(context->code_stack, &context->next); + goto meta(context, context->next); +} + +__code stackClear_stub(struct Context* context) { + goto stackClear(context, context->node_stack, &context->data[Tree]->tree); +} +\end{lstlisting} + +% }}} \begin{biography} \profile{n}{比嘉健太}{1992年生。2015年琉球大学工学部情報工学科卒業。2015年琉球大学大学院理工学研究科情報工学専攻入学。}