From charlesreid1

(Created page with " ==Question== Write a method that will rotate a Linked list, with similar result as the command addLast(removeFirst()), but that would not create and destroy any node. To ro...")
 
No edit summary
Line 7: Line 7:


The rotate method is in the TLinkedList class: https://charlesreid1.com:3000/cs/java/src/master/lists/linked-lists/TLinkedList.java
The rotate method is in the TLinkedList class: https://charlesreid1.com:3000/cs/java/src/master/lists/linked-lists/TLinkedList.java


<pre>
<pre>
/** Reverse the entire linked list in O(n) time. */
/** Rotate list by moving one element from front to back.
public void reverse() {  
*
if(this.size==0 || this.size==1) {
* This is implemented without creating/destroying a node.
*/
public void rotate() {  
if(this.size==0 || this.size==1) {  
return;
return;
}
}
Node<E> runner = this.head;
// Make circular
Node<E> prev = null;
tail.setNext(this.head);
Node<E> next_runner = this.head.getNext();
tail = tail.getNext();
// Circular
head = tail.getNext();
 
// Break circle
tail.setNext(null);


while(next_runner!=null){
runner.setNext(prev);
prev = runner;
runner = next_runner;
next_runner = next_runner.getNext();
}
this.head = runner;
}
}
</pre>
</pre>
To do this, need to connect head to tail, advance tail by one,


To reverse a linked list, need to hang on to three separate pointers:
To reverse a linked list, need to hang on to three separate pointers:
Line 34: Line 36:
* One pointer is the prior, which points to the node that will be behind the runner in the list
* One pointer is the prior, which points to the node that will be behind the runner in the list
* One pointer is the temporary pointer to the rest of the list that is still being processed
* One pointer is the temporary pointer to the rest of the list that is still being processed
<pre>
if(size=0):
  return
if(size==1)
  return
if size=2)
    runner = head
    prior = null
    temp = runner.getNext()
    runner.setNext(prior)
</pre>
if length is 0, do nothing
if length is 1, do nothing
<pre>
runner = head
prev = null
next runner = head.getNext()
while(nextrunner != null)
    runner.setNext(prev)
    prev = runner
    runner = nextrunner
    nextrunner = runner.getNext()
list.head = runner
</pre>
==Code==
This was implemented in the TLinkedList<T> class, the templated generic linked list type:
<pre>
/** Reverse the entire linked list in O(n) time. */
public void reverse() {
if(this.size==0 || this.size==1) {
return;
}
Node<E> runner = this.head;
Node<E> prev = null;
Node<E> next_runner = this.head.getNext();
while(next_runner!=null){
runner.setNext(prev);
prev = runner;
runner = next_runner;
next_runner = next_runner.getNext();
}
this.head = runner;
}
</pre>


Link to full implementation of TLinkedList class: https://charlesreid1.com:3000/cs/java/src/master/lists/linked-lists/TLinkedList.java
Link to full implementation of TLinkedList class: https://charlesreid1.com:3000/cs/java/src/master/lists/linked-lists/TLinkedList.java
Line 97: Line 45:
Code to make these figures is here: https://charlesreid1.com:3000/cs/java/src/master/lists/linked-lists/Timing.java
Code to make these figures is here: https://charlesreid1.com:3000/cs/java/src/master/lists/linked-lists/Timing.java


[[Image:rev_amortized.png|500px]]
[[Image:rotate_amortized.png|500px]]


[[Image:rev_walltime.png|500px]]
[[Image:rotate_walltime.png|500px]]


==Flags==
==Flags==
Line 107: Line 55:
[[Category:Linked Lists]]
[[Category:Linked Lists]]
[[Category:Skiena]]
[[Category:Skiena]]
[[Category:Lists]]

Revision as of 07:11, 6 June 2017

Question

Write a method that will rotate a Linked list, with similar result as the command addLast(removeFirst()), but that would not create and destroy any node.

To rotate a linked list without destroying the node, we will temporarily make the link circular.

The rotate method is in the TLinkedList class: https://charlesreid1.com:3000/cs/java/src/master/lists/linked-lists/TLinkedList.java

	/** Rotate list by moving one element from front to back.
	 *
	 * This is implemented without creating/destroying a node.
	 */
	public void rotate() { 
		if(this.size==0 || this.size==1) { 
			return;
		}
		// Make circular
		tail.setNext(this.head);
		tail = tail.getNext();
		
		// Circular
		head = tail.getNext();

		// Break circle
		tail.setNext(null);

	}

To do this, need to connect head to tail, advance tail by one,

To reverse a linked list, need to hang on to three separate pointers:

  • One pointer is the runner, which points to the current node being "fixed" (reversed in place).
  • One pointer is the prior, which points to the node that will be behind the runner in the list
  • One pointer is the temporary pointer to the rest of the list that is still being processed

Link to full implementation of TLinkedList class: https://charlesreid1.com:3000/cs/java/src/master/lists/linked-lists/TLinkedList.java

Profiling

Here are the total walltime costs and per operation costs for the remove operation defined in the TLinkedList class above.

Code to make these figures is here: https://charlesreid1.com:3000/cs/java/src/master/lists/linked-lists/Timing.java

Rotate amortized.png

Rotate walltime.png

Flags