假设我们有以下b-tree
我想创建一个算法,以便找到第k个最小的元素。我试图实现这个link中写的内容,但我发现没有一个解决方案似乎适用于这种树。
到目前为止,我已经完成了这项工作,对于最后一个分支
的元素运行良好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
我使用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);
}
为了获得每个第k个最小元素的有效输出,你能否建议我应该解决这个问题?我倾向于认为这个问题不能递归地解决,因为我们在每个节点中有多个条目。将它变成像link这样的堆树是明智的吗?
答案 0 :(得分:2)
这个问题可以递归解决。您所需要的只是让函数返回两件事:
通过在(根)节点的每个子树上连续地从最左边到最右边调用函数并使用不同的(递减的)参数k来进行递归:
显然,您必须处理树的根不再具有子树的终端条件。从概念上讲,通过允许包含0键的NULL子树可以更容易地处理它。
答案 1 :(得分:1)
递归访问每个节点,并将当前节点的k个最小元素添加到列表中。最后排序并获得第k个数字。
你也可以尝试比较2个列表并每次保持k个最小的列表,但我认为它会使代码看起来更复杂并且最终会以大致相同或更差的速度结束,但肯定会减少内存占据。