简体   繁体   中英

Java : singly linked list, dummy node, insert

public class A<E> extend AbstractList<E>{

private SLNode<E> Head = new SLNode<E>
private int length = 0;     // length of the list

 // I will skip the class of SLNode<E>
 // Head's element and successor is initialized as null in the class SLNode<E>

     public void add(int index, E element)  // insert an element in the list 
     {
         // if index is less than 0 or greater than the length
          if( (index < 0) || (index > length ) )
               throw new IndexOutOfBoundsException();

          if(index ==0)
          {
              SLNode<E> newnode = new SLNode<E>(element, null);  // make new node
              newnode.setSuccessor(Head.getSuccessor());  
              Head.setSuccessor( newnode);
              length++;
          }
       }

Q1. Is this right way of adding element at the front of the list? (using dummy header node, but no tail) Q2. Would it be the same whether the list is empty or non-empty?

That's not a bad way to do it, though using a "dummy" node for "head" is somewhat unusual.

But it has the advantage that you can replace "Head" with "current", initialize that to "Head", then "crawl" up the list index nodes and do your insert, and you wouldn't have to special-case the zero case.

 public void add(int index, E element)  // insert an element in the list 
 {
     // if index is less than 0 or greater than the length
      if( (index < 0) || (index > length ) ) {
           throw new IndexOutOfBoundsException();
      }

      // Find insertion point
      SLNode<E> current = Head;
      for (int i = 0; i < index; i++) {
          current = current.getSuccessor();
      }

      // Create & insert new node
      SLNode<E> newnode = new SLNode<E>(element, null);
      newnode.setSuccessor(current.getSuccessor());  
      current.setSuccessor( newnode);
      length++;
  }

(But note that standard naming convention is to reserve names with initial upper-case for class names.)

Assuming that this is your insert at head method, I dont understand why you need to pass index in. Ideally I would like to have just 1 method for insert. But since you are specfically asking for insert at head.

public void addToHead(E element)  // insert an element at head
     {
         if(length==0)
             throw new Exception("head does not exist");

         element.setSuccessor(head);
         head = element;


         length++;

       }

Q1. Is this right way of adding element at the front of the list? (using dummy header node, but no tail)

EDIT: After rereading your question, and trying your code, I would say yes.

Q2. Would it be the same whether the list is empty or non-empty?

EDIT: Yes, it appears to work on an empty list.

dummy_header_list<String> theList = new dummy_header_list<String>();
System.out.println(theList);
theList.add(0,"first add");
System.out.println(theList);
theList.add(0,"second add");
System.out.println(theList);
theList.add(0,"third add");
System.out.println(theList);

gives:

[]
[first add]
[second add,first add]
[third add,second add,first add]

with this toString:

public String toString()
{
   String output = "[";
   SLNode<E> temp = Head.getSuccessor();
   while ( temp != null ) {
      if ( output.length() == 1 ) {
         output = output + temp.toString();
      }
      else {
          output = output + "," + temp.toString(); 
      }
      temp = temp.getSuccessor();
   }
   output = output + "]";
   return output;
}

I don't think you really need to have a special case for inserting at the front of the list. Inserting at the front of this list is no different from inserting anywhere else in the list.

public void add(int index, E element)
{
    // if index is less than 0 or greater than the length
    if ((index < 0) || (index > length))
        throw new IndexOutOfBoundsException();

    SLNode<E> previousNode = head;
    for ( int i = 0; i < index; i++ ) {
        previousNode = previousNode.getSuccessor();
    }

    SLNode<E> newNode = new SLNode<E>(element, previousNode.getSuccessor());
    previousNode.setSuccessor(newNode);
    length++;
}

Basically, this just traverses the list to find the correct node to insert after - if the index is 0, it immediately stops at head. Once you have the node to insert after, you perform these three steps:

  1. Create a new node and set its successor to the successor of the previous node
  2. Set the successor of the previous node to be the new node
  3. Add one to the length of the list

I ran a couple little tests on this and it seemed to work just fine.

Note that this approach pretty much assumes that head will never actually be considered an element in the list. It's really just a place to start the list. By that, I mean that head.getElement() will always return null - it's not really part of the list. I'm not sure if that's the implementation you wanted, but it seemed to make the most sense when you said that you start the list with a head element, even when the list is supposed to be empty.

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