【问题标题】:Doubly Circular Linked List双循环链表
【发布时间】:2017-05-28 10:02:17
【问题描述】:

我创建了一个双向循环链表。

我需要知道每个节点到头的距离。

因为当我必须删除或获取具有特定键的节点时,如果两个节点具有相同的键和相同的距离,则必须删除或获取,否则必须删除离头最近的节点。

我不知道如何计算距离,因为是圆形的......

这个链表的插入就是这样工作的。

所有节点都在头部之后。

例子:

1) 头部

2) Head-A(插入 A)

3) Head-B-A(插入 B)

4) Head-C-B-A(插入 C)

目前,我只进行了没有距离的正常取消。 这是我的代码。

/* Function to delete node with the key  */
public void deleteWithKey(int key) {
    if (key == head.getData()) {
        if (size == 1) {
            head = null;
            end = null;
            size = 0;
            return;
        }
        head = head.getLinkNext();
        head.setLinkPrev(end);
        end.setLinkNext(head);
        size--;
        return;
    }
    if (key == end.getData()) {
        end = end.getLinkPrev();
        end.setLinkNext(head);
        head.setLinkPrev(end);
        size--;
    }
    Node current = head.getLinkNext();
    for (int i = 2; i < size; i++) {
        if (key == current.getData()) {
            Node p = current.getLinkPrev();
            Node n = current.getLinkNext();

            p.setLinkNext(n);
            n.setLinkPrev(p);
            size--;
            return;
        }
        current = current.getLinkNext();
    }
    System.out.println("Don't exist a node with this key");
}

谢谢大家。

【问题讨论】:

  • 为什么计算距离有问题?
  • 因为是循环的。每个节点都链接到左右。我需要知道头部到每个节点的距离。
  • 示例:我有一个列表 Head-B-A , B 和 A 的距离相同。因为 A 链接到 Head。将是 AHeadBA
  • 其他示例:Head-D-C-B-A 。 C 和 B 具有相同的距离,因为 Head-D-C(距离 2)。 B-A-Head(距离 2)
  • 我认为你错过了“head”和“A”之间的“end”节点

标签: java list distance doubly-linked-list circular-list


【解决方案1】:

您实际上不需要知道距离。相反,您需要找到最接近头部的位置

因为它是一个循环双向链表,所以这个任务很简单:

  1. 定义两个变量ab,都初始化为head
  2. 如果其中一个是目标,则删除匹配的节点并退出
  3. 分配a = a.nextb = b.previous
  4. 转到 2

【讨论】:

  • 对。我没有多想。我喜欢这个解决方案。我测试很快。
【解决方案2】:

这是我能想到的解决问题的伪代码。

给定head

// no data
if(head==null) return;
// next and prev are always at same distance
next = head;
prev = head.prev;

// ensure nodes are not same or crossed half way through the list
while (next == prev || next.prev == prev){
// delete nodes if values are same
if (next.val == prev.val){
    if(next!=head) {
        next.prev.next = next.next;
        next.next.prev = next.prev;
        prev.prev.next = prev.next;
        prev.next.prev = prev.prev;
    }
    // list has only two nodes
    else if(head.next==prev){
        head = null;
        return;
    // remove head and its prev node
    else{
        head = head.next;
        head.prev = prev.next;
        head.prev.next = head
    }
}
// traverse through the list
next = next.next
prev = prev.prev
}

【讨论】:

  • Node类的next和prev参数帮助我们滚动节点
  • (项目的正文)说头是插入的第一个节点,结尾总是插入模式的第二个节点。
  • 它们是数据节点。您应该保留两个指向这些数据节点的空指针以简化您的 impl 代码
  • 我已经更新了代码,因为你正在尝试实现它。看看代码现在看起来有多复杂!
  • 您不应该保留除“head”之外的任何变量。无论如何,这是一个微不足道的问题。
【解决方案3】:

这是我完成的最终工作代码。

你有改进吗?

感谢大家的帮助。

复杂度 = O(n)

/* Function to delete node with the key */
public void deleteWithKey(int key) {
    if (key == head.getData()) {
        if (size == 1) {
            head = null;
            end = null;
            size = 0;
            return;
        }
        head = head.getLinkNext();
        head.setLinkPrev(end);
        end.setLinkNext(head);
        size--;
        return;
    }
    if (key == end.getData()) {
        end = end.getLinkPrev();
        end.setLinkNext(head);
        head.setLinkPrev(end);
        size--;
    }
    Node next = head;
    Node back = head;
    while (next != end) {
        next = next.getLinkNext();
        back = back.getLinkPrev();
        if ((key == next.getData()) && (key == back.getData()) && (next != back)) {
            Node p = next.getLinkPrev();
            Node n = next.getLinkNext();
            Node p1 = back.getLinkPrev();
            Node n1 = next.getLinkNext();
            p.setLinkNext(n);
            n.setLinkPrev(p);
            p1.setLinkPrev(n1);
            n1.setLinkPrev(p1);
            size -= 2;
            return;
        }

        if ((key == next.getData()) && (next != back)) {
            Node p = next.getLinkPrev();
            Node n = next.getLinkNext();
            p.setLinkNext(n);
            n.setLinkPrev(p);
            size--;
            return;
        }
        if ((key == next.getData()) && (next == back)) {
            Node p = next.getLinkPrev();
            Node n = next.getLinkNext();
            p.setLinkNext(n);
            n.setLinkPrev(p);
            size--;
            return;
        }
    }
    System.out.println("Don't exist a node with this key");
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-15
    • 2020-12-03
    • 1970-01-01
    相关资源
    最近更新 更多