B-tree: delete a non-leaf node? - data-structures

Im studying B tree and in the book they said that:
If the key k is in node x and x is a leaf, delete the key k from x.
If the key k is in node x and x is an internal node, do the following.
a. If the child y that precedes k in node x has at least t keys, then find the predecessor k' of k in the subtree rooted at y. Recursively delete k', and replace k by k' in x. (Finding k' and deleting it can be performed in a single downward pass.)
b. Symmetrically, if the child z that follows k in node x has at least t keys, then find the successor k' of k in the subtree rooted at z. Recursively delete k', and replace k by k' in x. (Finding k' and deleting it can be performed in a single downward pass.)
c. Otherwise, if both y and z have only t- 1 keys, merge k and all of z into y, so that x loses both k and the pointer to z, and y now contains 2t - 1 keys. Then, free z and recursively delete k from y.
My question is this: In case 2.a.
Can someone explain me with example: Recursively delete k', and replace k by k' in x.
Regards.

Suppose you have b tree with the degree t = 4:
26, 49, 60
27,31,34,36 51,55,56,58
Suppose y = [27,31,34,36], x = [51,55,56,58] are not leaf nodes and you want to delete key k = 51. Let K = 49 be the key in the parent node which splits x and y.
Find the predecessor of k which is the rightmost key k' in the subtree y (which could contain integers between 37 and 48 in this example, say k' = 40). Set k = K = 49 and K = k' = 40 and delete k' recursively (which is actually the first case of the deletion procedure when the node is leaf). The resulting b tree looks like
26, 40, 60
27,31,34,36 49,55,56,58

Related

Count number of pairs of nodes in undirected graph such that W - L >= K

