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