查找链表邻居滚动密度

时间:2017-06-13 15:10:48

标签: c# linked-list

我有一个这样的链接列表:

public class Node {
    public Node next;
    public Node prev;
    public int length;
    public int weight;
}

我正在尝试使用特定长度作为窗口来查找非圆形链表(具有明确的开始和结束)的滚动密度。这增加了复杂性,因为端节点仅使用权重的百分比。

这意味着给定3个节点

A (L: 10, W:10) -> B (L: 5, W:10) -> C (L:20, W:5)

(其中L表示长度,W表示重量)

和节点9的{​​{1}}窗口将使用所有节点B,现在它有一个4的窗口。它会在C和A之前和之后均匀地分割窗口。

因此密度为:

B

这个常见的情况不是我正在努力的部分,它是左侧不够的时候的结束点,窗口应该从右侧看更多,反之亦然。还有一种情况是两边都没有足够的长度。

我不确定是否应该实现递归函数或循环。我知道循环需要较少的计算,但递归函数可能更容易理解。

案例1:链表中只有一个节点 取1节点的密度忽略窗口

案例2:左/右侧的长度不够 从右/左侧取下剩余部分。

案例3:两侧的长度不够,但不只有1个节点。 占用所有节点,不需要满足窗口。

1 个答案:

答案 0 :(得分:0)

有了你写的所有内容,似乎你唯一的问题是:"我应该循环还是应该递归?"根据您的需要,以最容易阅读和维护的方式(或者性能是您的最高优先级,以较高的性能为准)。

您正在处理链接列表。我建议简单地循环,而不是递归。 (如果你正在处理一棵树,那将是一个不同的故事。)在任何一种情况下,你都可以通过做某种形式的记忆来找到一种节省大量计算的方法。如果您的窗口涉及左右数百个节点,则可以存储节点 n 的大部分密度计算,并且几乎所有节点都可以重复使用 n + 1 。在你开始讨论之前,我先测试一下非记忆版本,然后看看它是否具有足够的性能。

可以帮助您删除边缘情况的一种设计模式是具有Null节点:

Node nullNodeBeginning = new nullNode(length=0, weight=0);
nullNodeBeginning.prev = nullNodeBeginning;
Node nullNodeEnding = new nullNode(length=0, weight=0);
nullNodeEnding.next = nullNodeEnding;

如果您将nullNodeBeginning添加到链接列表的开头并将nullNodeEnding添加到链接列表的末尾,则实际上会有一个无限链接列表。然后你的逻辑变成了:

  1. 获取特定中心节点的长度
  2. 对于上一个,下一个:
    1. 获取 n 节点在该方向上的长度(可能总计为0)
    2. 如果总长度=列表的总长度,则无法填充窗口
    3. 如果长度< n ,从另一个方向获取节点
  3. 还有其他方法可以做到这一点(这需要保持所有节点的长度),但是通过使用nullNode限制列表,您应该能够避免除了节点不足之外的所有特殊情况对于窗口",并使你的逻辑更清洁。