簡體   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);  

  }
  
}

任務:在本練習中,您將從第 2 周的講座示例中將方法 swapNodes 添加到 SinglyLinkedList class。 這個方法應該交換兩個節點 node1 和 node2(而不僅僅是它們的內容),因為它只引用了 node1 和 node2。 新方法應該檢查node1和node2是否是同一個節點等。編寫main方法來測試swapNodes方法。 提示:您可能需要遍歷列表。

我做了這個方法

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);
      }
      
      
  }
  

然后,創建了一個實例來檢查它是否工作,但它在這里向我顯示一個錯誤swap.swapNodes("2", "5"); 有誰知道是什么問題? 謝謝

它拋出錯誤,因為在您的swapNodes function 中,您希望傳遞兩個類型為Node<E>的參數,但您傳遞的是E (String) 因此,您必須更改 function 的簽名或傳遞您添加到列表中的Node<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);
    }
}

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