当您仅获得对节点的访问权限时,如何删除链接列表中的节点

时间:2016-11-06 23:19:31

标签: java data-structures linked-list

我的理解是,为了删除单链表中的节点,我们需要访问当前节点和前一节点。我有以下逻辑:

public SingleNode delete(int val) {

    SingleNode current = head;
    SingleNode prev = head;

    while(current.data != val) {

        if (current.next == null) {
            return null;
        } else {
            prev = current;
            current = current.next;
        }

    }

    if(current == head) {
        head = current.next;
    } else {
        prev.next = current.next;
    }

    return current;

}

如何更改代码,以便在您只能访问当前节点时可以删除链接列表中的节点?

4 个答案:

答案 0 :(得分:1)

如果只能访问要删除的节点,可以通过将下一个节点的数据和下一个指针设置为当前节点来实现。

public void delete (Node<E> node){
    if (node.next! = null){
        node.data = node.next.data;
        node.next = node.next.next;
    }else{
        node.next = null;
        node.data = null;
    }

}

如果使用sentinel定义的数据结构,那么我们不需要进行空检查,只需更改数据指针和下一个当前指针到下一个

*从手机发送,可能包含拼写错误

<强>更新

以下是Sentinel的部分实现

public class LinkedList<E> {

    private static class Node<E> {
        E element;
        Node<E> next;

        public Node(E element, Node<E> next) {
            this.element = element;
            this.next = next;
        }

        @Override
        public String toString() {
            return "Node [element=" + element + ", next=" + next + "]";
        }

    }

    private int size;
    private Node<E> head; // sentinel
    private Node<E> tail; // sentinel

    public LinkedList() {
        tail = new Node<>(null, null);
        head = new Node<>(null, tail);
    }

    public int size() {
        return this.size;
    }

    public boolean isEmpty() {
        return this.size == 0;
    }

    public Node<E> head() {
        return head.next;
    }

    public Node<E> tail() {
        // TODO
    }

    public void addFirst(E e) {
        addBetween(head, e, head.next);
    }

    public void addLast(E e) {
        // TODO
    }

    public void addBetween(Node<E> prev, E element, Node<E> next) {
        Node<E> curr = new Node<>(element, next);
        prev.next = curr;
        size++;
    }

    public Node<E> node(E e) {
        Node<E> temp = head;
        while (temp != null) {
            if (temp.element == e) {
                return temp;
            }
            temp = temp.next;
        }
        return null;
    }

    public E delete(Node<E> node) {
        E e = node.element;
        node.element = node.next.element;
        node.next = node.next.next;
        return e;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        Node<E> temp = head;
        while (temp != null) {
            sb.append(temp.element + " ");
            temp = temp.next;
        }
        return sb.toString();
    }

    public static void main(String[] args) {
        LinkedList<Integer> ll = new LinkedList<>();
        ll.addFirst(10);
        ll.addFirst(20);
        ll.addFirst(30);
        ll.addFirst(40);
        ll.addFirst(50);
        System.out.println("Linked List :: " + ll);
        Node<Integer> node = ll.node(10);
        System.out.println("Node :: " + node);
        System.out.println("Element :: " + ll.delete(node));
        System.out.println("Final List :: " + ll);
    }
}

输出

Linked List :: null 50 40 30 20 10 null 
Node :: Node [element=10, next=Node [element=null, next=null]]
Element :: 10
Final List :: null 50 40 30 20 null 

答案 1 :(得分:1)

  

如何更改代码,以便在您只能访问当前节点时可以删除链接列表中的节点?

对于单链接列表,除非 上一个节点,否则无法删除具有给定引用的节点,您可以访问列表的头部

如果你有头,你可以在O(N)步骤中找到上一个节点。

有一种方法可以通过修改节点来删除一个在大多数情况下都有效的节点,但是有各种边缘情况会让它变得困难。 (如果你需要支持并发删除和迭代等,它肯定会起作用。)

答案 2 :(得分:0)

struct node *temp  = node_ptr->next;
node_ptr->data  = temp->data;
node_ptr->next  = temp->next;
free(temp);

答案 3 :(得分:0)

void deleteNode(struct node * node_ptr)

{

struct node * temp = node_ptr-&gt; next;

node_ptr-&gt; data = temp-&gt; data;

node_ptr-&gt; next = temp-&gt; next;

自由(温度);

}

上面的函数用一个指针删除节点。 如果要删除的节点是列表的最后一个节点,则该方法不起作用。