diff --git a/btree.c b/btree.c index 26e9763..4c2403d 100644 --- a/btree.c +++ b/btree.c @@ -10,6 +10,21 @@ struct node { int keyCount; } *tRoot = NULL; +struct nodePosition { + int key; + struct node* box; +}; + +// Left-right stack for multiple splitting +struct splitStack { + struct node *leftHalf; + struct node *rightHalf; + struct splitStack *next; +} *head = NULL; + +void pushS(struct node *leftHalf, struct node *rightHalf); +struct splitStack *popS(); + // Globals int treeOrder; @@ -23,6 +38,8 @@ void doInOrder(); // Tree Operations struct node* newNode(int value,struct node *parent); struct node* insertN(int value,struct node *root,struct node *parent); +struct nodePosition* searchNValue(int value,struct node *root); +struct nodePosition* searchNBox(struct node *toFind,struct node *root); // Printing void inOrder(struct node *root); @@ -71,7 +88,7 @@ void doInsert(){ system("cls"); printf("--- Insertion ---\n"); printf("Value: "); - scanf("%d",&value); + scanf("%d",&value); tRoot = insertN(value,tRoot,NULL); @@ -94,6 +111,11 @@ void doSearch(){ system("cls"); printf("--- Search ---\n"); + printf("To Find: "); + scanf("%d",&toFind); + + if (searchNValue(toFind,tRoot) == NULL) printf("Not found!\n"); + else printf("found!\n"); printf("\n\n\nPress any key to continue...\n"); getch(); @@ -106,7 +128,6 @@ void doInOrder(){ system("cls"); printf("--- Printing ---\n"); - //for (i = 0; i < tRoot->keyCount - 1; i++) printf("%d ", tRoot->value[i]); if (tRoot != NULL) inOrder(tRoot); else printf("\nThe tree is empty!\n"); @@ -147,7 +168,8 @@ struct node* insertN(int value,struct node *root,struct node *parent){ printf("Data Already inserted!\n"); break; } else if ( value > root->value[i] ){ // if value to be inserted is greater, then proceed to next box - if (root->keys[i+1] != NULL && root->keys[i+1]->keyCount < treeOrder + 1) { + if (root->keys[i+1] != NULL && root->keys[i+1]->keyCount < treeOrder + 1 && root->value[i+1] > value) { + PUT_RIGHT: root->keys[i+1] = insertN(value,root->keys[i+1],root); break; } else i++; @@ -155,10 +177,14 @@ struct node* insertN(int value,struct node *root,struct node *parent){ continue; } else { // This is if the value to be inserted is lesser which means, we can put it now if (root->keys[i] != NULL && root->keys[i]->keyCount < treeOrder + 1) { + PUT_LEFT: root->keys[i] = insertN(value,root->keys[i],root); break; } else { - for (j = treeOrder - 2; j >= i; j--) root->value[j+1] = root->value[j]; // move everything to the right + for (j = treeOrder - 2; j >= i; j--) { + root->value[j+1] = root->value[j]; // move everything to the right + root->keys[j+2] = root->keys[j+1]; + } root->value[i] = value; root->keyCount++; @@ -167,7 +193,12 @@ struct node* insertN(int value,struct node *root,struct node *parent){ } } - } else { // else if the box is null. Insert directly + } else { // else if the box is null or the last box. Insert directly + if (root->keys[i] != NULL && root->keys[i]->keyCount < treeOrder + 1) { + printf("Succes!\n"); + goto PUT_LEFT; + } + root->value[i] = value; root->keyCount++; @@ -189,46 +220,114 @@ struct node* insertN(int value,struct node *root,struct node *parent){ for (i = 0; i <= left; i++){ // Move all left half data to new LeftHalf Box leftHalf = insertN(root->value[i],leftHalf,NULL); // Set the parent to NULL temporarily - } + leftHalf->keys[i] = root->keys[i]; + + if (root->keys[i] != NULL) root->keys[i]->parent = leftHalf; + } leftHalf->keys[left+1] = root->keys[left+1]; + if (root->keys[treeOrder] != NULL) root->keys[treeOrder]->parent = leftHalf; for (i = right; i < treeOrder; i++){ // Move all right half data to new LeftHalf Box - rightHalf = insertN(root->value[i],rightHalf,NULL); // pointer arithmethic - } + rightHalf = insertN(root->value[i],rightHalf,NULL); + rightHalf->keys[i] = root->keys[i]; + + if (root->keys[i] != NULL) root->keys[i]->parent = rightHalf; + } rightHalf->keys[treeOrder] = root->keys[treeOrder]; + if (root->keys[treeOrder] != NULL) root->keys[treeOrder]->parent = rightHalf; + int pIsNull = parent == NULL ? 1 : 0; struct node *tempRoot = root; - root = insertN(root->value[mid],parent,parent); + struct node *pParent = pIsNull ? NULL : parent->parent; - if (parent == NULL){ // Special case if splitted is the tRoot (The very Root) - leftHalf->parent = root; - rightHalf->parent = root; - root->keys[0] = leftHalf; - root->keys[1] = rightHalf; + parent = insertN(root->value[mid],parent,pParent); + + if (pIsNull){ // Special case if splitted is the tRoot (The very Root) + leftHalf->parent = parent; + rightHalf->parent = parent; + parent->keys[0] = leftHalf; + parent->keys[1] = rightHalf; + + //free(tempRoot); // Delete old root node box + return parent; } else { - for (i = 0; i < tempRoot->parent->keyCount; i++){ - if (tempRoot->parent->keys[i] == tempRoot){ - tempRoot->parent->keys[i] = leftHalf; - tempRoot->parent->keys[i+1] = rightHalf; + // Find the parent of the current left and right box + int found = 0; + for (i = 0; i < parent->keyCount; i++){ + if (parent->keys[i] != NULL && parent->keys[i] == tempRoot){ + parent->keys[i] = leftHalf; + parent->keys[i+1] = rightHalf; + + leftHalf->parent = parent; + rightHalf->parent = parent; + found = 1; } } + + + struct nodePosition *nodeF = searchNBox(tempRoot,tRoot); + if (nodeF != NULL && !found) { + printf("Beep: i is %d\n",nodeF->key); + nodeF->box->keys[nodeF->key] = leftHalf; + nodeF->box->keys[nodeF->key+1] = rightHalf; + } + + //free(tempRoot); + return leftHalf; } // To do : Non special case split and distribute... or if parent has a parent with values - - free(tempRoot); // Delete old root node box } } return root; } +struct nodePosition* searchNValue(int value,struct node *root){ + int i; + struct nodePosition *nodeF = NULL; + if (root == NULL) return NULL; + else { + for (i = 0; i < root->keyCount; i++){ // -1 since left and right key of every data box + if (root->value[i] == value) { + nodeF = (struct nodePosition*)malloc(sizeof(struct nodePosition)); + nodeF->box = root; + nodeF->key = i; + return nodeF; + } + else if (nodeF != NULL) return nodeF; + else nodeF = searchNValue(value,root->keys[i]); + } + return nodeF; + } +} + +struct nodePosition* searchNBox(struct node *toFind,struct node *root){ + int i; + struct nodePosition *nodeF = NULL; + if (root == NULL) return NULL; + else { + for (i = 0; i < root->keyCount; i++){ // -1 since left and right key of every data box + if (root == toFind) { + nodeF = (struct nodePosition*)malloc(sizeof(struct nodePosition)); + nodeF->box = root; + nodeF->key = i; + return nodeF; + } + else if (nodeF != NULL) return nodeF; + else nodeF = searchNBox(toFind,root->keys[i]); + } + return nodeF; + } +} + // Printing void inOrder(struct node *root){ int i; if (root == NULL) return; else { - for (i = 0; i < root->keyCount - 1; i++){ // -1 since left and right key of every data box + //root = root->keys[1]->keys[3]; + for (i = 0; i < root->keyCount + 2; i++){ // -1 since left and right key of every data box inOrder(root->keys[i]); - printf("~%d~\n",root->value[i]); + if (i < root->keyCount - 1) printf("~%d~\n",root->value[i]); } } } @@ -238,12 +337,12 @@ void levelOrder(struct node *root){ if (root == NULL) return; else { for (i = 0; i < root->keyCount - 1; i++){ // -1 since left and right key of every data box - printf("%d ",root->value[i]); + printf("Node %d : %d ",i,root->value[i]); } printf(" "); if (root->parent == NULL) printf("\n"); else { - for (i = 0; i < root->parent->keyCount; i++){ // Check if had a right sibling, if none then proceed to next level + for (i = 0; i < root->parent->keyCount + 2; i++){ // Check if had a right sibling, if none then proceed to next level if (root->parent->keys[i] == root){ if (root->parent->keys[i+1] == NULL) printf("\n"); break; @@ -257,3 +356,25 @@ void levelOrder(struct node *root){ } } +void pushS(struct node *leftHalf, struct node *rightHalf){ + struct splitStack *newNode = (struct splitStack*)malloc(sizeof(struct splitStack)); + newNode->leftHalf = leftHalf; + newNode->rightHalf = rightHalf; + if (head == NULL){ + head = newNode; + head->next = NULL; + } else { + newNode->next = head; + head = newNode; + } +} + +struct splitStack *popS(){ + if (head == NULL) { + printf("Stack Underflow!!\n"); + getch(); + exit(-1); + } else { + + } +} diff --git a/btree.exe b/btree.exe index 8a9aab8..cfd147d 100644 Binary files a/btree.exe and b/btree.exe differ