【问题标题】:Binary tree to Double Linked List in C#.netC#.net 中的二叉树到双链表
【发布时间】:2014-12-28 15:33:07
【问题描述】:

我正在尝试将二叉树转换为 C# 中的双链表。

DLL中节点的顺序必须是二叉树的中序遍历。

代码如下:

public void BSTtoDLL(ref Node root,ref Node head,ref Node tail)
        {
            if (root == null) return;

            BSTtoDLL(ref root.left,ref head,ref tail);

            if (tail != null)
            {               
                root.left = tail;
                tail.right = root;
            }
            else
            {
                head = root;
            }

            tail = root;

            BSTtoDLL(ref root.right,ref head, ref tail);
        }

但我得到堆栈溢出异常?

我错过了什么?

【问题讨论】:

    标签: c# .net data-structures


    【解决方案1】:

    虽然中序遍历没问题,但您的其余代码根本上是错误的。虽然leftright 字段是树结构的本机部分,但您将它们误用于双链表。结果是您使树结构无效,显然引入了一个圆圈,然后导致堆栈溢出。

    如果您确实需要将这些引用保留在Node 类本身,则必须维护两对,如下所示:

    • treeLeft, treeRight — 用于树数据结构
    • listPrev, listNext — 用于双链表结构(注意,将这些引用称为 previousnext

    还有一些需要考虑的事情:

    • 没有理由用ref 传递根节点
    • 我建议完全消除 refs,而是在 DoubleLinkedList 类上运行
    • 一般来说,我建议从有用的数据负载中分解数据结构的机制,创建TreeNode<T>ListNode<T>,其中T 代表有用的数据负载。

    【讨论】:

    • 这是一个算法问题,除了左右树之外,我不应该维护任何额外的指针。如果我不传递 ref 对象,我该如何更改左右指针?
    • 对不起,它起作用了。我刚刚删除了方法中根变量中的 ref。
    【解决方案2】:
    public class TreeNode
    {
        public TreeNode Left { get; set; }
        public int Data { get; set; }
        public TreeNode Right { get; set; }
    
        public TreeNode(int data)
        {
            this.Left = null;
            this.Data = data;
            this.Right = null;
        }
    }
    public class DLLNode
    {
        public DLLNode Prev { get; set; }
        public int Data { get; set; }
        public DLLNode Next { get; set; }
    
        public DLLNode(int data)
        {
            this.Data = data;
        }
    }
    public class Tree
    {
        public TreeNode Root { get; set; }
        public Tree()
        {
            // Creating a dummy tree;
            Root = new TreeNode(10);
            Root.Left = new TreeNode(12);
            Root.Left.Left = new TreeNode(25);
            Root.Left.Right = new TreeNode(30);
            Root.Right = new TreeNode(15);
            Root.Right.Left = new TreeNode(36);
        }
    }
    public class DLL
    {
        private DLLNode Curr { get; set; }
        public DLLNode Head { get; set; }
    
        public void FromTree(Tree t)
        {
            ProcessInOrder(t.Root);
        }
        public void Display()
        {
            while(Head != null)
            {
                Console.Write(Head.Data + ", ");
                Head = Head.Next;
            }
        }
    
        private void ProcessInOrder(TreeNode n)
        {
            if(n != null)
            {
                ProcessInOrder(n.Left);
                CreateDLLNode(n);
                ProcessInOrder(n.Right);
            }        
        }
        private void CreateDLLNode(TreeNode n)
        {
            DLLNode node = new DLLNode(n.Data);
            if(Curr == null)
            {
                Curr = Head = node;
            }
            else
            {
                Curr.Next = node;
                node.Prev = Curr;
                Curr = node;
            }
        }
    }
    DLL d = new DLL();
    d.FromTree(new Tree());
    d.Display();
    

    【讨论】:

    • 虽然您的代码可能会回答这个问题。最好在您的帖子中添加一些文字来解释 OP 遗漏了什么。
    猜你喜欢
    • 2018-09-02
    • 1970-01-01
    • 1970-01-01
    • 2015-01-14
    • 2012-07-15
    • 1970-01-01
    • 2012-03-17
    • 2012-02-28
    • 2013-08-26
    相关资源
    最近更新 更多