I understand that set is implemented as tree structure internally in c++ . So, how does lower_bound gets performed on it? I mean I understand for vector that you pick the middle element using the start and end indexes and perform binary search, but how does it get implemented for tree like structures?
Finding the lower_bound in a set is almost the same as searching for an element in the set. At the end of the search (navigating the tree) you've either found the node where the element is, or you find an element that is greater than the one you're looking for, but there aren't any nodes with a lower value in its subtree (so this is where you'd want to insert the value if you were adding it, as the left child of this node).
Either way you've found the lower bound for the element.
Related
I've built a circular two-way circular list and I want to find its length.
I am allowed to use the function only in the Pointer to list. In the list I have a binary field.
An idea how can I do this?
I have to use the binary field, I can not use the auxiliary pointer and I have to have it in good complexity.
Keep track of the element at which you start your traversal. Start walking along the list and check for each element if it is the one where you started. If it is not, you increment your count by one and continue on to the next element. If it is, you have visited every element and the current value of the count is your desired result.
You can browse your list in a way, counting how many elements you have until you come back to the starting element !
I am given a list of strings and would like to find the middle element.
I want this middle element because I am constructing a binary search tree from this list, using the middle element as the root node.
How would I go about finding the middle element of standard list so I can recursively call the left and right sides to make the tree? I understand everything about the BST besides this part.
You could use size() and then dividing it by 2 and storing in an integer. Later if you want left or right side you just take that number and add a -1 or a +1
I know we can find minimum/maximum in a binary search tree in O(logn) time. But map in c++ gives us the minimum/maximum in constant time. We can find minimum element in a map using the map::begin and maximum using map::rbegin . Both these operation takes constant time. Can anyone suggest a method that makes finding minimum/maximum O(1) ?
C++ map is not implemented by BST. It is implemented by Red Black Tree. If you want to find min/max in BST by O(1),you can store the two pointers to the leftmost node and rightmost node in the tree.
Else, you can use minheap or maxheap to find out min/max in O(1).
I need a data structure in c++ STL for performing insertion, searching and retrieval of kth element in log(n)
(Note: k is a variable and not a constant)
I have a class like
class myClass{
int id;
//other variables
};
and my comparator is just based on this id and no two elements will have the same id.
Is there a way to do this using STL or I've to write log(n) functions manually to maintain the array in sorted order at any point of time?
Afaik, there is no such datastructure. Of course, std::set is close to this, but not quite. It is a red black tree. If each node of this red black tree was annotated with the tree weight (the number of nodes in the subtree rooted at this node), then a retrieve(k) query would be possible. As there is no such weight annotation (as it takes valuable memory and makes insert/delete more complex as weights have to be updated), it is impossible to answer such a query efficently with any search tree.
If you want to build such a datastructure, use a conventional search tree implementation (red-black,AVL,B-Tree,...) and add a weight field to each node that counts the number of entries in its subtree. Then searching for the k-th entry is quite simple:
Sketch:
Check the weight of the child nodes, and find the child c which has the largest weight (accumulated from left) that is not greater than k
Subtract from k all weights of children that are left of c.
Descend down to c and call this procedure recursively.
In case of a binary search tree, the algorithm is quite simple since each node only has two children. For a B-tree (which is likely more efficient), you have to account as many children as the node contains.
Of course, you must update the weight on insert/delete: Go up the tree from the insert/delete position and increment/decrement the weight of each node up to the root. Also, you must exchange the weights of nodes when you do rotations (or splits/merges in the B-tree case).
Another idea would be a skip-list where the skips are annotated with the number of elements they skip. But this implementation is not trivial, since you have to update the skip length of each skip above an element that is inserted or deleted, so adjusting a binary search tree is less hassle IMHO.
Edit: I found a C implementation of a 2-3-4 tree (B-tree), check out the links at the bottom of this page: http://www.chiark.greenend.org.uk/~sgtatham/algorithms/cbtree.html
You can not achieve what you want with simple array or any other of the built-in containers. You can use a more advanced data structure for instance a skip list or a modified red-black tree(the backing datastructure of std::set).
You can get the k-th element of an arbitrary array in linear time and if the array is sorted you can do that in constant time, but still the insert will require shifting all the subsequent elements which is linear in the worst case.
As for std::set you will need additional data to be stored at each node to be able to get the k-th element efficiently and unfortunately you can not modify the node structure.
I have been wanting to write remove() method for my Binary Search Tree (which happens to be an array representation). But before writing it, I must consider all cases. Omitting all cases (since they are easy) except when the node has two children, in all the explanations I have read so far, most of the cases I see remove an element from an already balanced binary search tree. In the few cases where I have seen an element being removed from an unbalanced binary search tree, I find that they balance it through zigs and zags, and then remove the element.
Is there a way that I can possibly remove an element from an unbalanced binary search tree without having to balance it beforehand?
If not, would it be easier to write an AVL tree (in array representation)?
You don't need to balance it, but you do need to recursively go down the tree performing some swaps here and there so you actually end up with a valid BST.
Deletion of a node with 2 children in an (unbalanced) BST: (from Wikipedia)
Call the node to be deleted N. Do not delete N. Instead, choose either its in-order successor node or its in-order predecessor node, R. Copy the value of R to N, then recursively call delete on R until reaching one of the first two cases.
Deleting a node with two children from a binary search tree. First the rightmost node in the left subtree, the inorder predecessor 6, is identified. Its value is copied into the node being deleted. The inorder predecessor can then be easily deleted because it has at most one child. The same method works symmetrically using the inorder successor labelled 9.
Although, why do you want an unbalanced tree? All operations on it take on it take longer (or at least as long), and the additional overhead to balance doesn't change the asymptotic complexity of any operations. And, if you're using the array representation where the node at index i has children at indices 2i and 2i+1, it may end up fairly sparse, i.e. there will be quite a bit of wasted memory.