C#在二叉树节点中存储链表

C#在二叉树节点中存储链表,c#,linked-list,binary-tree,C#,Linked List,Binary Tree,我想开发一个二叉树结构,这样每个节点都存储一个键和一个链表。这种实现背后的原因是,我希望使用适当的键在二叉树(二叉搜索树)中进行搜索,链表将用作存储结构,我可以随时轻松检索任何信息。有人能在这个方法上帮助我吗?如果有人能提出更好的方法,我们将不胜感激 另外,使用二叉树是因为搜索算法O(logn)的性能,而使用链表是因为结构必须是动态的,所以我不能使用数组,因为它的结构是静态的 > P>您应该考虑使用内置的一个,例如在其他堆栈中描述的SoRead字典:项目是一个很棒的数据结构和算法集合,包括A.将

我想开发一个二叉树结构,这样每个节点都存储一个键和一个链表。这种实现背后的原因是,我希望使用适当的键在二叉树(二叉搜索树)中进行搜索,链表将用作存储结构,我可以随时轻松检索任何信息。有人能在这个方法上帮助我吗?如果有人能提出更好的方法,我们将不胜感激


另外,使用二叉树是因为搜索算法O(logn)的性能,而使用链表是因为结构必须是动态的,所以我不能使用数组,因为它的结构是静态的

> P>您应该考虑使用内置的一个,例如在其他堆栈中描述的SoRead字典:

项目是一个很棒的数据结构和算法集合,包括A.将其与类一起使用,如:

BinaryTree<LinkedList<T>> tree;
二叉树;

您应该使用排序字典:“SortedDictionary(Of TKey,TValue)泛型类是一个具有O(log n)检索的二元搜索树”,请查看文档:

您可以使用其他答案中提供的实现。如果您想了解如何自己编写,下面是我从哈夫曼编码项目中采用的一个示例。这并不完美,但你可以看到一个大致的想法

我将从用法开始

class Program
{
    static void Main(string[] args)
    {
        string[] testData = new string[] { "aa", "bbb", "cccccc", "d", "ee", "ffffff", "ggggg" };
        var expected = new BinaryNode<string>("ffffff");
        IBinaryTree<string> tree = new BinaryTree<string>();
        tree.Build(testData);

        var result = tree.Root.Traverse(expected, new List<IBinaryNode<string>>());
    }
}
类程序
{
静态void Main(字符串[]参数)
{
string[]testData=新字符串[]{“aa”、“bbb”、“CCCC”、“d”、“ee”、“ffffff”、“ggggg”};
var预期值=新的二进制节点(“ffffff”);
IBinaryTree=新的二进制树();
tree.Build(testData);
var result=tree.Root.transverse(应为新列表());
}
}
二进制节点接口和实现

public interface IBinaryNode<T>
{
    int? ID { get; }
    T Data { get; set; }
    IBinaryNode<T> RightChild { get; set; }
    IBinaryNode<T> LeftChild { get; set; }
    IEnumerable<IBinaryNode<T>> Traverse(IBinaryNode<T> current, IEnumerable<IBinaryNode<T>> recursionData);
}

public class BinaryNode<T> : IBinaryNode<T>
{
    public int? ID{get; private set;}
    public T Data { get; set; }
    public IBinaryNode<T> RightChild { get; set; }
    public IBinaryNode<T> LeftChild { get; set; }

    public BinaryNode():this(default(T)){}
    public BinaryNode(T data):this(data, null){}
    public BinaryNode(T data, int? id)
    {
        Data = data;
        ID = id;
    }

