Reputation: 373
Suppose we have the following b-tree
I would like to create an algorithm in order to find the k-th smallest element. I tried to implement what was written in this link but I found out that none of the solutions seem to work for this kind of tree.
So far I have done this, which runs fine for the elements of the last branch
i <-0
function kthSmallestElement(Node node, int k)
if(branch[i] != NULL) then
size<-branch[i].size();
if(k < size) then
i++;
call the function recursively for new branch[i], k
else if(k > size) then
k-=size
i++;
call the function recursively for new branch[i], k
else if (k==size) then
print branch[i]->entry[k-1]
else
print brach[i-1]->entry[k-1]
end function
I have implemented the algorithm using C
#define MAX 4 /* maximum number of keys in node. */
#define MIN 2 /* minimum number of keys in node */
typedef int Key;
typedef struct {
Key key;
int value; /* values can be arbitrary */
} Treeentry;
typedef enum {FALSE, TRUE} Boolean;
typedef struct treenode Treenode;
struct treenode {
int count; /* denotes how many keys there are in the node */
/*
The entries at each node are kept in an array entry
and the pointers in an array branch
*/
Treeentry entry[MAX+1];
Treenode *branch[MAX+1];
};
int i = 0;
int size = 0;
void FindKthSmallestElement(Treenode *rootNode, int k){
if(branch[i] != NULL) //since the node has a child
size = branch[i] ->count;
if(k < size){
i++;
FindKthSmallestElement(branch[i], k);
}else if(k > size){
k-=size;
i++;
FindKthSmallestElement(branch[i], k);
}else if (k==size)
printf ("%d", branch[i]->entry[k-1].key);
else
printf ("%d", brach[i-1]->entry[k-1].key);
}
Could you please suggest what should I fix in this in order to have a valid output for every kth smallest element? I tend to believe that this problem cannot be solved recursively, since we have more than one entries in each node. Would be wise to make it a heap tree like in this link?
Upvotes: 2
Views: 1129
Reputation: 470
This problem can be solve recursively. All you need is for the function to return 2 things:
The recursion occurs by calling the function on every subtree of the (root) node, consecutively, from the left-most to the right-most, and with different (decreasing) parameter k:
Obviously you'd have to take care of the terminal condition where a tree's root has no more subtree. Conceptually it may be more easily handled by allowing a NULL subtree, which contains 0 key.
Upvotes: 2
Reputation: 310
Recursively visit every node and add to a list the k smallest elements of the current node. In the end sort it and get the k-th number.
You could also try comparing the 2 list and keeping the k smallest ones each time but i think it's gonna make the code look more complicated and will end up with roughly the same or worse speed but for sure less memory occupied.
Upvotes: 1