【问题标题】:Converting a sorted doubly linked list to a BST将已排序的双向链表转换为 BST
【发布时间】:2017-05-15 07:49:53
【问题描述】:

如何将有序的双向链表转化为平衡的二叉搜索树。

我正在考虑以与将数组转换为平衡 BST 相同的方式执行此操作。 找到中心,然后递归转换DLL的左边部分和右边部分。 例如,

1 2 3 4 5 => 1 2 (3) 4 5 =>

     3
   /   \
  2     4
 /       \
1         5

这导致递归 T(n) = 2T(n/2) + O(n)。 O(n) 用于寻找中心。 因此时间复杂度为 O(nlogn)。 我想知道是否有一种算法可以在 O(n) 中执行此操作。

【问题讨论】:

    标签: algorithm binary-tree doubly-linked-list


    【解决方案1】:

    是的,有 O(n) 的解决方案。请注意,BST 上的 in-order traversal 正在以所需的顺序迭代元素,因此只需对最初为 n 大小的空树进行 inorder 遍历,并用列表中的元素填充它。 [您在遍历中插入树的第 i 个元素是列表中的第 i 个元素]。
    在答案的最后我添加了如何在O(n) 中创建一个空平衡树。

    伪代码:[假设 |list| == |树|]

    global current <- null
    fillTree(tree,list):
      current <- list.head
      fillTree(tree)
    fillTree(tree):
      if tree == null:
         return
      fillTree(tree.left)
      //in-order traversal: we set the value after setting left, and before calling right
      tree.val <- current.val
      current <- current.next
      fillTree(tree.right)
    

    复杂性是微不足道的O(n),因为对于树的每个顶点恰好有一次迭代,并且每次迭代都是 O(1)。

    编辑:
    您可以创建一个空平衡树,只需构建一个空的complete tree(*),它是平衡的并且构建它是 O(n)。

    (*)完全二叉树是一种二叉树,其中除了可能的最后一层之外,每一层都被完全填满。

    【讨论】:

    • 我没有将 BST 转换为 DLL。其他方式
    • @shreyasva:请阅读答案,它将排序列表转换为 BST。它在遍历树时这样做。
    • @shreyasva:我编辑了答案并添加了“如何在O(n) 中构建一个空平衡树?”如果这是我的答案的问题。
    • amit 的解决方案是正确的:先建一棵空树,然后用元素填充它。两个任务都是 O(n)。
    • @amit 您正在创建一棵新树,对吧?我正在寻找一种就地算法。
    【解决方案2】:

    晚了将近 4 年。但这是我的功能解决方案。以下是我在haskell中的代码,复杂度也是O(n)

    import Data.List hiding (insert)
    
    data Color = R | B deriving Show
    data RBTree a = RBEmpty | RBTree { color :: Color
                                     , ltree :: RBTree a
                                     , nod   :: a
                                     , rtree :: RBTree a } deriving Show
    
    fromOrdList ::  Ord e => [e] -> RBTree e
    fromOrdList [] = empty
    fromOrdList lst = 
        let (res, _) = _fol lst $ length lst
        in res
        where _fol :: (Ord e, Integral a) => [e] -> a -> (RBTree e, Maybe (e, [e]))
              _fol l 0            = (empty, uncons l)
              _fol (h:l) 1        = (RBTree B empty h empty, uncons l)
              _fol (h1:h2:l) 2    = (RBTree B (RBTree R empty h1 empty) h2 empty, uncons l)
              _fol (h1:h2:h3:l) 3 = (RBTree B (RBTree R empty h1 empty) h2 (RBTree R empty h3 empty), uncons l)
              _fol l n            =
                let mid                  = n `div` 2
                    (ltr, Just (rt, tl)) = _fol l mid
                    (rtr, mayremain)     = _fol tl (n - 1 - mid)
    in (RBTree B ltr rt rtr, mayremain)
    

    这实际上是我个人实践的一部分:https://github.com/HuStmpHrrr/PFDSPractise/blob/master/src/Tree/RBTree.hs#L97

    【讨论】:

      【解决方案3】:

      看看我的递归插入实现(c#)。有 T(n) = 2*T(n/2) + O(1)。 O(1) 用于寻找中心:(l+r)/2。所以同谋是 O(n)

      public class Tree<T>
        {
          public class TreeNode<T>
          {
            public TreeNode<T> Right { get; set; }
            public TreeNode<T> Left { get; set; }
            public T Data { get; set; }
          }
      
          public Tree()
          {
            Root = new TreeNode<T>();
          }  
      
          public TreeNode<T> Root { get; set; }
      
          private void InsertSortedListRec(IList<T> items, TreeNode<T> curNode, int l, int r)
          {
            var mid = (l + r)/2;
            curNode.Data = items[mid];
      
            if (mid - 1 >= l)
            {
              curNode.Left = new TreeNode<T>();
              InsertSortedListRec(items, curNode.Left, l, mid - 1);
            }
      
            if (mid + 1 <= r)
            {
              curNode.Right = new TreeNode<T>();
              InsertSortedListRec(items, curNode.Right, mid + 1, r);
            }
        }
      
          public void InsertSortedList(IList<T> items)
          {
            InsertSortedListRec(items, Root, 0, items.Count - 1);
          }
        }
      

      我假设我们有索引数组(我们可以将链表转换为数组 O(n))

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-02-14
        • 1970-01-01
        • 1970-01-01
        • 2023-04-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多