    public IEnumerable<IBinaryNode<T>> Traverse(IBinaryNode<T> current, IEnumerable<IBinaryNode<T>> recursionData)
    {
        // no children found
        if (RightChild == null && LeftChild == null)
        {
            //correct guess BinaryNode has the needed data
            if (current.Data.Equals(Data))
            {
                return recursionData;
            }

            //wrong value - try another leg
            return null;
        }

        //there are children
        IEnumerable<IBinaryNode<T>> left = null; //tmp left storage
        IEnumerable<IBinaryNode<T>> right = null; //tmp right storage

        //start with the left child
        //and travers in depth by left leg
        if (LeftChild != null)
        {
            //go in depth through the left child 
            var leftPath = new List<IBinaryNode<T>>();

            //add previously gathered recursionData
            leftPath.AddRange(recursionData);

            leftPath.Add(LeftChild);

            //recursion call by rigth leg
            left = LeftChild.Traverse(current, leftPath);
        }

        //no left children found
        //travers by right leg in depth now
        if (RightChild != null)
        {
            //go in depth through the right child 
            var rightPath = new List<IBinaryNode<T>>();

            //add previously gathered recursionData
            rightPath.AddRange(recursionData);

            //add current value 
            rightPath.Add(RightChild);

            //recursion call by rigth leg
            right = RightChild.Traverse(current, rightPath);
        }

        //return collected value of left or right
        if (left != null)
        {
            return left;
        }

        return right;
    }
}
public interface IBinaryTree<T>
{
    void Build(IEnumerable<T> source);
    IBinaryNode<T> Root { get; set; }
}

public class BinaryTree<T> : IBinaryTree<T>
{
    private readonly List<IBinaryNode<T>> nodes;
    private int nodeId = 0;

    public IBinaryNode<T> Root { get; set; }

    public BinaryTree()
    {
        nodes = new List<IBinaryNode<T>>();
    }

    public bool IsLeaf(IBinaryNode<T> binaryNode)
    {
        return (binaryNode.LeftChild == null && binaryNode.RightChild == null);
    }

    public void Build(IEnumerable<T> source)
    {
        foreach (var item in source)
        {
            var node = new BinaryNode<T>(item, nodeId);
            nodeId++;
            nodes.Add(node);
        }

        //construct a tree
        while (nodes.Count > 1) //while more than one node in a list
        {
            var taken = nodes.Take(2).ToList();

            // Create a parent BinaryNode and sum probabilities
            var parent = new BinaryNode<T>()
            {
                LeftChild = taken[0],
                RightChild = taken[1]
            };

            //this has been added so remove from the topmost list
            nodes.Remove(taken[0]);
            nodes.Remove(taken[1]);
            nodes.Add(parent);
        }

        Root = nodes.FirstOrDefault();
    }
}
公共接口IBinaryNode
{
int?ID{get;}
T数据{get;set;}
IBinaryNode RightChild{get;set;}
IBinaryNode LeftChild{get;set;}
IEnumerable遍历(IBinaryNode当前、IEnumerable递归数据);
}
公共类二进制节点:IBinaryNode
{
公共int?ID{get;private set;}
公共T数据{get;set;}
公共IBinaryNode RightChild{get;set;}
公共IBinaryNode LeftChild{get;set;}
public BinaryNode():此(默认值(T)){}
公共二进制节点(T data):这个(data,null){}
公共二进制节点(T数据,int?id)
{
数据=数据;
ID=ID;
}
公共IEnumerable遍历(IBinaryNode当前、IEnumerable递归数据)
{
//没有找到孩子
if(RightChild==null&&LeftChild==null)
{
//正确猜测BinaryNode具有所需的数据
if(当前数据等于(数据))
{
返回递归数据;
}
//错误的值-尝试另一条腿
返回null;
}
//有孩子
IEnumerable left=null;//tmp左存储
IEnumerable right=null;//tmp权限存储
//从左边的孩子开始
//用左腿纵深穿行
if(LeftChild!=null)
{
//深入检查左边的孩子
var leftPath=新列表();
//添加以前收集的递归数据
AddRange(递归数据);
添加(LeftChild);
//rigth leg的递归调用
left=LeftChild.Travel(当前,leftPath);
}
//未发现遗留儿童
//现在用右腿进行深度穿越
if(RightChild!=null)
{
//深入了解正确的孩子
var rightPath=新列表();
//添加以前收集的递归数据
AddRange(递归数据);
//添加当前值
添加(RightChild);
//rigth leg的递归调用
right=RightChild.Travel(当前,rightPath);
}
//返回左侧或右侧的收集值
if(左!=null)
{
左转;
}
返还权;
}
}
二叉树接口和实现

public interface IBinaryNode<T>
{
    int? ID { get; }
    T Data { get; set; }
    IBinaryNode<T> RightChild { get; set; }
    IBinaryNode<T> LeftChild { get; set; }
    IEnumerable<IBinaryNode<T>> Traverse(IBinaryNode<T> current, IEnumerable<IBinaryNode<T>> recursionData);
}

