简体   繁体   English

使用 java 中的方法交换单链表中的两个节点

[英]swap two nodes in singly linked lists using method in java

package linkedlists;

public class SinglyLinkedList<E> implements Cloneable {
  //---------------- nested Node class ----------------
  /**
   * Node of a singly linked list, which stores a reference to its
   * element and to the subsequent node in the list (or null if this
   * is the last node).
   */
  private static class Node<E> {

    /** The element stored at this node */
    private E element;            // reference to the element stored at this node

    /** A reference to the subsequent node in the list */
    private Node<E> next;         // reference to the subsequent node in the list

    /**
     * Creates a node with the given element and next node.
     *
     * @param e  the element to be stored
     * @param n  reference to a node that should follow the new node
     */
    public Node(E e, Node<E> n) {
      element = e;
      next = n;
    }

    // Accessor methods
    /**
     * Returns the element stored at the node.
     * @return the element stored at the node
     */
    public E getElement() { return element; }

    /**
     * Returns the node that follows this one (or null if no such node).
     * @return the following node
     */
    public Node<E> getNext() { return next; }

    // Modifier methods
    /**
     * Sets the node's next reference to point to Node n.
     * @param n    the node that should follow this one
     */
    public void setNext(Node<E> n) { next = n; }
    
  } //----------- end of nested Node class -----------

  // instance variables of the SinglyLinkedList
  /** The head node of the list */
  private Node<E> head = null;               // head node of the list (or null if empty)

  /** The last node of the list */
  private Node<E> tail = null;               // last node of the list (or null if empty)

  /** Number of nodes in the list */
  private int size = 0;                      // number of nodes in the list

  /** Constructs an initially empty list. */
  public SinglyLinkedList() { }              // constructs an initially empty list

  // access methods
  /**
   * Returns the number of elements in the linked list.
   * @return number of elements in the linked list
   */
  public int size() { return size; }

  /**
   * Tests whether the linked list is empty.
   * @return true if the linked list is empty, false otherwise
   */
  public boolean isEmpty() { return size == 0; }

  /**
   * Returns (but does not remove) the first element of the list
   * @return element at the front of the list (or null if empty)
   */
  public E first() {             // returns (but does not remove) the first element
    if (isEmpty()) return null;
    return head.getElement();
  }

  /**
   * Returns (but does not remove) the last element of the list.
   * @return element at the end of the list (or null if empty)
   */
  public E last() {              // returns (but does not remove) the last element
    if (isEmpty()) return null;
    return tail.getElement();
  }

  // update methods
  /**
   * Adds an element to the front of the list.
   * @param e  the new element to add
   */
  public void addFirst(E e) {                // adds element e to the front of the list
    head = new Node<>(e, head);              // create and link a new node
    if (size == 0)
      tail = head;                           // special case: new node becomes tail also
    size++;
  }

  /**
   * Adds an element to the end of the list.
   * @param e  the new element to add
   */
  public void addLast(E e) {                 // adds element e to the end of the list
    Node<E> newest = new Node<>(e, null);    // node will eventually be the tail
    if (isEmpty())
      head = newest;                         // special case: previously empty list
    else
      tail.setNext(newest);                  // new node after existing tail
    tail = newest;                           // new node becomes the tail
    size++;
  }

  /**
   * Removes and returns the first element of the list.
   * @return the removed element (or null if empty)
   */
  public E removeFirst() {                   // removes and returns the first element
    if (isEmpty()) return null;              // nothing to remove
    E answer = head.getElement();
    head = head.getNext();                   // will become null if list had only one node
    size--;
    if (size == 0)
      tail = null;                           // special case as list is now empty
    return answer;
  }

  @SuppressWarnings({"unchecked"})
  public boolean equals(Object o) {
    if (o == null) return false;
    if (getClass() != o.getClass()) return false;
    SinglyLinkedList other = (SinglyLinkedList) o;   // use nonparameterized type
    if (size != other.size) return false;
    Node walkA = head;                               // traverse the primary list
    Node walkB = other.head;                         // traverse the secondary list
    while (walkA != null) {
      if (!walkA.getElement().equals(walkB.getElement())) return false; //mismatch
      walkA = walkA.getNext();
      walkB = walkB.getNext();
    }
    return true;   // if we reach this, everything matched successfully
  }

  @SuppressWarnings({"unchecked"})
  public SinglyLinkedList<E> clone() throws CloneNotSupportedException {
    // always use inherited Object.clone() to create the initial copy
    SinglyLinkedList<E> other = (SinglyLinkedList<E>) super.clone(); // safe cast
    if (size > 0) {                    // we need independent chain of nodes
      other.head = new Node<>(head.getElement(), null);
      Node<E> walk = head.getNext();      // walk through remainder of original list
      Node<E> otherTail = other.head;     // remember most recently created node
      while (walk != null) {              // make a new node storing same element
        Node<E> newest = new Node<>(walk.getElement(), null);
        otherTail.setNext(newest);     // link previous node to this one
        otherTail = newest;
        walk = walk.getNext();
      }
    }
    return other;
  }

  public int hashCode() {
    int h = 0;
    for (Node walk=head; walk != null; walk = walk.getNext()) {
      h ^= walk.getElement().hashCode();      // bitwise exclusive-or with element's code
      h = (h << 5) | (h >>> 27);              // 5-bit cyclic shift of composite code
    }
    return h;
  }

  /**
   * Produces a string representation of the contents of the list.
   * This exists for debugging purposes only.
   */
  public String toString() {
    StringBuilder sb = new StringBuilder("(");
    Node<E> walk = head;
    while (walk != null) {
      sb.append(walk.getElement());
      if (walk != tail)
        sb.append(", ");
      walk = walk.getNext();
    }
    sb.append(")");
    return sb.toString();
  }
  
