Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Data structures 二叉搜索树问题:将BST转换为左右节点数相差1的BST_Data Structures_Binary Tree_Binary Search Tree_Graph Theory_Balance - Fatal编程技术网

Data structures 二叉搜索树问题:将BST转换为左右节点数相差1的BST

Data structures 二叉搜索树问题:将BST转换为左右节点数相差1的BST,data-structures,binary-tree,binary-search-tree,graph-theory,balance,Data Structures,Binary Tree,Binary Search Tree,Graph Theory,Balance,我正在做一个需要平衡任何二叉搜索树的问题,每个级别上的左、右子树应该有相同数量的节点,或者最多有一个节点差 我如何处理这个问题? 到目前为止,我已将该树转换为链表。。就这样。我很确定这是第一步,但不太确定。我到处寻找资源,但我能找到的最接近的东西是day stout warren算法,它根据高度而不是节点数量进行平衡 我只是在寻找伪代码将所有节点按顺序遍历添加到数组中,然后大致如下所示: fun buildBalanced( array: Array, start: Int

我正在做一个需要平衡任何二叉搜索树的问题,每个级别上的左、右子树应该有相同数量的节点,或者最多有一个节点差

我如何处理这个问题? 到目前为止,我已将该树转换为链表。。就这样。我很确定这是第一步,但不太确定。我到处寻找资源,但我能找到的最接近的东西是day stout warren算法,它根据高度而不是节点数量进行平衡


我只是在寻找伪代码

将所有节点按顺序遍历添加到数组中,然后大致如下所示:


fun buildBalanced(
    array: Array, 
    start: Int = 0, 
    end: Int = array.length) -> Node {
  if (start >= end) {
    return nil
  }
  let middle = (start + end) / 2
  return new Node(
      array[middle], 
      buildBalanced(array, start, middle),
      buildBalanced(array, middle + 1, end))  
}


这是一个Python解决方案,它在O(n)时间内工作,在O(h)辅助空间中,h是树的高度;唯一的辅助数据结构是递归函数所需的堆栈

它使用生成器函数进行工作,该函数在使用者更改树时对树进行迭代,但我们在生成
子树之前,先对其进行本地复制,以便使用者可以在不破坏生成器的情况下重新分配这些子树。(实际上只需要一份
右侧的本地副本
,但无论如何我都制作了本地副本。)

类节点:
定义初始化(self,data,左=无,右=无):
self.data=数据
self.left=左
self.right=right
定义报告(自我):
#显示用于调试/测试目的
def_r(n):
如果n不是其他值,则返回“*”(%s)← %R→ %s) “%(_r(n.左),n.数据,_r(n.右))
返回(自我)
def余额(根):
定义树(节点):
如果节点不是“无”:
#保存到局部变量,可以在生成时重新分配
左,右=node.left,node.right
树的产量(左)
屈服点
从"树"到"iter"的产量(右)
def_辅助程序(it,k):
如果k==0:
一无所获
其他:
half_k=(k-1)//2
left=\u helper(it,half\k)
节点=下一个(it)
right=\u helper(it,k-half\u k-1)
node.left=左
node.right=右
返回节点
n=总和(1表示树中的根)
return\u helper(\u tree\u iter(root),n)
例如:

根=节点(4,左=节点(3,左=节点(1,右=节点(2)),右=节点(6,左=节点(5),右=节点(8,左=节点(7),右=节点(9))) >>>根 (((* ← 1.→ (* ← 2.→ *)) ← 3.→ *) ← 4.→ ((* ← 5.→ *) ← 6.→ ((* ← 7.→ *) ← 8.→ (* ← 9→ *)))) >>>平衡(根) (((* ← 1.→ *) ← 2.→ (* ← 3.→ (* ← 4.→ *))) ← 5.→ ((* ← 6.→ *) ← 7.→ (* ← 8.→ (* ← 9→ *))))
为什么将其转换为链表会有用?似乎目标是找到中间元素并使其成为根节点。@kaya3是的,考虑到树未排序,链表将对其进行排序,我认为这意味着从中间开始旋转的次数较少。我假设我们只旋转左侧的下一个中间,即d在右边,等等,但我认为这不起作用。二元搜索树怎么可能不排序?不排序的意思是数字不是升序的。二元搜索树排序的意思是,如果我没有弄错的话,按顺序遍历将按升序给你节点。如果不创建另一个链表和si,你无法找到中间值由于这是一个可能会减少总旋转次数的模型,我想我只需将树转换为一个链接列表,你就可以找到中间值,而无需将节点放入另一个数据结构中。谁说你不能?树是这样的吗?如果是这样,可能是因为我的问题措辞不当。在子树2和7中,d左子树节点和右子树节点之间的差异是-1。非常感谢btw提供的代码。这对我很有帮助,我可以自己调整它。啊,在这种情况下,交换
half_k
k-half_k-1
就足够了。我最终将树变成了一棵藤蔓,然后将其操纵到我想要的树中。我无法实现你的算法不适用于我的二叉树类。它在伪代码方面帮助了我很多。谢谢。既然我看到你在攻读博士学位,我想知道,你不会把它变成一个链表,然后操纵它,占用更少的辅助空间吗?我知道它与这个问题无关,但今天的stout warren算法不是唯一有效的吗因为转换成链表?哦,我现在明白了,你的意思是重用树节点的内部指针来形成链表;你的建议并不清楚。是的,在这种情况下,你应该能够用O(1)辅助空间而不是O(h)来完成。如果你能这样做,那么你可能想自己将其作为答案发布。谢谢你的回复。今天,我得知我的同学到达平衡树的时间比我少10倍,因此肯定链表不是解决问题的方法(他们只是在树上工作).但我的大脑太小,无法破解代码,无法在树中完成。很抱歉,我不清楚这个问题,我想我应该更多地学习英语技能,而不是python技能哈哈