// Read a tree from a stream // Example: // // 10 black // // / \ // // 5 red 15 black // // / \ / \ // // null 7 black null null // // / \ // // null null // // is represented as // // 10 black // 5 red // null // 7 black // null // null // 15 black // null // null // This is a recursive function // static bool readIntegerTree(RBTree& tree, FILE* f) { tree.clear(); char line[256]; if (fgets(line, 254, f) == NULL) return false; line[254] = 0; int len = strlen(line); // Remove "\r\n" at the end of line if (len > 0 && line[len-1] == '\n') --len; if (len > 0 && line[len-1] == '\r') --len; int i = 0; while (i < len && isspace(line[i])) ++i; if (i < len && (isdigit(line[i]) || line[i] == '-')) { int n = atoi(line + i); bool red = false; while (i < len && (isdigit(line[i]) || line[i] == '-')) ++i; if (i >= len || !isspace(line[i])) return false; while (i < len && isspace(line[i])) ++i; if (i < len && line[i] == 'r') red = true; RBTree leftSubtree; if (!readIntegerTree(leftSubtree, f)) return false; RBTree rightSubtree; if (!readIntegerTree(rightSubtree, f)) return false; RBTreeNode* rootNode = new RBTreeNode(); rootNode->red = red; rootNode->value = new Integer(n); tree.header.left = rootNode; rootNode->parent = &(tree.header); tree.numNodes = 1; if (leftSubtree.size() > 0) { rootNode->left = leftSubtree.root(); leftSubtree.root()->parent = rootNode; tree.numNodes += leftSubtree.size(); leftSubtree.header.left = 0; leftSubtree.numNodes = 0; } if (rightSubtree.size() > 0) { rootNode->right = rightSubtree.root(); rightSubtree.root()->parent = rootNode; tree.numNodes += rightSubtree.size(); rightSubtree.header.left = 0; rightSubtree.numNodes = 0; } } return true; }
///== ///////////////////////////////////////////// int main() { printf("Test of Red-Black Tree class\n"); printHelp(); FILE* f = NULL; // Define a random tree with 20 nodes time_t t = time(0); // Current time in seconds since 1 Jan 1970 srand(t); RBTree tree; char line[256]; while (true) { printf("Command>"); if (fgets(line, 254, stdin) == NULL) break; // Parse a command line[254] = 0; int len = strlen(line); // Remove "\r\n" at the end of line if (len > 0 && line[len-1] == '\n') { line[len-1] = 0; --len; } if (len > 0 && line[len-1] == '\r') { line[len-1] = 0; --len; } int i = 0; // Skip a space in beginning of line while (i < len && isspace(line[i])) ++i; int commandBeg = i; while (i < len && isalpha(line[i])) ++i; int commandEnd = i; int commandLen = commandEnd - commandBeg; if (strncmp("gentree", line+commandBeg, commandLen) == 0 || strncmp("gt", line+commandBeg, commandLen) == 0) { while (i < len && isspace(line[i])) ++i; // Skip a space if (i >= len || !isdigit(line[i])) { printf("Incorrect command.\n"); printHelp(); continue; } int n = atoi(line + i); // Generate a random tree tree.clear(); int j = 0; if (n > 100) n = 100; // Maximum 100 nodes while (j < n) { Integer num(rand() % 100 + 1); RBTreeNode* node; if (!tree.find(&num, tree.root(), &node)) { Integer* v = new Integer(num); tree.insert(node, v); ++j; } } // Print a tree to stdout writeIntegerTree(tree.root(), stdout); } else if (strncmp("readtree", line+commandBeg, commandLen) == 0) { while (i < len && isspace(line[i])) ++i; // Skip a space if ((f = fopen(line+i, "r")) == NULL) { perror("Could not open a file for reading"); continue; } // Read a tree from a file if (readIntegerTree(tree, f)) writeIntegerTree(tree.root(), stdout); else printf("Incorrect format.\n"); fclose(f); f = NULL; } else if (strncmp("writetree", line+commandBeg, commandLen) == 0) { while (i < len && isspace(line[i])) ++i; // Skip a space if (i >= len) { printf("Incorrect command.\n"); printHelp(); continue; } if ((f = fopen(line+i, "w")) == NULL) { perror("Could not open a file for writing"); continue; } writeIntegerTree(tree.root(), f); fclose(f); f = NULL; } ///////////////////// ================================================ else if (strncmp("md", line+commandBeg, commandLen) == 0) { RBTreeNode*node = tree.root(); printf("Max depth = %d.\n", GetDepth(node)); printf("Black depth = %d.\n", GetBlackDepth(node)); } ///////////////////// ================================================ else if (strncmp("quit", line+commandBeg, commandLen) == 0) break; // end if } // end while return 0; }