public class BinaryNode<T> : IBinaryNode<T>
{
    public int? ID{get; private set;}
    public T Data { get; set; }
    public IBinaryNode<T> RightChild { get; set; }
    public IBinaryNode<T> LeftChild { get; set; }

    public BinaryNode():this(default(T)){}
    public BinaryNode(T data):this(data, null){}
    public BinaryNode(T data, int? id)
    {
        Data = data;
        ID = id;
    }

    public IEnumerable<IBinaryNode<T>> Traverse(IBinaryNode<T> current, IEnumerable<IBinaryNode<T>> recursionData)
    {
        // no children found
        if (RightChild == null && LeftChild == null)
        {
            //correct guess BinaryNode has the needed data
            if (current.Data.Equals(Data))
            {
                return recursionData;
            }

            //wrong value - try another leg
            return null;
        }

        //there are children
        IEnumerable<IBinaryNode<T>> left = null; //tmp left storage
        IEnumerable<IBinaryNode<T>> right = null; //tmp right storage

        //start with the left child
        //and travers in depth by left leg
        if (LeftChild != null)
        {
            //go in depth through the left child 
            var leftPath = new List<IBinaryNode<T>>();

            //add previously gathered recursionData
            leftPath.AddRange(recursionData);

            leftPath.Add(LeftChild);

            //recursion call by rigth leg
            left = LeftChild.Traverse(current, leftPath);
        }

        //no left children found
        //travers by right leg in depth now
        if (RightChild != null)
        {
            //go in depth through the right child 
            var rightPath = new List<IBinaryNode<T>>();

            //add previously gathered recursionData
            rightPath.AddRange(recursionData);

            //add current value 
            rightPath.Add(RightChild);

            //recursion call by rigth leg
            right = RightChild.Traverse(current, rightPath);
        }

        //return collected value of left or right
        if (left != null)
        {
            return left;
        }

        return right;
    }
}
public interface IBinaryTree<T>
{
    void Build(IEnumerable<T> source);
    IBinaryNode<T> Root { get; set; }
}

public class BinaryTree<T> : IBinaryTree<T>
{
    private readonly List<IBinaryNode<T>> nodes;
    private int nodeId = 0;

    public IBinaryNode<T> Root { get; set; }

    public BinaryTree()
    {
        nodes = new List<IBinaryNode<T>>();
    }

    public bool IsLeaf(IBinaryNode<T> binaryNode)
    {
        return (binaryNode.LeftChild == null && binaryNode.RightChild == null);
    }

    public void Build(IEnumerable<T> source)
    {
        foreach (var item in source)
        {
            var node = new BinaryNode<T>(item, nodeId);
            nodeId++;
            nodes.Add(node);
        }

        //construct a tree
        while (nodes.Count > 1) //while more than one node in a list
        {
            var taken = nodes.Take(2).ToList();

            // Create a parent BinaryNode and sum probabilities
            var parent = new BinaryNode<T>()
            {
                LeftChild = taken[0],
                RightChild = taken[1]
            };

            //this has been added so remove from the topmost list
            nodes.Remove(taken[0]);
            nodes.Remove(taken[1]);
            nodes.Add(parent);
        }

        Root = nodes.FirstOrDefault();
    }
}
公共接口IBinaryTree
{
无效构建(IEnumerable源);
IBinaryNode根{get;set;}
}
公共类二进制树:IBinaryTree
{
私有只读列表节点;
私有int节点ID=0;
公共IBinaryNode根{get;set;}
公共二叉树()
{
节点=新列表();
}
公共布尔IsLeaf(IBinaryNode二进制节点)
{
返回值(binaryNode.LeftChild==null&&binaryNode.RightChild==null);
}
公共void生成(IEnumerable源)
{
foreach(源中的var项)
{
var节点=新的二进制节点(项,nodeId);
nodeId++;
nodes.Add(node);
}
//建树
while(nodes.Count>1)//当列表中有多个节点时
{
var Take=nodes.Take(2.ToList();
//创建父二进制节点并求和概率
var parent=new BinaryNode()
{
LeftChild=take[0],
RightChild=take[1]
};
//此项已添加,因此从最上面的列表中删除
移除(取[0]);
移除(取[1]);
添加(父节点);
}
Root=nodes.FirstOrDefault();
}
}

最简单的方法是使用内置类,如
SortedDictionary