In B-trees which element gets promoted when the node splits - b-tree

Let's say there is a B-tree of order 8. This means it can have 8 pointers and 7 elements. Say the letters A through G are stored in this B-tree. So this B-tree is just a single node containing 7 elements.
Then you try to insert J into the tree. There's no room, so you have to split the node and create a new root node. Which element gets promoted up into the root node?

When you want to insert a new element in a full node (with 2*t - 1 keys)
you split it by choosing the median key of the node (the key that is the middle)
you generate the two new children with t-1 keys each (splitting it according to the previous key)
the median value remains in the father node
then you proceed by normal insertion algorithm, looking where you should place the new element.

Related

in 2,3,4 tree do you insert a 3rd element only in a leaf node?

Suppose I am entering 3 elements into a top-down 2,3,4 tree. Would
all the three elements go into root?
For subsequent inserts would a 3rd element be inserted into a node
only if its a leaf node (or into a node when a key kicked up when
you encounter a 3 key node)
Yes, all the three elements would end up in root. Why? A node of 2-3-4 tree is broken only when it is full. When inserting three elements, the only node of the tree won't be full until the insertion of the third element.
For subsequent inserts, not just third, even the second and first elements would be inserted in the leaf node only. It's been nicely outlined in the insertion pseudocode of 2-3-4 trees on Wikipedia.

Number of nodes in a B-Tree

How many nodes does a resulting B-Tree(min degree 2) have if I insert numbers from 1 to n in order?
I tried inserting nodes from 1 to 20 there was a series for the number of nodes coming but i could not generalize it.
Can anyone please help me derive the formula for this.
It will depend on the order of the B-Tree. The order of a BTree is the maximum number of children nodes a non-leaf node may hold (which is one more than the minimum number of keys such a node could hold).
According to Knuth's definition, a B-tree of order m is a tree which satisfies the following properties:
Every node has at most m children.
Every non-leaf node (except root) has at least ⌈m⁄2⌉ children.
The root has at least two children if it is not a leaf node.
A non-leaf node with k children contains k−1 keys.
All leaves appear in the same level, and internal vertices carry no information.
So in your case when you are inserting 20 keys if the order is m then based on the conditions mentioned above you can derive a set of inequalities that describes the possible value of m. But there is no equality formula that says the number of internal nodes in a B-Tree.

Inserting and deleting edges in a Tree Dynamically

Problem : Given a rooted Tree T containing N nodes. Each node is numbered form 1 to N, node 1 being the root node. Also, each node contains some value. We have to do three kind of queries in the given tree.
Query 1::
Given a node nd, you have to find the sum of the values of all the nodes of the subtree rooted at nd and print the answer.
Query 2::
Given a node nd, you have to delete the subtree rooted at nd, completely (including node nd).
Query 3::
Given a node nd and some integer v, you have to add a child to node nd having value equal to v.
Constraints : N will be of the order of 100000. And total number of queries wil also be of the order 100000. So, I can't to DFS traversal every time.
My Idea: My solution is offline . I will first find all the nodes that are added to the tree at-least once and make the corresponding tree. Then I will do pre-order traversal to the tree and convert it into an array where a subtree will always appear continuously. Then I can use segment tree data structure to solve the problem. My algorithm will be thus O(QlogN), where Q is the total number of queries. However, I am looking for a "online" solution which is efficient. I mean, I have perform each query as soon as it is asked. I can not store all the queries first then perform them one by one.
Any help is appreciated a lot!
Thanks.
Assuming tree is balanced, with two extra parameters in every node you can solve it in o(qlogn).
With every node maintain a sum whose value will be equal to the sum of values of nodes in the subtree rooted at that and maintain parent as well.
With the above two requirements, query one just reduces to returning sum plus the value at that node(o(1)). query two reduces to just subtracting sum plus the value of node from every parent of that node till you reach the root(o(logn)). query three just reduces to adding v to every parent of that node till you reach the root(o(logn)).

priority queue with range query

Suppose each object has this form: (key, priority) i.e., (0, 3), (5, 7).
Say you are given two numbers, x and y.
What data structure would you use to return the highest-priority object whose key is between x and y?
I think priority queue can be a good solution, but I have no idea how to modify it to return the highest-priority object in the given range.
Starting with a binary search tree, add two fields to each node: the priority, and (a pointer to) the highest-priority node in the subtree (see CLRS Chapter 14 for more on how to carry out this augmentation).
Now, to do a range query, start the search normally until the current node's key lies in the range. Examine that node and, using symmetric variants of the following procedure to identify O(log n) candidates that include the highest-priority node in range, the left and right subtrees of the current node. The following procedure is for the left subtree.
If the root is in range, consider it for highest priority, along with the highest-priority node in its right subtree (cached in the node). Continue with the left subtree. If the root is not in range, continue with the right subtree.
This problem is known as RMQ (Range Minimum/Maximum Query).
The best data structure to use in your case is Segment Tree.
It is a hard structure to get right the first time, but keep trying: this solves exactly your problem.

How to find all elements in an ordered dictionary implemented as a binary tree that have the key k

Given a binary tree I need to implement a method findAllElements(k) to find all the elements in the tree with a key equal to k.
The idea I had is the first time you come across an element with key k. All the elements with the same key should be either in the left child's right subtree or the right child's left subtree. But I was told this may not be the case?
I just need to find a way to implement an algorithm. So pseudo code is needed.
I probably should have added this sorry. But the implementation is that the left subtree contains keys less than or equal to the key at the root and the right subtree contains keys greater than or equal to the key at the root.
It depends on your tree implementation, by binary tree I assume you mean binary search tree, and you use operator< to compare the key. That is, The left subtree of a node contains only nodes with keys less(<) than the node's key, and the right subtree of a node contains only nodes with keys not less(!<) than the node's key.
e.g.
7
/ \
4 7
/ \
6 8
If there is multi equal keys in the tree, do this
k < current_node_key, search left subtree
k > current_node_key, search right subtree
k == current_node_key, record current node , then search right tree
Look at the current node. If its key is higher than k, search the left subtree. If it is lower, search the right subtree. If it is equal, search both left and right subtrees (and also include the current node in the results).
Do that recursively starting from the root node.
Thought I'd come back and explain what the result should have been after conversing with me teacher. So if you perform a method findElement(k) that will find an element with the key equal to k, the element it find should be the element highest in the tree with key k (let's denote this element V).
Then from this element V, other elements the contain a key=k will either be in the left child subtree (particularly all the way to the right) or the right child subtree (particularly all the way to the left). So for the left child keep going to the next nodes right child until an element with key=k is found...now... every element in the subtree with this node as its root must have a key=k (this is the part i didn't recognize at first) thus ANY kind of traversal of this full subtree can be done to find and store all the elements in this subtree (visiting every node in it). This type of thing must be repeated for the right child but visiting every left child until an element with a key=k is found. then the subtree with this element as its root has all the other elements with key=k in it and they can be found by one again fully traversing this subtree.
That is just a word description of it obviously, sorry for the length, and any confusion. Hopefully this will help anyone else trying to solve a similar problem.

Resources