diff --git a/assignments/03/lpa.cpp b/assignments/03/lpa.cpp index d330c57..1732c2a 100644 --- a/assignments/03/lpa.cpp +++ b/assignments/03/lpa.cpp @@ -45,6 +45,23 @@ void pair_vector_init(struct pair_vector *); void pair_vector_clear(struct pair_vector *); void pair_vector_push(struct pair_vector *v, int fst, int snd); +// Red black tree implementation adapted from: +// https://www.programiz.com/dsa/red-black-tree +enum nodeColor { RED, BLACK }; +struct rbNode { + int data; + void *otherData; + enum nodeColor color; + struct rbNode *link[2]; +}; + +struct int_map { + rbNode *map_root; +}; +void int_map_init(struct int_map *); +void int_map_insert(struct int_map *, int key, void *value); +void *int_map_get(struct int_map *, int key); + pair compute_node_range(int p, int total_num_nodes, int each_num_nodes, int process); int lookup_assignment(int *base_node_assignment, pair my_node_range, @@ -58,6 +75,12 @@ int main(int argc, char **argv) { MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &p); + struct int_map helloge; + int_map_init(&helloge); + int_map_insert(&helloge, 10, (void *)"hello"); + int_map_insert(&helloge, 1, (void *)"world"); + printf("%s\n", (char *)int_map_get(&helloge, 10)); + MPI_Datatype IntPairType; init_pair_type(&IntPairType); @@ -171,7 +194,6 @@ int main(int argc, char **argv) { // of the graph. #pragma region int node_label_assignment_vec[num_my_nodes]; - // std::map node_label_assignment; pair my_node_range = node_ranges[rank]; // Initial node assignment @@ -449,3 +471,332 @@ int lookup_assignment(int *base_node_assignment, pair my_node_range, // Pull the corresponding value from the map return recvbuf[recv_displs[process_from] + index]; } + +// Red black tree implementation adapted from: +// https://www.programiz.com/dsa/red-black-tree +#pragma region +// Create a red-black tree +struct rbNode *createNode(int data, void *otherData) { + struct rbNode *newnode; + newnode = (struct rbNode *)malloc(sizeof(struct rbNode)); + newnode->data = data; + newnode->otherData = otherData; + newnode->color = RED; + newnode->link[0] = newnode->link[1] = NULL; + return newnode; +} + +// Insert an node +void insertion(struct rbNode *root, int data, void *otherData) { + struct rbNode *stack[98], *ptr, *newnode, *xPtr, *yPtr; + int dir[98], ht = 0, index; + ptr = root; + if (!root) { + root = createNode(data, otherData); + return; + } + + stack[ht] = root; + dir[ht++] = 0; + while (ptr != NULL) { + if (ptr->data == data) { + printf("Duplicates Not Allowed!!\n"); + return; + } + index = (data - ptr->data) > 0 ? 1 : 0; + stack[ht] = ptr; + ptr = ptr->link[index]; + dir[ht++] = index; + } + stack[ht - 1]->link[index] = newnode = createNode(data, otherData); + while ((ht >= 3) && (stack[ht - 1]->color == RED)) { + if (dir[ht - 2] == 0) { + yPtr = stack[ht - 2]->link[1]; + if (yPtr != NULL && yPtr->color == RED) { + stack[ht - 2]->color = RED; + stack[ht - 1]->color = yPtr->color = BLACK; + ht = ht - 2; + } else { + if (dir[ht - 1] == 0) { + yPtr = stack[ht - 1]; + } else { + xPtr = stack[ht - 1]; + yPtr = xPtr->link[1]; + xPtr->link[1] = yPtr->link[0]; + yPtr->link[0] = xPtr; + stack[ht - 2]->link[0] = yPtr; + } + xPtr = stack[ht - 2]; + xPtr->color = RED; + yPtr->color = BLACK; + xPtr->link[0] = yPtr->link[1]; + yPtr->link[1] = xPtr; + if (xPtr == root) { + root = yPtr; + } else { + stack[ht - 3]->link[dir[ht - 3]] = yPtr; + } + break; + } + } else { + yPtr = stack[ht - 2]->link[0]; + if ((yPtr != NULL) && (yPtr->color == RED)) { + stack[ht - 2]->color = RED; + stack[ht - 1]->color = yPtr->color = BLACK; + ht = ht - 2; + } else { + if (dir[ht - 1] == 1) { + yPtr = stack[ht - 1]; + } else { + xPtr = stack[ht - 1]; + yPtr = xPtr->link[0]; + xPtr->link[0] = yPtr->link[1]; + yPtr->link[1] = xPtr; + stack[ht - 2]->link[1] = yPtr; + } + xPtr = stack[ht - 2]; + yPtr->color = BLACK; + xPtr->color = RED; + xPtr->link[1] = yPtr->link[0]; + yPtr->link[0] = xPtr; + if (xPtr == root) { + root = yPtr; + } else { + stack[ht - 3]->link[dir[ht - 3]] = yPtr; + } + break; + } + } + } + root->color = BLACK; +} + +// Delete a node +void deletion(struct rbNode *root, int data) { + struct rbNode *stack[98], *ptr, *xPtr, *yPtr; + struct rbNode *pPtr, *qPtr, *rPtr; + int dir[98], ht = 0, diff, i; + enum nodeColor color; + + if (!root) { + printf("Tree not available\n"); + return; + } + + ptr = root; + while (ptr != NULL) { + if ((data - ptr->data) == 0) + break; + diff = (data - ptr->data) > 0 ? 1 : 0; + stack[ht] = ptr; + dir[ht++] = diff; + ptr = ptr->link[diff]; + } + + if (ptr->link[1] == NULL) { + if ((ptr == root) && (ptr->link[0] == NULL)) { + free(ptr); + root = NULL; + } else if (ptr == root) { + root = ptr->link[0]; + free(ptr); + } else { + stack[ht - 1]->link[dir[ht - 1]] = ptr->link[0]; + } + } else { + xPtr = ptr->link[1]; + if (xPtr->link[0] == NULL) { + xPtr->link[0] = ptr->link[0]; + color = xPtr->color; + xPtr->color = ptr->color; + ptr->color = color; + + if (ptr == root) { + root = xPtr; + } else { + stack[ht - 1]->link[dir[ht - 1]] = xPtr; + } + + dir[ht] = 1; + stack[ht++] = xPtr; + } else { + i = ht++; + while (1) { + dir[ht] = 0; + stack[ht++] = xPtr; + yPtr = xPtr->link[0]; + if (!yPtr->link[0]) + break; + xPtr = yPtr; + } + + dir[i] = 1; + stack[i] = yPtr; + if (i > 0) + stack[i - 1]->link[dir[i - 1]] = yPtr; + + yPtr->link[0] = ptr->link[0]; + + xPtr->link[0] = yPtr->link[1]; + yPtr->link[1] = ptr->link[1]; + + if (ptr == root) { + root = yPtr; + } + + color = yPtr->color; + yPtr->color = ptr->color; + ptr->color = color; + } + } + + if (ht < 1) + return; + + if (ptr->color == BLACK) { + while (1) { + pPtr = stack[ht - 1]->link[dir[ht - 1]]; + if (pPtr && pPtr->color == RED) { + pPtr->color = BLACK; + break; + } + + if (ht < 2) + break; + + if (dir[ht - 2] == 0) { + rPtr = stack[ht - 1]->link[1]; + + if (!rPtr) + break; + + if (rPtr->color == RED) { + stack[ht - 1]->color = RED; + rPtr->color = BLACK; + stack[ht - 1]->link[1] = rPtr->link[0]; + rPtr->link[0] = stack[ht - 1]; + + if (stack[ht - 1] == root) { + root = rPtr; + } else { + stack[ht - 2]->link[dir[ht - 2]] = rPtr; + } + dir[ht] = 0; + stack[ht] = stack[ht - 1]; + stack[ht - 1] = rPtr; + ht++; + + rPtr = stack[ht - 1]->link[1]; + } + + if ((!rPtr->link[0] || rPtr->link[0]->color == BLACK) && + (!rPtr->link[1] || rPtr->link[1]->color == BLACK)) { + rPtr->color = RED; + } else { + if (!rPtr->link[1] || rPtr->link[1]->color == BLACK) { + qPtr = rPtr->link[0]; + rPtr->color = RED; + qPtr->color = BLACK; + rPtr->link[0] = qPtr->link[1]; + qPtr->link[1] = rPtr; + rPtr = stack[ht - 1]->link[1] = qPtr; + } + rPtr->color = stack[ht - 1]->color; + stack[ht - 1]->color = BLACK; + rPtr->link[1]->color = BLACK; + stack[ht - 1]->link[1] = rPtr->link[0]; + rPtr->link[0] = stack[ht - 1]; + if (stack[ht - 1] == root) { + root = rPtr; + } else { + stack[ht - 2]->link[dir[ht - 2]] = rPtr; + } + break; + } + } else { + rPtr = stack[ht - 1]->link[0]; + if (!rPtr) + break; + + if (rPtr->color == RED) { + stack[ht - 1]->color = RED; + rPtr->color = BLACK; + stack[ht - 1]->link[0] = rPtr->link[1]; + rPtr->link[1] = stack[ht - 1]; + + if (stack[ht - 1] == root) { + root = rPtr; + } else { + stack[ht - 2]->link[dir[ht - 2]] = rPtr; + } + dir[ht] = 1; + stack[ht] = stack[ht - 1]; + stack[ht - 1] = rPtr; + ht++; + + rPtr = stack[ht - 1]->link[0]; + } + if ((!rPtr->link[0] || rPtr->link[0]->color == BLACK) && + (!rPtr->link[1] || rPtr->link[1]->color == BLACK)) { + rPtr->color = RED; + } else { + if (!rPtr->link[0] || rPtr->link[0]->color == BLACK) { + qPtr = rPtr->link[1]; + rPtr->color = RED; + qPtr->color = BLACK; + rPtr->link[1] = qPtr->link[0]; + qPtr->link[0] = rPtr; + rPtr = stack[ht - 1]->link[0] = qPtr; + } + rPtr->color = stack[ht - 1]->color; + stack[ht - 1]->color = BLACK; + rPtr->link[0]->color = BLACK; + stack[ht - 1]->link[0] = rPtr->link[1]; + rPtr->link[1] = stack[ht - 1]; + if (stack[ht - 1] == root) { + root = rPtr; + } else { + stack[ht - 2]->link[dir[ht - 2]] = rPtr; + } + break; + } + } + ht--; + } + } +} +#pragma endregion + +void int_map_init(struct int_map *m) { m->map_root = NULL; } + +void int_map_insert(struct int_map *m, int key, void *value) { + // If empty + if (m->map_root == NULL) { + m->map_root = createNode(key, value); + return; + } + + // Else, insert + insertion(m->map_root, key, value); +} + +void *int_map_get(struct int_map *m, int key) { + if (m->map_root == NULL) + return NULL; + + struct rbNode *current = m->map_root; + while (true) { + if (current->link[0] == NULL && current->link[1] == NULL) + return NULL; + + if (key < current->data) { + current = current->link[0]; + } else if (key > current->data) { + current = current->link[1]; + } else { + return current->otherData; + } + } + + return NULL; +} \ No newline at end of file diff --git a/assignments/03/test.gdb b/assignments/03/test.gdb index 171a8f9..963626d 100644 --- a/assignments/03/test.gdb +++ b/assignments/03/test.gdb @@ -1,5 +1,3 @@ set pagination off run dataset/both_1000.txt -bt -frame 3 -print k \ No newline at end of file +bt \ No newline at end of file