def insert(self, key, data):
     res = self.search(key)
     if res != None:
         self.tree[res].data = data
         return None
     walk = self.root_idx
     if self.tree[walk].key == None:
         self.tree[walk].key = key
         self.tree[walk].data = data
         return None
     new_node, prev_node, flag = Node(key, data), 0, True
     while flag:
         if not self.comparator(key, self.tree[walk].key):
             if self.tree[walk].right == None:
                 new_node.parent = prev_node
                 self.tree.append(new_node)
                 self.tree[walk].right = self.size
                 self.size += 1
                 flag = False
             prev_node = walk = self.tree[walk].right
         else:
             if self.tree[walk].left == None:
                 new_node.parent = prev_node
                 self.tree.append(new_node)
                 self.tree[walk].left = self.size
                 self.size += 1
                 flag = False
             prev_node = walk = self.tree[walk].left
     self._update_size(walk)
Exemple #2
0
    def insert(self, key, data):
        walk = self.root_idx
        if self.tree[walk].key == None:
            self.tree[walk].key = key
            self.tree[walk].data = data
            return None
        new_node, prev_node, flag = Node(key, data), 0, True
        while flag:
            if self.tree[walk].key == key:
                self.tree[walk].data = data
                flag = False
            else:
                if not self.comparator(key, self.tree[walk].key):
                    if self.tree[walk].right == None:
                        new_node.parent = prev_node
                        self.tree.append(new_node)
                        self.tree[walk].right = self.size
                        self.size += 1
                        flag = False
                    prev_node = walk = self.tree[walk].right
                else:
                    if self.tree[walk].left == None:
                        new_node.parent = prev_node
                        self.tree.append(new_node)
                        self.tree[walk].left = self.size
                        self.size += 1
                        flag = False
                    prev_node = walk = self.tree[walk].left

        self._balance_insertion(self.size - 1, self.tree[self.size - 1].parent)
Exemple #3
0
 def __new__(cls, key=None, root_data=None, comp=None):
     obj = object.__new__(cls)
     if key == None and root_data != None:
         raise ValueError('Key required.')
     key = None if root_data == None else key
     root = Node(key, root_data)
     root.is_root = True
     obj.root_idx = 0
     obj.tree, obj.size = [root], 1
     obj.comparator = lambda key1, key2: key1 < key2 \
                     if comp == None else comp
     return obj
Exemple #4
0
 def insert(self, key, data):
     walk = self.root_idx
     if self.tree[walk].key == None:
         self.tree[walk].key = key
         self.tree[walk].data = data
         return None
     new_node = Node(key, data)
     while True:
         if self.tree[walk].key == key:
             self.tree[walk].data = data
             return None
         if not self.comparator(key, self.tree[walk].key):
             if self.tree[walk].right == None:
                 self.tree.append(new_node)
                 self.tree[walk].right = self.size
                 self.size += 1
                 return None
             walk = self.tree[walk].right
         else:
             if self.tree[walk].left == None:
                 self.tree.append(new_node)
                 self.tree[walk].left = self.size
                 self.size += 1
                 return None
             walk = self.tree[walk].left
 def __new__(cls,
             key=None,
             root_data=None,
             comp=None,
             is_order_statistic=False):
     obj = object.__new__(cls)
     if key == None and root_data != None:
         raise ValueError('Key required.')
     key = None if root_data == None else key
     root = Node(key, root_data)
     root.is_root = True
     obj.root_idx = 0
     obj.tree, obj.size = ArrayForTrees(Node, [root]), 1
     obj.comparator = lambda key1, key2: key1 < key2 \
                     if comp == None else comp
     obj.is_order_statistic = is_order_statistic
     return obj
    def build(self):
        """
        Builds the segment tree from the segments,
        using iterative algorithm based on stacks.
        """
        if self.cache:
            return None
        endpoints = []
        for segment in self.segments:
            endpoints.extend(segment)
        endpoints.sort()

        elem_int = Queue()
        elem_int.append(Node([False, endpoints[0] - 1, endpoints[0], False], None))
        i = 0
        while i < len(endpoints) - 1:
            elem_int.append(Node([True, endpoints[i], endpoints[i], True], None))
            elem_int.append(Node([False, endpoints[i], endpoints[i+1], False], None))
            i += 1
        elem_int.append(Node([True, endpoints[i], endpoints[i], True], None))
        elem_int.append(Node([False, endpoints[i], endpoints[i] + 1, False], None))

        self.tree = []
        while len(elem_int) > 1:
            m = len(elem_int)
            while m >= 2:
                I1 = elem_int.popleft()
                I2 = elem_int.popleft()
                I = self._union(I1, I2)
                I.left = len(self.tree)
                I.right = len(self.tree) + 1
                self.tree.append(I1), self.tree.append(I2)
                elem_int.append(I)
                m -= 2
            if m & 1 == 1:
                Il = elem_int.popleft()
                elem_int.append(Il)

        Ir = elem_int.popleft()
        Ir.left, Ir.right = -3, -2
        self.tree.append(Ir)
        self.root_idx = -1

        for segment in self.segments:
            I = Node([True, segment[0], segment[1], True], None)
            calls = [self.root_idx]
            while calls:
                idx = calls.pop()
                if self._contains(I, self.tree[idx]):
                    if self.tree[idx].data == None:
                        self.tree[idx].data = []
                    self.tree[idx].data.append(I)
                    continue
                calls = self._iterate(calls, I, idx)
        self.cache = True
    def insert(self, key, data):
        """
        Inserts data by the passed key using iterative
        algorithm.

        Parameters
        ==========

        key
            The key for comparison.
        data
            The data to be inserted.

        Returns
        =======

        None
        """
        walk = self.root_idx
        if self.tree[walk].key == None:
            self.tree[walk].key = key
            self.tree[walk].data = data
            return None
        new_node = Node(key, data)
        while True:
            if self.tree[walk].key == key:
                self.tree[walk].data = data
                return None
            if not self.comparator(key, self.tree[walk].key):
                if self.tree[walk].right == None:
                    self.tree.append(new_node)
                    self.tree[walk].right = self.size
                    self.size += 1
                    return None
                walk = self.tree[walk].right
            else:
                if self.tree[walk].left == None:
                    self.tree.append(new_node)
                    self.tree[walk].left = self.size
                    self.size += 1
                    return None
                walk = self.tree[walk].left
    def query(self, qx, init_node=None):
        """
        Queries the segment tree.

        Parameters
        ==========

        qx: int/float
            The query point
        init_node: int
            The index of the node from which the query process
            is to be started.

        Returns
        =======

        intervals: set
            The set of the intervals which contain the query
            point.

        References
        ==========

        .. [1] https://en.wikipedia.org/wiki/Segment_tree
        """
        if not self.cache:
            self.build()
        if init_node == None:
            init_node = self.root_idx
        qn = Node([True, qx, qx, True], None)
        intervals = []
        calls = [init_node]
        while calls:
            idx = calls.pop()
            if _check_type(self.tree[idx].data, list):
                intervals.extend(self.tree[idx].data)
            calls = self._iterate(calls, qn, idx)
        return set(intervals)
 def _union(self, i1, i2):
     """
     Helper function for taking union of two
     intervals.
     """
     return Node([i1.key[0], i1.key[1], i2.key[2], i2.key[3]], None)