C#.net中的二叉树到双链表

C#.net中的二叉树到双链表,c#,.net,data-structures,C#,.net,Data Structures,我正在尝试将二叉树转换为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)

我正在尝试将二叉树转换为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);
        }
但是我得到了堆栈溢出异常


我遗漏了什么?

虽然顺序遍历是正确的,但代码的其余部分基本上是错误的。虽然
字段是树结构的本机部分,但您将它们错误地用于双链接列表。其结果是使树结构无效,显然引入了一个圆圈,从而导致堆栈溢出

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

  • treeLeft
    treeRight
    -用于树数据结构
  • listprov
    listNext
    -用于双链接列表结构(注意,通常将这些引用称为previous和next)
另外还有几件事需要考虑:

  • 没有理由用
    ref
  • 我建议完全取消
    ref
    s,而是在
    DoubleLinkedList
    类上操作
  • 通常,我建议从有用的数据有效负载分解数据结构的机制,创建
    TreeNode
    ListNode
    ,其中
    T
    表示有用的数据有效负载

这是一个算法问题,我不应该维护除树左和树右之外的任何额外指针。如果我不传递ref对象,我如何更改左和右指针?很抱歉,它起了作用。我刚刚在方法的根变量中删除了ref。尽管您的代码可能会回答这个问题。最好在帖子中添加一些文字,解释OP遗漏了什么。
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();