链表的删除和insertAfter方法

huangapple go评论88阅读模式
英文:

Linked List Delete and insertAfter Method

问题

我遇到了删除和insertAfter方法的问题,这些方法用于执行操作并返回操作是否成功(true)的布尔值,否则为(false)。insertAfter方法将始终在相同的位置插入一个字符串,而Delete方法将始终删除相同的节点。

private class StrNode {

        String data;
        StrNode next;
    }

    private StrNode head;   // 单向链表的头部

    public StringList() {
        head = null;
    }

public void prepend(String s) {															
        var newNode = new StrNode();
        // TODO: 在列表开头添加一个项目		
        newNode.data = s;
        if(head == null) {
        	head = newNode;
        }
        else {
        newNode.next = head;
		head = newNode;
        }
        
    }

/**
     * 如果键存在,则在第一个键的实例之后插入一个项目。
     *
     * @param s 要插入的项目
     * @param key 要在其后插入项目的列表中的项目
     * @return 插入是否成功
     */
    public boolean insertAfter(String s, String key) {															
        // TODO: 如果键存在,则在第一个键的实例之后插入一个项目
    	var newNode = new StrNode();
    	StrNode current = head;
    	newNode.data = s;
    	
    	if(head == null) {
    		head = newNode;
    	}
    	else if(current == newNode.next){
    		current.next = newNode;
    		current = newNode;

    	}
    	else {
    		newNode.next = current.next;
    		current.next = newNode;
    	}
    	
    	
    	return false;
    }
    
    /**
     * 从列表中删除第一个项目的实例。
     *
     * @param key 要从列表中删除的项目的值。
     * @return 删除是否成功。
     */
    public boolean delete(String key) {															
        // TODO: 从列表中删除第一个项目的实例
    	StrNode current = head;
    	StrNode sucNode = current;
    	
    	if(current == null) {
    		sucNode = head.next;
    		head = sucNode;
    		return true;
    	}
    	else if(current.next != null) {
    		sucNode = current.next.next;
    		current.next = sucNode;
    		return true;
    	}

    	return false;
    }

我想在主方法中将“four”插入到“three”之后,应该是:three, two, four, one。
但我得到的是:three, four, two, one。

delete方法只删除了“four”,实际上应该是:three, four, two。
但我得到的是:three, two, one。

主方法:

public static void main(String[] args) {
    	
    	StringList s = new StringList();
    	
    	s.prepend("one");
    	s.prepend("two");
    	s.prepend("three");
        System.out.println(s);
    	
    	s.insertAfter("four", "three");
    	System.out.println(s);
    	
    	System.out.println(s.delete("one"));
    	System.out.println(s);
        
        
    }
英文:

I am having trouble with delete and insertAfter methods, the methods are to perform the action and return a boolean if the action was a success(true) or not(false). The InsertAfter method will insert a string but always in the same spot, and Delete method will always delete the same node.

private class StrNode {

        String data;
        StrNode next;
    }

    private StrNode head;   // the head of the singly-linked list.

    public StringList() {
        head = null;
    }

public void prepend(String s) {															
        var newNode = new StrNode();
        // TODO: Adds an item to the start of the list.		
        newNode.data = s;
        if(head == null) {
        	head = newNode;
        }
        else {
        newNode.next = head;
		head = newNode;
        }
        
    }

/**
     * Inserts an item after the first instance of a key if the key exists.
     *
     * @param s the item to insert
     * @param key the item in the list to insert after
     * @return whether the insertion was successful
     */
    public boolean insertAfter(String s, String key) {														
        // TODO: 	Inserts an item after the first instance of a key if the key exists.
    	var newNode = new StrNode();
    	StrNode current = head;
    	newNode.data = s;
    	
    	if(head == null) {
    		head = newNode;
    	}
    	else if(current == newNode.next){
    		current.next = newNode;
    		current = newNode;

    	}
    	else {
    		newNode.next = current.next;
    		current.next = newNode;
    	}
    	
    	
    	return false;
    }
    
    /**
     * Deletes the first instance of an item from the list.
     *
     * @param key the value of the item to delete from the list.
     * @return whether the deletion was successful.
     */
    public boolean delete(String key) {														
        // TODO:	Deletes the first instance of an item from the list.
    	StrNode current = head;
    	StrNode sucNode = current;
    	
    	if(current == null) {
    		sucNode = head.next;
    		head = sucNode;
    		return true;
    	}
    	else if(current.next != null) {
    		sucNode = current.next.next;
    		current.next = sucNode;
    		return true;
    	}

    	return false;
    }

the main method I am wanting to insert four after three which should be: three, two, four, one.
but I get: three, four, two, one

the delete method just deletes the four which should actually look like: three, four, two
but I get: three, two, one
main:

public static void main(String[] args) {
    	
    	StringList s = new StringList();
    	
    	s.prepend("one");
    	s.prepend("two");
    	s.prepend("three");
        System.out.println(s);
    	
    	s.insertAfter("four", "three");
    	System.out.println(s);
    	
    	System.out.println(s.delete("one"));
    	System.out.println(s);
        
        
    }

答案1

得分: 1

以下是翻译好的内容:

insertAfter

一些问题:

  • 你没有使用参数 key
  • 如果 head 为空,你永远无法满足在具有关键字的节点之后插入节点的条件,因此在这种情况下应该返回 false。
  • current 被初始化为 head,因此在没有检查 key 是否匹配的情况下,你将新节点赋值给了 head.next...
  • 你总是返回 false,从未返回过 true

你应该通过遍历列表来查找给定的关键字:

public boolean insertAfter(String s, String key) {
    // 如果关键字存在,则在第一个关键字的实例之后插入项。
    StrNode current = head;
    
    while (current != null) {
        if (current.data == key) { // 找到插入位置
            var newNode = new StrNode();
            newNode.data = s;
            newNode.next = current.next;
            current.next = newNode;
            return true;
        }
        current = current.next; // 需要沿着列表走
    }
    return false; // 没找到关键字
}

delete

  • 你没有使用参数 key
  • 如果 head(是 current)为空,你永远无法满足删除节点应该具有给定关键字的条件,因此在这种情况下应该返回 false。
  • 在其他情况下,你总是删除第二个节点而没有检查 key 是否匹配...

修正后:

public boolean delete(String key) {                                                     
    // 从列表中删除第一个实例项。
    StrNode current = head;
    if (head == null) return false;
    if (head.data == key) {
         head = head.next;
         return true;
    }

    while (current.next != null) {
        if (current.next.data == key) { // 找到了
            current.next = current.next.next; // 删除它
            return true;
        }
        current = current.next; // 需要沿着列表走
    }
    return false; // 没找到
}

关于 prepend 的备注:

你不需要这个 if 语句。在 else 块中的代码在 head 为空时也能正常工作,所以你的代码可以简化为:

public void prepend(String s) { 
    // 将项添加到列表的开头。
    StrNode node = new StrNode();
    node.data = s;
    node.next = head;
    head = node;
}
英文:

You asked about two methods:

insertAfter

Some issues:

  • You don't use the argument key.
  • In case head is null, you can never satisfy the condition that the node should be inserted after a node with a key, so in that case you should return false.
  • current is initialised as head, so you are assigning the new node to head.next without checking the key matches...
  • You always return false, never true

You should look for the given key by iterating over the list:

public boolean insertAfter(String s, String key) {
    // Inserts an item after the first instance of a key if the key exists.
    StrNode current = head;
    
    while (current != null) {
        if (current.data == key) { // found the insertion spot
            var newNode = new StrNode();
            newNode.data = s;
            newNode.next = current.next;
            current.next = newNode;
            return true;
        }
        current = current.next; // need to walk along the list
    }
    return false; // didn't find the key
}

delete

  • You don't use the argument key.
  • In case head (is current) is null, you can never satisfy the condition that the node to delete should have the given key, so in that case you should return false.
  • In the other case, you are always deleting the second node without checking the key matches...

Corrected:

public boolean delete(String key) {                                                     
    // Deletes the first instance of an item from the list.
    StrNode current = head;
    if (head == null) return false;
    if (head.data == key) {
         head = head.next;
         return true;
    }

    while (current.next != null) {
        if (current.next.data == key) { // found it
            current.next = current.next.next; // delete it
            return true;
        }
        current = current.next; // need to walk along the list
    }
    return false; // not found
}

Remark about prepend:

You don't need the if statement. The code in the else block works fine when head is null, so your code can just be:

public void prepend(String s) { 
    // Adds an item to the start of the list. 
    StrNode node = new StrNode();
    node.data = s;
    node.next = head;
    head = node;
}

huangapple
  • 本文由 发表于 2020年10月27日 03:10:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/64543535.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定