C 在一个节点中有多个元素的B树中递归查找第k个最小元素

C 在一个节点中有多个元素的B树中递归查找第k个最小元素,c,algorithm,data-structures,b-tree,C,Algorithm,Data Structures,B Tree,假设我们有下面的b-树 我想创建一个算法,以便找到第k个最小元素。我试图实现本文中所写的内容,但我发现似乎没有任何解决方案适用于这种树 到目前为止,我已经完成了这项工作,它对于最后一个分支的元素运行良好 i <-0 function kthSmallestElement(Node node, int k) if(branch[i] != NULL) then size<-branch[i].size(); if(k < size) then

假设我们有下面的b-树

我想创建一个算法,以便找到第k个最小元素。我试图实现本文中所写的内容,但我发现似乎没有任何解决方案适用于这种树

到目前为止,我已经完成了这项工作,它对于最后一个分支的元素运行良好

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条目[k-1]
其他的
打印分支[i-1]->条目[k-1]
端函数
我已经用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);
}
#定义节点中最多4/*个键的最大数目*/
#定义节点中最少2/*个键的最小数目*/
typedef int键;
类型定义结构{
钥匙;
int value;/*值可以是任意值*/
}树木;
typedef枚举{FALSE,TRUE}布尔值;
类型定义结构树节点树节点;
树状结构{
int count;/*表示节点中有多少个键*/
/*
每个节点上的条目都保存在一个数组条目中
以及数组分支中的指针
*/
树入口[MAX+1];
Treenode*分支[最大值+1];
};
int i=0;
int size=0;
void findkthsmalestelement(Treenode*rootNode,int k){
if(branch[i]!=NULL)//因为节点有一个子节点
大小=分支[i]->计数;
如果(k<尺寸){
i++;
FindKthSmallestElement(分支[i],k];
}否则,如果(k>大小){
k-=尺寸;
i++;
FindKthSmallestElement(分支[i],k];
}else if(k==大小)
printf(“%d”,分支[i]->条目[k-1]。键);
其他的
printf(“%d”,分支[i-1]->条目[k-1]。键);
}

为了使每个第k个最小元素都有一个有效的输出,您能建议我在这方面应该解决什么问题吗?我倾向于认为这个问题不能递归地解决,因为每个节点中有多个条目。明智的做法是将其设置为如下所示的堆树?

递归地访问每个节点,并将当前节点的k个最小元素添加到列表中。最后,对它进行排序并得到第k个数字

您也可以尝试比较2个列表,每次保留k个最小的列表,但我认为这会使代码看起来更复杂,最终的速度大致相同或更差,但占用的内存肯定会更少。

这个问题可以递归解决。您只需函数返回两个内容:

  • 第k个最小键(或指向它的指针),如果它有k个或多个键
  • 树的大小(如果它的关键帧少于k个)
  • 递归是通过从最左边到最右边连续调用(根)节点的每个子树上的函数,并使用不同的(递减的)参数k来实现的:

    • 让原始/当前树为R,通过调用R最左边的子树上与R接收的k相同的函数开始递归
    • 如果在R的子树上调用函数成功返回第k个最小键,那么这就是答案并返回它
    • 如果在R的某个子树T上调用函数找不到第k个最小键,而是返回一个大小为T的值,例如n(
    • 如果T是最右边的子树,则R的项数少于k,返回R的大小(将其所有子树的大小和R根中的键数相加即可得到)
    • 如果n==k-1,那么第k个最小的键就是紧靠T右边的键
    • 如果n

    显然,您必须注意树的根没有子树的终端条件。从概念上讲,允许包含0键的空子树可能更容易处理。

    采用普通b树排序算法并采用第k个元素有什么问题?请将其转换为a,以演示您所取得的成果。发布的代码不是C,而是一些伪代码。您说它“对于最后一个分支的元素运行良好”。好的-但是如果你有一些C代码,就发布它而不是伪代码。因为这个问题缺乏数据结构和代码之类的基本知识,所以任何人都很难帮助你。如果数据结构与我想象的一样,那么可以使用递归,但您必须一直到左边开始,然后在函数调用开始返回时检查“返回值”。@Simons0n您有一点,我只是想知道我是否可以用一个如上所示的算法递归地解决这个问题,这个算法应该是分支[1]的直接右子树?分支[1]还是分支[0]?我正在测试您的解决方案,但无法到达第三小元素,即分支[0]。也许我错过了什么。如果我尝试对上面的代码实现您的建议,您能做出适当的更正吗?@VassilisDe分支[1]的右近子树是分支[2]。对不起,我的术语似乎和你的不同。在我的算法中,分支[0]是当前树的“根”,其中{branch[1],branch[2],branch[3]}是分支[0]拥有的3个子树。