+ } \r
+\r
+\r
+// TaggedFollowingSibling(x,tag): returns the first node tagged tag with larger preorder than x and not in\r
+// the subtree of x. Returns NULLT if there is none.\r
+treeNode XMLTree::TaggedFollowingSibling(treeNode x, TagType tag) \r
+ {\r
+ if (!finished) {\r
+ fprintf(stderr, "Error: data structure has not been constructed properly\n");\r
+ exit(1);\r
+ }\r
+\r
+ int r, s;\r
+ treeNode ns = next_sibling(Par,x);\r
+\r
+ if (x == NULLT || x == Root() || ns == -1)\r
+ return NULLT;\r
+\r
+ r = (int) Tags->rank(tag, node2tagpos(ns)-1);\r
+ s = (int) Tags->select(tag, r+1); // select returns -1 in case that there is no r+1-th tag.\r
+ if (s==-1) return NULLT;\r
+ else return tagpos2node(s);\r
+ }\r
+\r
+\r
+// TaggedAncestor(x, tag): returns the closest ancestor of x tagged tag. Return\r
+// NULLT is there is none.\r
+treeNode XMLTree::TaggedAncestor(treeNode x, TagType tag)\r
+ {\r
+ if (!finished) {\r
+ fprintf(stderr, "Error: data structure has not been constructed properly\n");\r
+ exit(1);\r
+ }\r
+ \r
+ if (x == NULLT || x == Root())\r
+ return NULLT;\r
+ \r
+ treeNode s = parent(Par, x), r = Root();\r
+ while (s != r) {\r
+ if (get_field(tags_fix,tags_blen,node2tagpos(s)) /*Tags->access(node2tagpos(s))*/ == tag) return s;\r
+ s = parent(Par, s);\r
+ }\r
+ return NULLT;\r