Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to reverse a certain number of objects in a Linked List?

Tags:

java

Here is the method I have so far. I'm not sure how to go about this. I want the method to take a int parameter of how many of the objects the user wants reversed in the linked list.

public void reverseFirstFew(int howMany) // NOT DONE 
{
   ListIterator iterator = listIterator();
   Object temp = null;

   if(howMany <= 0){
       throw new IndexOutOfBoundsException();
   }
   if(howMany > size()){
       throw new IndexOutOfBoundsException();
   }



}

I also have a custom ListIterator class that I made. Here are the methods in it.

public ListIterator listIterator()
{
  return new LinkedListIterator();
}


private class LinkedListIterator implements ListIterator
{

  private Node position;
  private Node previous;

  // Constructs an iterator that points to the front
  // of the linked list.   of the linked list.
  public LinkedListIterator()
  {
     position = null;
     previous = null;
  }

 // Moves the iterator past the next element, and returns
 // the traversed element's data.
  public Object next()
  {
     if (!hasNext())
        throw new NoSuchElementException();
     previous = position; // Remember for remove

     if (position == null)
        position = first;
     else
        position = position.next;

     return position.data;
  }

  // Tests if there is an element after the iterator position  position
  public boolean hasNext()
  {
     if (position == null)
        return first != null;
     else
        return position.next != null;
  }

  // Adds an element after the iterator position
  // and moves the iterator to the inserted element.
  public void add(Object element)
  {
     if (position == null)
     {
        addFirst(element);
        position = first;
     }
     else
     {
        Node newNode = new Node();
        newNode.data = element;
        newNode.next = position.next;
        position.next = newNode;
        position = newNode;
     }
     previous = position;
  }

// Removes the last traversed element. This method may
// only be called after a call to the next() method.
  public void remove()
  {
     if (previous == position)
        throw new IllegalStateException();

     if (position == first)
     {
        removeFirst();
     }
     else
     {
        previous.next = position.next;
     }
     position = previous;
  }

  // Sets the last traversed element to a different value
  public void set(Object element)
  {
     if (position == null)
        throw new NoSuchElementException();
     position.data = element;
  }
}//end of

I would greatly appreciate if someone could guide me in the right direction.

like image 462
Suds2 Avatar asked Mar 15 '23 04:03

Suds2


2 Answers

Use List.subList(int fromIndex, int toIndex) and Collections.reverse(List<?> list):

Collections.reverse(list.subList(0, howMany));

Works for both ArrayList and LinkedList.

Example

List<Integer> list = new LinkedList<>(Arrays.asList(1,2,3,4,5,6,7,8,9));
Collections.reverse(list.subList(0, 4));
System.out.println(list);

Output

[4, 3, 2, 1, 5, 6, 7, 8, 9]

As for why this works, quoting javadoc of subList:

Returns a view of the portion of this list between the specified fromIndex, inclusive, and toIndex, exclusive. (If fromIndex and toIndex are equal, the returned list is empty.) The returned list is backed by this list, so non-structural changes in the returned list are reflected in this list, and vice-versa. The returned list supports all of the optional list operations supported by this list.

This method eliminates the need for explicit range operations (of the sort that commonly exist for arrays). Any operation that expects a list can be used as a range operation by passing a subList view instead of a whole list. For example, the following idiom removes a range of elements from a list:

list.subList(from, to).clear();
like image 61
Andreas Avatar answered Mar 25 '23 00:03

Andreas


I'm going to give the same answer as Andreas, because damnit I coded this up and he posted just as I put the answer in my clipboard to paste it. >:-p

public class ReverseList
{
   public static void main(String[] args) {
      List<Integer> result = reverseFirst( Arrays.asList( 1,2,3,4,5,6,7,8,9 ), 4 );
      System.out.println( result );
   }

   private static List<Integer> reverseFirst( List<Integer> asList, int howMany )
   {
      List<Integer> sub = asList.subList( 0, howMany );
      Collections.reverse( sub );
      return asList;
   }
}
like image 41
markspace Avatar answered Mar 25 '23 00:03

markspace