Question:
Given an undirected graph of N nodes and N-1 edges. The length of all edges are 1. Each edge i has a weight of Wi. (0 <= Wi <= 10.000)
The graph is guaranteed to not have any loops. So there's always one (and only) shortest path between 2 nodes.
Take a pair of node (u, v) from the graph:
l is the length of shortest the path between the 2 nodes
w is the edge with the largest weight in the shortest path between the 2 nodes
Given the number K, count the number of pair (u, v) from the graph such that w - l >= K
Example:
N = 3, K = 1
Edges:
1 - 2 - 3
1 - 3 - 2
(Edges are described as: u - v - w)
Answer: 6. All the possible pairs are: (1, 2), (1, 3), (2, 1), (2, 3), (3, 1), (3, 2)
Brute Force Solution (N < 100):
Go over all pairs of (u, v), find the shortest path along side with w and l. Increase the answer if w - l >= K.
Time complexity: O(N^3)
P/S:
I have tried and succeeded the brute force solution (with N < 100). But I'm struggling to find a solution with N up to 100.000
To work out user202729's hint:
Find the centroid (vertex whose removal leaves subtrees that each have at most half of the vertices of the whole tree).
Count the pairs (u, v) whose path contains the centroid.
Delete the centroid and operate recursively on each of the subtrees.
Step 1 is O(n) (there's a standard algorithm) and Step 2 will be O(n log n), so the Master Theorem gives O(n log2 n) for the whole.
To implement Step 2, root the tree at the centroid and calculate, for the centroid and each of its children, the number of descendants at each depth. Put the results in Fenwick trees for O(log n)-time prefix sums.
Now, sort the edges by weight. Starting with the heaviest edge e and working our way to the lightest, we count the pairs whose path has e as its heaviest edge. The edge e connects a parent and a child; let x be the child. For each (improper, so including x) descendant u of x, let ℓ* = w − K be the greatest ℓ such that w − ℓ ≥ K. With two prefix sums, count the number of vertices v in other subtrees at depth at most ℓ* − depth(u). Then issue updates to the Fenwick trees to remove u from the count.

Edmond matching algorithm. How to start with a empty matching set?

I would like to perform the Edmond matching algorithm or Blossom algorithm on a Graph (example Graph in picture), but how to I start with a empty matching set?
The Algorithm work this way:
Given: Graph G and matching M in G
Task: find matching M' with |M'| =
[M| + 1, or |M'| = IM| if M maximum
1 let F be the forest consisting of all M-exposed nodes; 2 while there
is outer node x and edge {x, y) with y \in V(F), add (x, y} and
matching edge covering y to F;
3 if there are adjacent outer nodes x, y in same tree, then shrink
cycle (M-blossom) in F \cup {x, y) and go to Step 2;
4 if there are adjacent outer nodes x, y in different trees, then
augment M along M-augmenting path P(x) \cup {x, y} \cup P(y);
5 in reverse order, undo each shrinking and re-establish near-perfect
matchings in blossoms.
You don’t begin the algorithm with an empty M. You have to provide one, generally by generating it with a greedy algorithm that parses all edges e of the graph G and adds each e to M if M + e form a matching.

Deletion of the leaf node from B-tree

What are the rules of deleting nodes from a leaf nodes in a B tree. I have given an example below. I need to delete keys, J,K,U from leaf nodes. the 't' of the B tree is 3. so the minimum number of keys in a node should be 2.
J can be deleted without any issue.
But when J is deleted, the remaining would be K,L. Next when deleting K, since the node contains 2 nodes, K cannot be deleted directly.
Since its sibling node, which is N,O also contains its minimum nodes what should I perform here? Is it a merge?
How can I delete K and also U.
Please help.
I referred this book Introduction-to-algorithms-3rd-edition by Thomas H Cormen and he explained it very well.
Here are the 3 steps that include all the cases.Hope it helps.
If the key k is in node x and x is a leaf, delete the key k from x.
If the key k is in node x and x is an internal node, do the following:
a. If the child y that precedes k in node x has at least t keys, then find the predecessor k' of k in the subtree rooted at y. Recursively delete k0,and
replace k by k' in x. (We can find k0 and delete it in a single downward
pass.)
b. If y has fewer than t keys, then, symmetrically, examine the child z that
follows k in node x. If z has at least t keys, then find the successor k' of k in the subtree rooted at z. Recursively delete k' ,and replace k by k' in x. (We
can find k' and delete it in a single downward pass.)
c. Otherwise, if both y and z have only t-1 keys, merge k and all of z into y,
so that x loses both k and the pointer to z, and y now contains 2t-1 keys.
Then free z and recursively delete k from y.
If the key k is not present in internal node x, determine the root x.ci of the appropriate subtree that must contain k, if k is in the tree at all. If x.ci has only t-1 keys, execute step 3a or 3b as necessary to guarantee that we descend to a node containing at least t keys. Then finish by recursing on the appropriate child of x.
a. If x.ci has only t-1 keys but has an immediate sibling with at least t keys, give x.ci an extra key by moving a key from x down into x.ci, moving a
key from x.ci’s immediate left or right sibling up into x, and moving the
appropriate child pointer from the sibling into x.ci.
b. If x.ci and both of x.ci’s immediate siblings have t-1 keys, merge x.ci with one sibling, which involves moving a key from x down into the new
merged node to become the median key for that node.

Data structure for an integer list minimizing cost of inserting, deleting and partial sums

Let L be a list of integers, design data structure that would minimize cost of following operations:
Insert(i,x) - insert integer x to the list after position i
Delete(i) - remove the integer at position i from the list
Sum(i,j) - returns sum of all elements between and including positions i and j
I already figured out that normal linked list is much too slow for this when you work on large amounts of data.
You start with any of the many methods that create a binary tree with a height that is O (log n). The elements in the tree are ordered by index. In addition to a usual tree, for each link to a subtree it also contains the number of items in that subtree and the sum of the integers in the subtree.
The number of items in the subtree makes it easy to add and remove items in the right positions. For example, if there are two subtrees with x and y items, and we want to insert an item at position i, 0 ≤ i ≤ x+y, we insert it at position i in the left subtree if i ≤ x, or at position i - x in the right subtree if i ≥ x (if i = x we can insert it in either tree), updating the number of indexes and the sum of integers for that link. If the tree needs to be balanced, the counts and sums need to be updated during the balancing as well.
It is also easy to calculate the sum in logarithmic time: To calculate the sum for i ≤ n ≤ j when the left subtree has x items and the right one has y items: If j < x calculate the sum of elements i ≤ n ≤ j in the left subtree. if i ≥ x then calculate the sum of elements i-x ≤ n ≤ j-x in the right subtree. If i < x and j ≥ x then add the sum of elements i ≤ n ≤ x-1 in the left subtree and the sum of elements 0 ≤ n ≤ j-x in the right subtree. Obviously if j - i + 1 equals the number of items in a subtree, then we take the stored sum of numbers.
We can use AVL tree as it is balanced tree and Binary tree has worst case complexity higher than AVL.

Binary Search Tree - Searching for a Scope

If I have a binary search tree S with the number pair (a,b) where (a<=b); is there an algorithm that would help me find the elements in S with the key values that are within the range of a,b inclusive ([a,b]).
The runtime restriction is O(h+k), h is the tree height of S, and k is the number of elements within the range.
The classic answer is from "Introduction to Algorithms":
http://staff.ustc.edu.cn/~csli/graduate/algorithms/book6/chap14.htm
Step 1: find a, using the normal binary tree lookup.
Step 2: call tree successor iteratively until you find b. Tree successor gives you the next item in the tree:
TREE-SUCCESSOR(x)
if right[x] ≠ NIL
then return TREE-MINIMUM (right[x])
y ← p[x]
while y ≠ NIL and x = right[y]
do x ← y
y ← p[y]
return y
TREE-MINIMUM (x)
while left[x] ≠ NIL
do x ← left[x]
return x

Resources