简体   繁体   中英

Sorted Insert into Singly Linked List from scratch

I have been trying to create a sorted linked list from scratch that takes only strings, but sorts it upon insertion. Here is my current code:

import java.util.Arrays;

public class SortedLinkedList {

    private StringNode head = null;

    /**
     * Default Constructor for a sorted linked list
     */
    public SortedLinkedList() {}

    /**
     * Will add a new node with the specified data to the correctly sorted 
     * position in the list
     */
    public void add(String data) {

        if (head == null) {
            head = new StringNode(data);
        }

        StringNode temp = new StringNode(data);
        StringNode current = head;

        if (current != null) {
            while (current.getNext() != null) {
                if (current.getData().toString().compareTo(current.getNext().getData().toString()) < 0) {
                    temp.setNext(current.getNext());
                    current.setNext(temp);
                } else
                    current.setNext(temp);
            }
        }
    }

    /**
     * Will remove the node that matches the specified data from the list.
     * Returns true if node is found, otherwise will return false
     */
    public boolean remove(String data) {
        StringNode current = head;

        if (head != null) {

            while (current.getNext() != null) {

                if (current.getData().toString().equals(data)) {
                    current.setNext(current.getNext().getNext());
                    return true;
                }

                current = current.getNext();
            }
        }
        return false;
    }

    /**
     * Will cycle through the list and display each item on a new line
     */
    public void display() {

        if (head != null) {

            StringNode current = head.getNext();
            System.out.print("[");

            while (current.getNext() != null) {
                System.out.print(current.getData().toString() + ", ");
                current = current.getNext();
            }

            System.out.print("]");
        }
    }

    // Inner Class 

    class StringNode {

        String data;
        StringNode next;

        public StringNode(String nodeData) {
            next = null;
            data = nodeData;
        }

        /**
         * Getter of Data
         */
        public String getData() {
            return data;
        }

        /**
         * Getter of Next
         */
        public StringNode getNext() {
            return next;
        }

        /**
         * Setter of Data
         */
        public void setData(String newData) {
            data = newData;
        }

        /**
         * Setter of Next
         */
        public void setNext(StringNode nextNode) {
            next = nextNode;
        }
    }

}

Ive been able to add without insertion sorting, however, after I tried to code in insertion coding it broke. It seems like it no longer adds any values. My current output from my driver:

public class Driver {
    public static void main(String[] args) {
        SortedLinkedList name = new SortedLinkedList();

        name.add("v");
        name.add("a");
        name.add("b");

        name.display();
    }
}

Is a null pointer exception in my display method, line 70, which is the creation of my while loop. I am completely lost and need some guidance. Thanks.

You actually want to check if current == null, since the .getNext() of the last element is null.

while (current != null)

refactoring a bit:

// should print [] for empty SLL; no dangling comma
public void display() {

  String out = "[";
  StringNode current = head;

  while(current != null) {
      out = out + current.getData();
      current = current.getNext();
      if (current != null)
        out = out + ", ";
  }
  out += "]";
  System.out.print(out);
}

EDIT: additionally, your add/remove methods need to be reworked... try going through the algorithm step-by-step on paper, and then translating the conditions/actions to Java.

Example:

/**
 * Will add a new node with the specified data to the correctly sorted 
 * position in the list
 */
public void add(String data) {
  StringNode temp = new StringNode(data);

  if(head == null) {
      head = temp;
      return; // only adding one node
  }

  StringNode previous = head;

  if (data.compareTo(previous.getData()) < 0) {
     head = temp; // temp < head, so we add it to the beginning
     head.setNext(previous);
     return; // done
  }

  StringNode current = previous.getNext();

  while (current != null) {
      if (data.compareTo(current.getData()) < 0) {
          temp.setNext(current);
          previous.setNext(temp);
          return; // done
      } else {
          previous = current;
          current = previous.getNext();
      }
  }
  // current == null, so we reached the end of the list;
  previous.setNext(temp);
}

I have refactored your code a bit and removed the code comments you wrote. Instead I have added a few comments of my own.

Please go through these comments and consider writing unit tests for any code you write. It will help you catch any bugs and will give you confidence about the code being shipped.

package com.so36046948;

public class SortedLinkedList {

  private StringNode head = null;

  public SortedLinkedList() {}

  public void add(String data) {
    // Do null checks on Data.
    if (head == null) {
      // If we have no head, set head and return immediately.
      head = new StringNode(data, null);
      return;
    }

    StringNode previous = head;
    StringNode current = head;
    StringNode temp = new StringNode(data);

    // Continue iterating till we reach the end of the list.
    while (null != current) {

      if (current.getData().compareTo(data) < 0) {
        if (current == head) {
          // Special handling for the case when the element being inserted is greater than head.
          head = temp;
          temp.setNext(current);
          return;
        }
        break;
      }
      previous = current;
      current = current.getNext();
    }

    // Break out of the while loop and reset the next pointers. Previous points to immediate 
    // greater element and current points to immediate element that is less than *data* being
    // inserted.
    previous.setNext(temp);
    temp.setNext(current);
  }

  public void display() {
    // Consider overriding toString method instead of creating a display method,
    if (null == head) {
      System.out.println("List is empty.");
      return;
    }

    StringBuilder sb = new StringBuilder();
    StringNode current = head;
    sb.append("[");
    while (current != null) {
      sb.append(current.getData()).append(",");
      current = current.getNext();
    }
    sb.append("]");
    System.out.println(sb);
  }

  // Inner Class

  class StringNode {

    private final String data;
    private StringNode next;

    public StringNode(String nodeData) {
      next = null;
      data = nodeData;
    }

    public StringNode(String nodeData, StringNode next) {
      this.next = next;
      data = nodeData;
    }

    /**
     * Getter of Data
     */
    public String getData() {
      return data;
    }

    /**
     * Getter of Next
     */
    public StringNode getNext() {
      return next;
    }

    /**
     * Setter of Next
     */
    public void setNext(StringNode nextNode) {
      next = nextNode;
    }
  }

  public static void main(String[] args) {
    // Consider writing unit tests. I have created skeletons of a few rudimentry tests,
    // you may add more.
    test_insertInDscendingOrder();
    test_insertInAscendingOrder();
    test_insertTwoElements();
    test_insertSingleElement();
    //test_insertNullData();
  }

  private static void test_insertInDscendingOrder() {
    SortedLinkedList name = new SortedLinkedList();
    name.add("v");name.add("b");name.add("a");name.display();
  }

  private static void test_insertInAscendingOrder() {
    SortedLinkedList name = new SortedLinkedList();
    name.add("a");name.add("b");name.add("c");name.add("d");
    name.display();
  }

  private static void test_insertTwoElements() {
    SortedLinkedList name = new SortedLinkedList();
    name.add("a");name.add("b");name.display();
  }

  private static void test_insertSingleElement() {
    SortedLinkedList name = new SortedLinkedList();
    name.add("a");name.display();
  }

  private static void test_insertNullData() {
    // This would fail, Consider handling null data.
    SortedLinkedList name = new SortedLinkedList();
    name.add("a");
    name.add(null);
    name.display();
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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