  public void swapNodes(Node<E> num1, Node<E> num2) {
      
      Node<E> num1Prev = this.head;
      Node<E> num2Prev = this.head;
      
      if (num1 == num2 ) 
          return ;
      
      while((num1Prev != null)&&(num1Prev.getNext() != num1)){
          
          num1Prev = num1Prev.getNext();
      }
      
      while((num2Prev != null)&&(num2Prev.getNext() != num2)){
          
          num2Prev = num2Prev.getNext();
      }
      
      if(num2Prev == num1) {
          
          num1.setNext(num2.getNext());
          num2.setNext(num1);
          num1Prev.setNext(num2);
      }
      else if(num1Prev == num2) {
          num2.setNext(num1.getNext());
          num1.setNext(num2);
          num2Prev.setNext(num1);
      }
      else {
          Node<E> tmp = num1.getNext();
          num1.setNext(num2.getNext());
          num2.setNext(tmp);
          
          num1Prev.setNext(num2);
          num2Prev.setNext(num1);
      }
      
      
  }
  
  
  
  //main method
  public static void main(String[] args)
  {
      
      SinglyLinkedList<String> list = new SinglyLinkedList<String>();
      list.addFirst("MSP");
      list.addLast("ATL");
      list.addLast("BOS");
      //
      list.addFirst("LAX");
      System.out.println(list);
      //
      
      SinglyLinkedList<String> swap = new SinglyLinkedList<String>();
      swap.addFirst("1");
      swap.addLast("2");
      swap.addLast("3");
      swap.addLast("4");
      swap.addLast("5");
      
      System.out.println("Original list: " + swap);  

      swap.swapNodes("2","5");
      
      System.out.println("After Swapping list: " + swap);  

  }
  
}

Task: In this exercise, you will add a method swapNodes to SinglyLinkedList class from week 2 lecture examples.任务:在本练习中,您将从第 2 周的讲座示例中将方法 swapNodes 添加到 SinglyLinkedList class。 This method should swap two nodes node1 and node2 (and not just their contents) given references only to node1 and node2.这个方法应该交换两个节点 node1 和 node2(而不仅仅是它们的内容),因为它只引用了 node1 和 node2。 The new method should check if node1 and node2 are the same nodes, etc. Write the main method to test the swapNodes method.新方法应该检查node1和node2是否是同一个节点等。编写main方法来测试swapNodes方法。 Hint: You may need to traverse the list.提示:您可能需要遍历列表。

I made this method我做了这个方法

public void swapNodes(Node<E> num1, Node<E> num2) {
      
      Node<E> num1Prev = this.head;
      Node<E> num2Prev = this.head;
      
      if (num1 == num2 ) 
          return ;
      
      while((num1Prev != null)&&(num1Prev.getNext() != num1)){
          
          num1Prev = num1Prev.getNext();
      }
      
      while((num2Prev != null)&&(num2Prev.getNext() != num2)){
          
          num2Prev = num2Prev.getNext();
      }
      
      if(num2Prev == num1) {
          
          num1.setNext(num2.getNext());
          num2.setNext(num1);
          num1Prev.setNext(num2);
      }
      else if(num1Prev == num2) {
          num2.setNext(num1.getNext());
          num1.setNext(num2);
          num2Prev.setNext(num1);
      }
      else {
          Node<E> tmp = num1.getNext();
          num1.setNext(num2.getNext());
          num2.setNext(tmp);
          
          num1Prev.setNext(num2);
          num2Prev.setNext(num1);
      }
      
      
  }
  

And then, created an instance to check if it's work, but it is showing me an error on here swap.swapNodes("2", "5");然后,创建了一个实例来检查它是否工作,但它在这里向我显示一个错误swap.swapNodes("2", "5"); Does anyone know what is the problem?有谁知道是什么问题? Thank you谢谢

It's throwing error, because in your swapNodes function, you expect two parameters of type Node<E> passed, but you are passing E (String) .它抛出错误,因为在您的swapNodes function 中,您希望传递两个类型为Node<E>的参数,但您传递的是E (String) So you have to change signature of the function or pass Node<E> that you added to your List.因此,您必须更改 function 的签名或传递您添加到列表中的Node<E>

Here's how you could do your swapNodes function with parameters of type E :以下是使用E类型参数执行swapNodes function 的方法:

public void swapNodes(E element1, E element2) {
    if (element1 == element2 || element1 == null || element2 == null || isEmpty()) return;
    Node<E> num1 = findNode(element1);
    Node<E> num2 = findNode(element2);
    if (num1 == null || num2 == null) return;
    Node<E> num1Prev = this.head;
    Node<E> num2Prev = this.head;
  
    while(num1Prev != null && num1Prev.getNext() != num1){
        num1Prev = num1Prev.getNext();
    }
    while(num2Prev != null && num2Prev.getNext() != num2){
        num2Prev = num2Prev.getNext();
    }
    if (num1Prev.getNext() == null || num2Prev.getNext() == null) return;
  
    if (num2Prev.equals(num1)) {
        num1.setNext(num2.getNext());
        num2.setNext(num1);
        num1Prev.setNext(num2;
    } else if (num1Prev.equals(num2)) {
        num2.setNext(num1.getNext());
        num1.setNext(num2);
        num2Prev.setNext(num1);
    } else {
        Node<E> tmp = num1.getNext();
        num1.setNext(num2.getNext());
        num2.setNext(tmp);
        num1Prev.setNext(num2);
        num2Prev.setNext(num1);
    }
}

The findNode function could look like this: findNode function 可能如下所示:

public Node<E> findNode(E element) {
    if (isEmpty()) return null;
    Node<E> node = this.head;
    while(node != null) {
        if (node.getElement() == element) return node;
    }
    return null;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM