changeset 20:324c44f2076f

implement insert
author Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
date Tue, 28 Apr 2015 04:31:19 +0900
parents 9302b1a48008
children 737a900518be
files src/llrb/llrb.c src/llrb/llrbContext.c src/llrb/llrbContext.h
diffstat 3 files changed, 86 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/src/llrb/llrb.c	Tue Apr 21 22:36:23 2015 +0900
+++ b/src/llrb/llrb.c	Tue Apr 28 04:31:19 2015 +0900
@@ -15,6 +15,9 @@
 #define ALLOCATE_SIZE 1024
 
 extern __code initLLRBContext(struct Context* context);
+void colorFlip(struct Context*);
+void rotateLeft(struct Context*);
+void rotateRight(struct Context*);
 /* 
 __code code1(Allocate allocate) {
     allocate.size = sizeof(long);
@@ -27,6 +30,8 @@
     context->data[0]->allocate.size = sizeof(struct Node);
     context->data[0]->allocate.next = Put;
     context->data[0]->allocate.after_put = Code2;
+    context->data[0]->allocate.key = 0;
+    context->data[0]->allocate.value = 0;
     goto meta(context, Allocate);
 }
 
@@ -39,16 +44,92 @@
     context->data[context->dataSize]->node.value = context->data[0]->allocate.value;
     if (context->root == 0) {
         context->root = context->data[context->dataSize];
-        context->root->node.color = Red;
+        context->root->node.color = Black;
         goto meta(context, context->data[0]->allocate.after_put);
     }
+    context->data[context->dataSize]->node.color = Red;
+    context->current = context->root;
     goto meta(context, Insert);
 }
 
 __code insert(struct Context* context) {
+    int persistentKey = context->current->node.key;
+    int temporalKey = context->data[context->dataSize]->node.key;
+    
+    if (context->current->node.right != 0 && context->current->node.left != 0) {
+        if (context->current->node.right->node.color == Red && context->current->node.left->node.color == Red) {
+            colorFlip(context);
+        }
+    }
+    
+    if (persistentKey == temporalKey) {
+        context->current->node.value = context->data[context->dataSize]->node.value;
+        goto meta(context, context->data[0]->allocate.after_put);
+    } else if (persistentKey < temporalKey) {
+        if (context->current->node.left == 0) {
+            context->current->node.left = context->data[context->dataSize];
+        } else {
+            context->current = context->current->node.left;
+            goto meta(context, Insert);
+        }
+    } else {
+        if (context->current->node.right == 0) {
+            context->current->node.right = context->data[context->dataSize];
+        } else {
+            context->current = context->current->node.right;
+            goto meta(context, Insert);
+        }
+    }
+
+    if (context->current->node.right != 0) {
+        if (context->current->node.right->node.color == Red) {
+            rotateLeft(context);
+        }
+    }
+
+    if (context->current->node.left != 0) {
+        if (context->current->node.left->node.left != 0) {
+            if (context->current->node.left->node.color == Red && context->current->node.left->node.left->node.color == Red) {
+                rotateRight(context);
+            }
+        }
+    }
+
+    if (context->current->node.right != 0 && context->current->node.left != 0) {
+        if (context->current->node.right->node.color == Red && context->current->node.left->node.color == Red) {
+            colorFlip(context);
+        }
+    }    
+    
+    context->root->node.color = Black;
+    
     goto meta(context, context->data[0]->allocate.after_put);
 }
 
+void rotateLeft(struct Context* context) {
+    union Data* tmp = context->current->node.right;
+    context->current->node.right = tmp->node.left;
+    tmp->node.left = context->current;
+    tmp->node.color = tmp->node.left->node.color;
+    tmp->node.left->node.color = Red;
+    context->current = tmp;
+}
+
+void rotateRight(struct Context* context) {
+    union Data* tmp = context->current->node.left;
+    context->current->node.left = tmp->node.right;
+    tmp->node.right = context->current;
+    tmp->node.color = tmp->node.right->node.color;
+    tmp->node.right->node.color = Red;
+    context->current = tmp;
+}
+
+void colorFlip(struct Context* context) {
+    context->current->node.color ^= 1;
+    context->current->node.left->node.color ^= 1;
+    context->current->node.right->node.color ^= 1;
+}
+
 /*
 __code code2(Allocate allocate, Count count) {
     count.count = 0;
--- a/src/llrb/llrbContext.c	Tue Apr 21 22:36:23 2015 +0900
+++ b/src/llrb/llrbContext.c	Tue Apr 28 04:31:19 2015 +0900
@@ -19,4 +19,7 @@
     context->dataSize = 0;
     context->data[context->dataSize] = context->heap;
     context->heap += sizeof(struct Allocate);
+
+    context->root = 0;
+    context->current = 0;
 }
--- a/src/llrb/llrbContext.h	Tue Apr 21 22:36:23 2015 +0900
+++ b/src/llrb/llrbContext.h	Tue Apr 28 04:31:19 2015 +0900
@@ -19,6 +19,7 @@
     __code (**code) (struct Context *);
     void* heap;
     union Data* root;
+    union Data* current;
     int dataSize;
     union Data **data;
 };