简体   繁体   中英

How to build a data-structure to support some range queries

An interval is defined by start and end.

Given a set of possibly overlapping intervals in a range[say, 0-999], build a data structure to support following range queries in optimal time complexity

.

Overlap(start, end) = set of all intervals that overlap with [start, end]

Within(start, end) = set of all intervals that lie within [start, end]

Where,

Intervals I1[start1, end1], I2[start2, end2] are said to overlap with  each other iff start1<end2 && start2<end1
Interval I1[start1, end1] is said to be within interval I2[start2,end2] iff start1>start2 && end1<end2

The data-structure this question addresses is called Interval tree :

An ordered tree data structure to hold intervals, it allows one to efficiently find all intervals that overlap with any given interval or point.

Two effective approaches:

The proposed algorithm in the link for searching for all overlapping intervals is expected to be faster than a traditional interval tree (augmented tree) for search operations, adding elements is a little slower.

Various approaches to implementing an interval tree:

When implementing a solution you should know the performance of java collections processing

Wrote some Scala code to implement this using interval trees!

class IntervalSearchTree {
     var root=new IntervalNode(null,null,null,null,null);

  class IntervalNode(var left:IntervalNode,var start:Integer,var end:Integer,var maxEnd:Integer,var right:IntervalNode);

    def add(start:Integer,end:Integer ):Unit={
      var node:IntervalNode=root
      while(node!=null){
        if(end>node.maxEnd)
          node.maxEnd=end
        if (start < node.start) {
                if (node.left == null) {
                    node.left = new IntervalNode(null, start, end, end, null);
                    return;
                }
                node = node.left;
            } else {
                if (node.right == null) {
                    node.right = new IntervalNode(null, start, end, end, null);
                    return;
                }
                node = node.right;
            }
      }
      root =  new IntervalNode(null, start, end, end, null);
    }

    def overlap(start:Integer,end:Integer):Unit={

      var intervalNode:IntervalNode=root;
      while (intervalNode != null) {
         if (intersection(start, end, intervalNode)){
           println(intervalNode.start+"-"+intervalNode.end)
         }
         if (leftSubTree(start, end, intervalNode.left)) {
                intervalNode = intervalNode.left;


            } else {

                intervalNode = intervalNode.right;

            }


      }

    }

    def within(start:Integer,end:Integer):Unit={
        var intervalNode:IntervalNode = root;
        while (intervalNode != null) {
           if (subset(start, end, intervalNode)){
           println(intervalNode.start+"-"+intervalNode.end)
         }
         if (leftSubTree(start, end, intervalNode.left)) {
                intervalNode = intervalNode.left;


            } else {

                intervalNode = intervalNode.right;

            }
        }

    }


    def subset(start:Integer,end:Integer,intervalNode:IntervalNode):Boolean={
      return start<intervalNode.start  && end >intervalNode.end ;
    }

    def intersection(start:Integer,end:Integer,intervalNode:IntervalNode):Boolean={
      return start < intervalNode.end && end > intervalNode.start;
    }

    def leftSubTree(start:Integer,end:Integer,intervalLeftSubtree:IntervalNode):Boolean={
      return intervalLeftSubtree != null && intervalLeftSubtree.maxEnd > start;
    }


    def main(args: Array[String]): Unit = {
      var intervalSearchTree=new IntervalSearchTree()
        intervalSearchTree.add(17, 19);
        intervalSearchTree.add(5, 8);
        intervalSearchTree.add(21, 24);
        intervalSearchTree.add(22, 24);
        intervalSearchTree.add(20, 26);
        intervalSearchTree.add(20, 24);
        intervalSearchTree.add(4, 8);
        intervalSearchTree.add(5, 9);
        intervalSearchTree.add(15, 18);
        intervalSearchTree.add(7, 10);
        intervalSearchTree.add(16, 22);

        //Input for testing overlaps 
        println("Overlaps");
        intervalSearchTree.overlap(23, 25);
        //Input for testing overlaps
        println("Within");
        intervalSearchTree.within(4, 25);
    }




}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM