Variations on Linked Lists by mlq89969


									Variations on Linked Lists

       Ellen Walker
  CPSC 201 Data Structures
      Hiram College
            Linked List (review)

• Each element contains two parts:
  – Value of this element
  – Pointer to the next element

  class string_node {
     string val;
     string_node *next;
Inserting into a Linked List (Review)

   Ann             Barry                       Ellen


/* Assume item is a reference to the node that contains
Node<string> newNode = new Node<string> (“Carol”); =; = newitem;
     Printing a Linked List (Review)

//print elements, starting at the node called head;
// Uses a for loop
   for(Node<String> current=head; current!=null;{
    Printing Using Iterator (Review)

//prints the list, one item per line
//returns iterator pointing before the list…
Iterator<String> itr = aList.iterator();
   String name =;
    LinkedList Implementation (Review)

public class LinkedList<E>{
 private Node<E> head; //first element or null
 private int size; //list length
 private static class Node<E>{ //inner class
      private E data;
     private node<E> next;
    //methods go here
             Implementing toString

• Writes elements of list into a string
• Use either traversal from before (iterator version
   String toString(){
       StringBuilder result = new StringBuilder();
       Iterator<E> itr = iterator();
           Dummy Nodes simplify
• An empty list has one node (the dummy node)
• There is no longer a special case for adding the first
  element of the node!
• What changes need to be made to…
   – Constructor?
   – Find / Retrieve ?
   – Insert / Delete?
• Sometimes a dummy node can have a useful value
  (e.g. smallest possible element for sorted list)
Changes to the implementation for a
          dummy node
• Constructor
   – Head is a new (dummy) node instead of NULL
• indexOf / get
   – indexOf is unchanged (assume value not
     otherwise in list)
   – get(k) will return value at node (k+1)
• Insert / Delete
   – Begin by locating the predecessor node
   – No special cases for first node (it has a
                 Circular List

• Circular List: The tail of the list points back to
  the head

• There is no NULL pointer to “end” the list.
         Issues with circular list

• How do you know when you‟re done?
  – Make sure you save the head pointer.
  – When ( == head) you‟ve reached the end
• How are insertion and deletion handled?
  – No special cases!
  – Predecessor to head node is the last node in the
         The Josephus Problem

• (One of many variations…)
  The founder of a startup is forced to lay off all
  but one employee. Not having any better
  way to decide, he arranges all employees in a
  circle and has them count off. The 10th
  employee in the circle is laid off, and the
  count begins again. The last person is not
  laid off.
• If there are N employees, where should you
  sit to avoid being laid off?

• Model the circle of employees as a circular
  linked list
• Implement the counting off process, and
  delete the 10th employee each time
• After N-1 people are deleted, there should be
  only one employee left.
• That employee‟s original position number is
  the solution to the problem.
             Doubly Linked List

• Each node has prev and next pointer
• List can be traversed forward or backward
• To insert a node after “cur”
  –   Node<E> tmp = new Node<E>(newItem);
  – =;
  –   tmp.prev=cur;
  – = tmp;
• Reverse the process to delete!
       Which list implementation?

• Array
  – Can jump into the middle easily (random access)
  – Inserting & deleting can require time-consuming shifting
  – Must allocate block of memory at once (can resize later with
• Linked
  – No random access
  – Insert & delete are fixed cost, once you decide where.
  – Nodes allocated one at a time.
              Linked List Choices

• Plain vanilla
   – Simple, small
• Dummy header
   – Eliminates special cases (chance for error)
• Circular
   – No defined start position in sequence
   – Can find the node before, though it takes N steps
• Doubly linked
   – Easy to find the node before
   – Larger Node; twice as many special cases
• Circular and doubly linked
       Linked Lists and Recursion

• Recursive definition of a list
   – Null (empty list) is a list    (base case)
   – A list consists of one item (the head) followed by a
     list (next)
• Example:
   – A->B->C-| is a list
   – Head = A, next = B->C-|
      Recursive Function on Lists

• Base case for the recursive function is the
  empty list (base case for the definition)
• Other cases -
  – “Take a step” = do something to the head
  – Recurse = call function for the rest of the list
  – May or may not build up a solution
            Recursive List Search

Node<E> recFind (Node<E> head, E x){
    //x is not in an empty list!
    If (head == null) return null;
    //x is found at the beginning
    Else if (head.item == x) return head;
    //Recursive case: search the rest of the list
    Return recFind(, x);
    Recursive functions are private!

• A recursive function uses Node references.
• Node references are private
   – Implementation detail
   – Not every implementation of List has Nodes
• Most recursive functions have a public
  “starter” and a private internal function
         Public Caller for recFind

boolean isIn(E x){
  //call Find on the head of the list
  //if Find does not return null, the item is in
   // the list.
  return (recFind(head,x) != null);
          Recursive CountItem

• This function counts the number of
  occurrences of the item x in the list
Int CountItem (Node * head, ItemType x){

      Public Caller for CountItem

int List::howMany(ListItemType x){


To top