如何删除链表中的多次出现?

时间:2019-02-16 19:32:48

标签: java

我相信我有关于如何删除链表中项目的代码,但是我不确定如何做到这一点,以便将所有出现的值都删除。我需要在哪里进行一些更改以检查列表中的所有值?

我试图做一个备用或假人指向头部,但是我不确定该去哪里。

public class LinkList {

private Link first;            // ref to first link on list

// -------------------------------------------------------------
public LinkList() // constructor
{
    first = null;               // no links on list yet
}
// -------------------------------------------------------------

public void insertFirst(int id, double dd) {                           
    Link newLink = new Link(id, dd);
    newLink.next = first;       // it points to old first link
    first = newLink;            // now first points to this
}
// -------------------------------------------------------------

public Link find(int key) // find link with given key
{                           // (assumes non-empty list)
    Link current = first;              // start at 'first'
    while (current.iData != key) // while no match,
    {
        if (current.next == null) // if end of list,
        {
            return null;                 // didn't find it
        } else // not end of list,
        {
            current = current.next;      // go to next link
        }
    }
    return current;                    // found it
}

// -------------------------------------------------------------
public void displayList() // display the list
{
    System.out.print("List (first-->last): ");
    Link current = first;       // start at beginning of list
    while (current != null) // until end of list,
    {
        current.displayLink();   // print data
        current = current.next;  // move to next link
    }
    System.out.println("");
}
// -------------------------------------------------------------
public Link removeAll(int n) // delete link with given key
{                           // (assumes non-empty list)
    Link current = first;              // search for link
    Link previous = first;

    while (current.iData != n) {
        if (current.next == null) {
            return null;                 // didn't find it
        } else {
            previous = current;          // go to next link
            current = current.next;
        }
    }
    if (current == first) // if first link,
    {
        first = first.next;             //    change first
    } else // otherwise,
    {
        previous.next = current.next;   //    bypass it
    }
    return current;
  }
} 

我希望删除给定键的所有值,但是我只能删除给定值的一个实例。

4 个答案:

答案 0 :(得分:0)

这将删除sess.run中所有出现的for e in range(epochs): for _ in range(batches): _, loss_ = sess.run([training_op, loss]) losses.append(loss_) 。如果要通过Link删除,则应该相同。

id == n

像这样运行代码:

Link.iData

输出:

public Link removeAll(int n)
{
    Link head = first;
    Link previous = null;
    Link current = first;

    while (current != null) {
        if (current.id == n) {
            if (previous == null) {
                head = current.next;
            } else {
                previous.next = current.next;
            }
        } else {
            previous = current; // if we removed current, let previous remain the same
        }
        current = current.next;
    }
    first = head;
    return head;
}

答案 1 :(得分:0)

我有一个叫ListNode的课程,类似于您的课程。

public class ListNode {

    public ListNode next;
    public int val;

    public ListNode removeAll(int n) {
        ListNode newHead = null;
        ListNode node = this;

        //for keeping track of the node previous to the current node
        ListNode prev = null;
        //loop through the entire linked list
        while (node != null) {

            //when you encounter the val == n, delete the node
            if (node.val == n) {

                if (prev != null){
                    //this makes the previous node to point the node to the next of the current node
                    //if 2 -> 1 -> 3 and we have to remove node with key 1 and current node val == 1
                    // the following code will do this
                    // 2 -> 3
                    prev.next = node.next;
                }

                ListNode next = node.next;
                //taking the same example
                //this code will break the link : 1->3
                node.next = null;
                node = next;
            } else {
                if (newHead == null) {
                    newHead = node;
                }
                prev = node;
                node = node.next;
            }
        }
        return newHead;
    }
}

基本上,您必须遍历整个链表,跟踪当前节点的前一个节点,当您发现一个值/键/数据等于n的节点时,则使前一个节点指向下一个节点当前节点的节点,并断开当前节点到下一个节点的链接。

答案 2 :(得分:0)

我们先删除所有内容。要删除所有出现的内容,您首先需要能够遍历整个列表(以便您可以查找多个匹配项)。遍历整个列表将只是:

public void removeAll(int n) // delete link with given key
{
    Link current = first;
    Link previous = first;

    while (current != null)
    {
        // simply move to the next Link
        previous = current; // store the current node as the previous for the next iteration
        current = current.next; // move to the next link
    }
} 

接下来,让我们添加一个检查以查看当前链接是否为应删除的链接:

public void removeAll(int n) // delete link with given key
{
    Link current = first;
    Link previous = first;

    while (current != null)
    {
        if (current.iData == n)
        {   
            // To do...delete the current Link
        }
        else
        {
            // simply move to the next Link
            previous = current; // store the current node as the previous for the next iteration
            current = current.next; // move to the next link
        }       
    }
} 

一旦找到匹配项,就有两种可能性。链接是第一个链接,或者在列表中更远的位置:

  • 如果链接是第一个,则将当前移动到下一个链接,并将第一个和上一个指向新的当前链接。
  • 如果我们不是第一个链接,则将当前移动到下一个链接,并更新上一个.next字段以指向新的当前链接(从而跳过要删除的链接)。

这是更新的代码:

public void removeAll(int n) // delete link with given key
{
    Link current = first;
    Link previous = first;

    while (current != null)
    {
        if (current.iData == n)
        {   
            if (current == first)
            {       
                current = current.next;
                first = current;
                previous = current;
            }
            else
            {
                current = current.next;
                previous.next = current;            
            }
        }
        else
        {
            // simply move to the next Link
            previous = current;
            current = current.next;
        }       
    }
}

答案 3 :(得分:0)

这是简单的递归实现(此实现保留了初始列表的完整性,并创建了没有指定元素的新列表):

{{1}}