Pet*_*ron 9 c# linq sorting linked-list
使用LINQ通过前任(或父)元素索引来排序无序元素列表的最快方法是什么?
每个元素都有一个唯一的ID和该元素的前任(或父)元素的ID,从中可以构建链表以表示有序状态.
ID | Predecessor's ID
--------|--------------------
20 | 81
81 | NULL
65 | 12
12 | 20
120 | 65
Run Code Online (Sandbox Code Playgroud)
排序顺序为{81,20,12,65,120}.一个(有序的)链表可以很容易地从这些元素迭代地组装,但它可以在更少的LINQ语句中完成吗?
编辑:我应该指定ID不一定是顺序的.为简单起见,我选择了1到5.查看随机的更新元素索引.
假设“索引”与排序无关(只是一个ID),那么可以这样声明:
public class Node
{
public int ID { get; set; }
public int? PredID { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
然后,您可以建立从前任到后继的地图,然后点击链接。但是,这不是纯粹的 LINQ,但可读性和效率很高:
public static LinkedList<int> GetLinkedList(IEnumerable<Node> nodes)
{
if(nodes == null)
throw new ArgumentNullException("nodes");
return new LinkedList<int>(GetOrderedNodes(nodes.ToList()));
}
private static IEnumerable<int> GetOrderedNodes(IEnumerable<Node> nodes)
{
// Build up dictionary from pred to succ.
var links = nodes.Where(node => node.PredID != null)
.ToDictionary(node => node.PredID, node => node.ID);
// Find the head, throw if there are none or multiple.
var nextId = nodes.Single(node => node.PredID == null).ID;
// Follow the links.
do
{
yield return nextId;
} while (links.TryGetValue(nextId, out nextId));
}
Run Code Online (Sandbox Code Playgroud)
编辑:这是一个效率低下但功能强大的解决方案。
想法是元素的索引必须为1 +先前索引,这很容易递归指定。当然,基本情况是头-一个节点,其前任ID为null。
static LinkedList<int> GetLinkedList(IEnumerable<Node> nodes)
{
return new LinkedList<int>
( from node in nodes
orderby GetIndex(nodes, node)
select node.ID
);
}
static int GetIndex(IEnumerable<Node> nodes, Node node)
{
return node.PredID == null ? 0 :
1 + GetIndex(nodes, nodes.Single(n => n.ID == node.PredID));
}
Run Code Online (Sandbox Code Playgroud)
通过首先创建从后继者到前任者的映射,可以在某种程度上改进第二种解决方案。但是,它仍然没有强制性解决方案那么出色。
编辑:将第一个解决方案变成迭代器块。
Bro*_*ass -1
对于排序来说,节点链接的事实是无关紧要的,只是 id 很重要。在这种情况下,您可以只使用OrderBy,在这种情况下,它将把可为空的 int 放在顶部,然后升序排序。
public class ListNode
{
public int Id { get; set; }
public int? Predecessor { get; set; }
}
List<ListNode> myList = new List<ListNode> {
new ListNode() { Id = 2, Predecessor = 1},
new ListNode() { Id = 1, Predecessor = null},
new ListNode() { Id = 5, Predecessor = 4},
new ListNode() { Id = 3, Predecessor = 2},
new ListNode() { Id = 4, Predecessor = 3}};
var sortedbyPredecessor = myList.OrderBy(n => n.Predecessor).ToList();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3408 次 |
| 最近记录: |