} //maximum high value in subtree rooted with this node public ITNode(Interval i, int m, ITNode l, ITNode r) { this.i = i; this.max = m; this.left = l; this.right = r; }
//Check if a given interval overlaps in the given interval tree public static bool overlapSearch(ITNode root, Interval i) { //base case, tree is empty if (root == null) { return(false); } //if i overlaps with root if (doOverlap(root.i, i)) { return(true); } //if left child of root is present and max of left child is //greater than or equal to given interval, then i may overlap //with an interval in left subtree if (root.left != null && root.left.max >= i.low) { return(overlapSearch(root.left, i)); } //Else interval can only overlap with right subtree return(overlapSearch(root.right, i)); }
//use interval BST to store previous k intervals public static bool containsNearbyAlmostDuplicate(int[] arr, int k, int l) { if (arr.Length == 0) { return(false); } Interval interval = new Interval(arr [0] - l / 2, arr [0] + l / 2); //put first element into tree ITNode root = new ITNode(interval, interval.high, null, null); for (int i = 1; i < arr.Length; i++) { Interval curr = new Interval(arr [i] - l / 2, arr [i] + l / 2); if (IntervalTree.overlapSearch(root, curr)) //if overlap, return true { return(true); } if (i >= k) //if tree size >= k, remove the earliest element from the tree { Interval toDelete = new Interval(arr [i - k] - l / 2, arr [i - k] + l / 2); IntervalTree.delete(root, toDelete); } IntervalTree.insert(root, curr); //insert current interval to the tree } return(false); }
//Insert a new Interval Search Tree node //this is very similar to BST Insert. The low value of interval //is used to maintain BST property public static ITNode insert(ITNode root, Interval i) { //base case: tree is empty, new node become root if (root == null) { return(newNode(i)); } //get low value of interval of root int l = root.i.low; //if i.low is smaller than root's low value, //then i goes to the left subtree if (i.low < l) { root.left = insert(root.left, i); } //else, i goes to the right subtree else { root.right = insert(root.right, i); } //update the max value of this ancestor if needed if (root.max < i.high) { root.max = i.high; } return(root); }
//delete the node containing the given interval from tree public static ITNode delete(ITNode root, Interval i) { //base case if (root == null) { return(root); } //get low value of root int l = root.i.low; //if i.low is smaller than root's low value, //then it lies in the left subtree if (i.low < l) { root.left = delete(root.left, i); } //if i.low is greater than root's low value, //then it lies in the right subtree else if (i.low > l) { root.right = delete(root.right, i); } //if i.low is equal to root's low value //then root is the node to be deleted else { //if root has only one child or no child if (root.left == null) { ITNode temp = root.right; return(temp); } else if (root.right == null) { ITNode temp = root.left; return(temp); } //if root with two childre: get the inorder successor //which is the smallest in the right subtree else { //Node with two children: get the inorder successor ITNode temp = minValueNode(root.right); //copy inorder successor's content to this node root.i = temp.i; root.max = temp.max; //delete the inorder successor root.right = delete(root.right, temp.i); } } return(root); }
//Given a non-empty BST, return the node with minimum key //value found in that tree. Note the entire tree does not //need to be searched private static ITNode minValueNode(ITNode node) { ITNode current = node; //loop down to find the leftmost child while (current.left != null) { current = current.left; } return(current); }
//create a new interval tree node private static ITNode newNode(Interval i) { ITNode temp = new ITNode(i, i.high, null, null); return(temp); }
public int max { get; set;} //maximum high value in subtree rooted with this node public ITNode(Interval i, int m, ITNode l, ITNode r){ this.i = i; this.max = m; this.left = l; this.right = r; }
//create a new interval tree node private static ITNode newNode(Interval i){ ITNode temp = new ITNode (i, i.high, null, null); return temp; }
//use interval BST to store previous k intervals public static bool containsNearbyAlmostDuplicate(int[] arr, int k, int l){ if (arr.Length == 0) return false; Interval interval = new Interval (arr [0] - l / 2, arr [0] + l / 2); //put first element into tree ITNode root = new ITNode (interval, interval.high, null, null); for(int i=1;i<arr.Length;i++){ Interval curr = new Interval (arr [i] - l / 2, arr [i] + l / 2); if (IntervalTree.overlapSearch (root, curr)) //if overlap, return true return true; if (i >=k) { //if tree size >= k, remove the earliest element from the tree Interval toDelete = new Interval (arr [i - k] - l / 2, arr [i - k] + l / 2); IntervalTree.delete (root, toDelete); } IntervalTree.insert (root, curr); //insert current interval to the tree } return false; }
//Check if a given interval overlaps in the given interval tree public static bool overlapSearch(ITNode root, Interval i){ //base case, tree is empty if(root == null) return false; //if i overlaps with root if(doOverlap(root.i,i)) return true; //if left child of root is present and max of left child is //greater than or equal to given interval, then i may overlap //with an interval in left subtree if (root.left != null && root.left.max >= i.low) return overlapSearch (root.left, i); //Else interval can only overlap with right subtree return overlapSearch (root.right, i); }
//delete the node containing the given interval from tree public static ITNode delete(ITNode root, Interval i){ //base case if (root == null) return root; //get low value of root int l = root.i.low; //if i.low is smaller than root's low value, //then it lies in the left subtree if (i.low < l) root.left = delete (root.left, i); //if i.low is greater than root's low value, //then it lies in the right subtree else if (i.low > l) root.right = delete (root.right, i); //if i.low is equal to root's low value //then root is the node to be deleted else { //if root has only one child or no child if (root.left == null) { ITNode temp = root.right; return temp; } else if (root.right == null) { ITNode temp = root.left; return temp; } //if root with two childre: get the inorder successor //which is the smallest in the right subtree else { //Node with two children: get the inorder successor ITNode temp = minValueNode (root.right); //copy inorder successor's content to this node root.i = temp.i; root.max = temp.max; //delete the inorder successor root.right = delete (root.right, temp.i); } } return root; }
//Given a non-empty BST, return the node with minimum key //value found in that tree. Note the entire tree does not //need to be searched private static ITNode minValueNode(ITNode node){ ITNode current = node; //loop down to find the leftmost child while (current.left != null) current = current.left; return current; }
//Insert a new Interval Search Tree node //this is very similar to BST Insert. The low value of interval //is used to maintain BST property public static ITNode insert(ITNode root, Interval i){ //base case: tree is empty, new node become root if (root == null) return newNode (i); //get low value of interval of root int l = root.i.low; //if i.low is smaller than root's low value, //then i goes to the left subtree if (i.low < l) root.left = insert (root.left, i); //else, i goes to the right subtree else root.right = insert (root.right, i); //update the max value of this ancestor if needed if (root.max < i.high) root.max = i.high; return root; }