int findAncestor(tNode* root, int key1, int key2) { int lc = 0; int rc = 0; if(root->lchild != NULL) { lc = findAncestor(root->lchild , key1, key2); } if(root->rchild != NULL) { rc = findAncestor(root->rchild , key1, key2); } int ret = lc + rc; int cc = *(int*)root->item; if( cc == key1 || cc == key2) { ret += 1; } if( ret == 2) { printf("The ancestor is %d\n",*(int*)root->item); } return ret; }
static inline Path checkEntry(const Entry *entries, const Path &path, const Path &home) { for (int i=0; entries[i].name; ++i) { Path p = findAncestor(path, entries[i].name, entries[i].flags); if ((p.isEmpty() || p == home) && (entries[i].flags & Wildcard)) { const int len = strlen(entries[i].name); if (entries[i].name[len - 1] == '*') { const String name(entries[i].name, len - 1); p = findAncestor(path, name.constData(), entries[i].flags & ~Wildcard); } } if (!p.isEmpty() && p != home) { return p; } } return Path(); }
void findAncestor(TreeNode *root, unordered_map<TreeNode *, TreeNode *> &map) { if (!root) { return; } else { if (root->right) { map[root->right] = root; findAncestor(root->right, map); } if (root->left) { map[root->left] = root; findAncestor(root->left, map); } } }
int main() { srand(time(NULL)); int num = 20; int* arr = createArr(num, INT); print_arr(arr, num); tNode* root = createBSTRoot(arr, num); print_tree(root,print); printf("\n"); int i; for(i = 0 ; i < num ; i++) { int key1 = rand()%20 + 1; int key2 = rand()%20 + 1; printf("(%d,%d)\n", key1, key2); int tmp = findAncestor(root, key1, key2); } return 0; }
Path findProjectRoot(const Path &path) { assert(path.isAbsolute()); const Path config = findAncestor(path, ".rtags-config", Shallow); if (config.isDir()) { const List<String> conf = Path(config + ".rtags-config").readAll().split('\n'); for (List<String>::const_iterator it = conf.begin(); it != conf.end(); ++it) { const char *ch = it->constData(); while (*ch && isspace(*ch)) ++ch; if (*ch && !strncmp("project: ", ch, 9)) { ch += 9; while (*ch && isspace(*ch)) ++ch; const Path p = ch; if (p.isDir()) { return p.ensureTrailingSlash(); } else { error("Invalid project root %s", p.constData()); } } } } static const Path home = Path::home(); const Entry before[] = { { "GTAGS", 0 }, { "CMakeLists.txt", 0 }, { "configure", 0 }, { ".git", 0 }, { ".svn", 0 }, { "*.pro", Wildcard }, { "scons.1", 0 }, { "*.scons", Wildcard }, { "SConstruct", 0 }, { "autogen.*", Wildcard }, { "GNUMakefile*", Wildcard }, { "INSTALL*", Wildcard }, { "README*", Wildcard }, { 0, 0 } }; { const Path ret = checkEntry(before, path, home); if (!ret.isEmpty()) return ret; } { const Path configStatus = findAncestor(path, "config.status", 0); if (!configStatus.isEmpty()) { FILE *f = fopen((configStatus + "config.status").constData(), "r"); Path ret; if (f) { char line[1024]; enum { MaxLines = 10 }; for (int i=0; i<MaxLines; ++i) { int r = Rct::readLine(f, line, sizeof(line)); if (r == -1) break; char *configure = strstr(line, "/configure "); if (configure) { char *end = configure + 10; while (--configure >= line) { Path conf(configure, end - configure); if (!conf.isAbsolute()) conf.resolve(); if (conf.isFile()) { ret = conf.parentDir(); if (ret == home) ret.clear(); break; } } } if (!ret.isEmpty()) break; } fclose(f); if (!ret.isEmpty()) return ret; } } } { const Path cmakeCache = findAncestor(path, "CMakeCache.txt", 0); if (!cmakeCache.isEmpty()) { FILE *f = fopen((cmakeCache + "Makefile").constData(), "r"); if (f) { Path ret; char line[1024]; enum { MaxLines = 256 }; for (int i=0; i<MaxLines; ++i) { int r = Rct::readLine(f, line, sizeof(line)); if (r == -1) { break; } if (!strncmp(line, "CMAKE_SOURCE_DIR", 16)) { char *dir = line + 16; while (*dir && (*dir == ' ' || *dir == '=')) ++dir; if (dir != home) { ret = dir; ret += '/'; if (!Path(ret + "CMakeLists.txt").isFile()) ret.clear(); } break; } } fclose(f); if (!ret.isEmpty()) return ret; } } } const Entry after[] = { { "Makefile*", Wildcard }, { 0, 0 } }; { const Path ret = checkEntry(after, path, home); if (!ret.isEmpty()) return ret; } return Path(); }
int Layout::lookupName(Name name) { Layout* layout = findAncestor(name); return layout ? layout->slotIndex() : NotFound; }
Path findProjectRoot(const Path &path, ProjectRootMode mode) { if (!path.isAbsolute()) error() << "GOT BAD PATH" << path; assert(path.isAbsolute()); const Map<String, String> config = rtagsConfig(path); { const Path project = config.value("project"); if (!project.isEmpty() && project.isDir()) return project.ensureTrailingSlash(); } static const Path home = Path::home(); if (mode == SourceRoot) { const Entry before[] = { { "GTAGS", 0 }, { "CMakeLists.txt", 0 }, { "configure", 0 }, { ".git", 0 }, { ".svn", 0 }, { "*.pro", Wildcard }, { "scons.1", 0 }, { "*.scons", Wildcard }, { "SConstruct", 0 }, { "autogen.*", Wildcard }, { "GNUMakefile*", Wildcard }, { "INSTALL*", Wildcard }, { "README*", Wildcard }, { "compile_commands.json", 0 }, { 0, 0 } }; { const Path ret = checkEntries(before, path, home); if (!ret.isEmpty()) return ret; } } { const Path configStatus = findAncestor(path, "config.status", 0); if (!configStatus.isEmpty()) { if (mode == BuildRoot) return configStatus; FILE *f = fopen((configStatus + "config.status").constData(), "r"); Path ret; if (f) { char line[1024]; enum { MaxLines = 10 }; for (int i=0; i<MaxLines; ++i) { int r = Rct::readLine(f, line, sizeof(line)); if (r == -1) break; char *configure = strstr(line, "/configure "); if (configure) { char *end = configure + 10; while (--configure >= line) { Path conf(configure, end - configure); if (!conf.isAbsolute()) conf.resolve(); if (conf.isFile()) { ret = conf.parentDir(); if (ret == home) ret.clear(); break; } } } if (!ret.isEmpty()) break; } fclose(f); if (!ret.isEmpty()) return ret; } } } { const Path cmakeCache = findAncestor(path, "CMakeCache.txt", 0); if (!cmakeCache.isEmpty()) { if (mode == BuildRoot) return cmakeCache; FILE *f = fopen((cmakeCache + "Makefile").constData(), "r"); bool makefile = true; if (!f) { f = fopen((cmakeCache + "build.ninja").constData(), "r"); makefile = false; } if (f) { Path ret; char line[1024]; enum { MaxLines = 256 }; for (int i=0; i<MaxLines; ++i) { int r = Rct::readLine(f, line, sizeof(line)); if (r == -1) { break; } if (makefile) { if (!strncmp(line, "CMAKE_SOURCE_DIR", 16)) { char *dir = line + 16; while (*dir && (*dir == ' ' || *dir == '=')) ++dir; if (dir != home) { ret = dir; ret += '/'; if (!Path(ret + "CMakeLists.txt").isFile()) ret.clear(); } break; } } else if (!strncmp(line, "# Write statements declared in CMakeLists.txt:", 46)) { r = Rct::readLine(f, line, sizeof(line)); ++i; if (r != -1) { ret = line + 2; if (ret.exists()) { ret = ret.parentDir(); } else { ret.clear(); break; } } } } fclose(f); if (!ret.isEmpty()) return ret; } } } const Entry after[] = { { "build.ninja", 0 }, { "Makefile*", Wildcard }, { 0, 0 } }; { const Path ret = checkEntries(after, path, home); if (!ret.isEmpty()) return ret; } if (mode == BuildRoot) return findProjectRoot(path, SourceRoot); return Path(); }