菜单项的双重链接列表

时间:2014-07-06 22:01:58

标签: java doubly-linked-list

我有一个使用linkedList数据结构处理菜单项(和子菜单项)的程序。我的程序工作除了delete函数,如果删除在现有元素之前插入的元素,但是如果在现有元素之后插入元素,则该函数不起作用。任何建议都非常感谢!这是插入功能

public Item insert(String newElem, String existingElem, int key) {
    // search for given existing element starting at head
    currentNode = new Item("");
    currentNode = head;
    while (!currentNode.element.equals(existingElem)) {
        currentNode = currentNode.next;
        if (currentNode == null)
            break; // cannot find the given key
    }
    // create a new node
    newNode = new Item(newElem);
    if (key == 1) // if key = 1 insert after the existing element
    {
        newNode.next = currentNode.next;
        newNode.prev = currentNode;
        currentNode.next = newNode;
        tail = newNode;
        tail.next = null;
        counter++;
    }
    if (key == 2) // if key = 2 insert before the existing element
    {
        newNode.next = currentNode;
        newNode.prev = currentNode.prev;
        currentNode.prev = newNode;
        head = newNode;
        head.prev = null;
        counter++;
    }
    return newNode;
}

我也意识到我只假设一个现有元素,但是,如果我可以使删除功能更通用,那么它将是最好的,我不想将该功能分成多个功能!这是删除功能: -

public Item delete(String elem) {
    // search for given existing element starting at head
    currentNode = new Item("");
    currentNode = head;
    while (!currentNode.element.equals(elem)) {
        currentNode = currentNode.next;
        if (currentNode == null)
            break; // cannot find the given key
    }
    // check if element is the first element
    if (currentNode == head) {
    head = currentNode.next;
    } else {
        currentNode.prev = currentNode.next;
    }
    // check if element is the last element
    if (currentNode == tail) {
        tail = currentNode.prev;
    } else {
        currentNode = currentNode.prev;
    }
    return currentNode;
}

1 个答案:

答案 0 :(得分:2)

<强>问题

每次插入新节点时,都不应更新tailhead。你应该只在列表的开头或结尾插入,如果你不在列表的开头,你还需要更新以前/之后的元素的上一个/下一个元素插入旁边:

if (key == 1) // if key = 1 insert after the existing element
{
    newNode.next = currentNode.next;
    newNode.prev = currentNode;
    currentNode.next = newNode;
    if (newNode.next == null)
        tail = newNode;
    else
        newNode.next.prev = newNode;
}
else if (key == 2) // if key = 2 insert before the existing element
{
    newNode.next = currentNode;
    newNode.prev = currentNode.prev;
    currentNode.prev = newNode;
    if (newNode.prev == null)
        head = newNode;
    else
        newNode.prev.next = newNode;
}

注意:我还使用了 else if 语句,而不是两个 if

您的删除功能也需要更新。您没有更新周围的节点,只是要删除的节点:

if (currentNode.prev == null) { // is head 
    head = currentNode.next;
} else {
    currentNode.prev.next = currentNode.next;
}
if (currentNode.next == null) { // is tail
    tail = currentNode.prev;
} else {
    currentNode.next.prev = currentNode.prev;
}

其他评论

通过值搜索节点插入前后似乎很不寻常,如果我有这样的列表怎么样:[1,2,2,2,3]?在该列表中的几个位置插入值是不可能的。当然,您的API应基于Item s:

public Item insert(String newValue, Item existingItem, int key);
public Item delete(Item item);

或者指标:

public Item insert(String newValue, int index, int key);
public Item delete(int index);

然后,您可以使用另一种方法查找特定值的Item或索引:

public Item find(String value);

或者:

public int indexOf(String value);

并像这样使用它们来获得相当于你的方法:

list.insert("value", list.find("other value"), 1);

您可能需要考虑将insert方法更改为insertBeforeinsertAfter方法,或者至少将key参数更改为枚举类型:

public enum Position {
    BEFORE,
    AFTER,
}

毕竟,key为0或23时会发生什么?


您目前有currentItem作为班级成员,它应该是该函数的局部变量(毕竟,它在这些函数之外有什么用途),而且您也不需要要将其初始化为新元素,只需将其直接设置为head

public Item insert(String newElem, String existingElem, int key) {
    Item currentNode = head;
    ...
}

最后,如果列表中没有项目,则搜索代码不起作用。如果NullPointerException为空,则以下行将失败并显示head

while (!currentNode.element.equals(existingElem))

因为您无法在空引用上调用.equals(...)