Presentation is loading. Please wait.

Presentation is loading. Please wait.

Linked Lists Linear collections.

Similar presentations


Presentation on theme: "Linked Lists Linear collections."— Presentation transcript:

1 Linked Lists Linear collections

2 List Abstract Data Type
List interface built-in to the collections framework The built-in List interface is a dynamic linear collection that DOES support random access This presentation uses a “simplified” List interface Our list is NOT the built-in list! Our list does NOT support random access Our list is dynamic (grows/shrinks as needed)

3 Java List Interface (Partial listing)
void add(int index, Object element) - Inserts the specified element at the specified position in this list boolean add(Object element) - Appends the specified element to the end of this List. boolean addAll(int index, Collection c) - Inserts all of the elements in the specified collection into this list at the specified position. void clear() – Removes all elements from the list boolean equals(Object element) – Compares the specified object with this list for equality Object get(int index) – Returns the element at the specified index int indexOf(Object element) – Returns the index of the first occurrence of this object in the list boolean isEmpty() – Returns true if this list contains no elements and false otherwise Iterator iterator() – Returns an iterator over the elements of the list int lastIndexOf(Object element) – Returns the index of the last occurrence of element in the list Object remove(int index) – Removes and returns the element at the specified index Object set(int index, Object element) – Replaces the item at the specified index with the specified object int size() – Returns the number of elements in the list

4 Our List Interface Fundamental Methods
void addToFront(Object d) Adds object d to the front of the list void addToTail(Object d) Adds object d to the end of the list Object removeFirst() Removes and returns the first element of the list An error occurs if the list is empty Object removeLast() Removes and returns the last element of the list Object first() Returns the first element of the list Object last() Returns the last element of the list interface List{ public void addToFront(Object o); public void addToTail(Object o); public Object removeFirst(); public Object removeLast(); public Object first(); public Object last(); public int size(); public boolean isEmpty(); }

5 List ADT Operation Output List theList.addToFront(“A”) none (“A”)
theList.addToFront(“B”) none (“B”, “A”) theList.addToFront(“X”) none (“X”,”B”,”A”) theList.addToTail(“Y”) none (“X”,”B”,”A”,”Y”) theList.first() “X” (“X”,”B”,”A”,”Y”) theList.first() “X” (“X”,”B”,”A”,”Y”) theList.last() “Y” (“X”,”B”,”A”,”Y”) theList.removeFirst() “X” (“B”,”A”,”Y”) theList.removeLast() “Y” (“B”,”A”) theList.removeLast() “A” (“B”) theList.removeLast() “B” () theList.removeLast() error ()

6 List Implementation data: size: 5
Sequential Implementation (using arrays) Use an array to hold data elements Has a “fixed” capacity with (probably many) wasted slots. Insertion at the “beginning” of the list is slow (linear or O(n) performance). Keep track of the size of the list explicitly. Identical to a Vector index 0 index 11 Data Objects data: size: 5 List Object

7 Java Vector Class Hierarchy
AbstractList AbstractCollection Object List Interface Collection Interface

8 Array List Performance
Method Run-time performance void add(int index, Object element) O(n) boolean add(Object element) O(1) void clear() O(1) or O(n) Object get(int index) int indexOf(Object element) Object remove(int index) Object set(int index, Object element)

9 List Implementation head Next Data Next Data Next Data
Singly-Linked Implementation: Uses a recursively-defined “list node” structure to hold data elements Keep track of only the “head” node and can access all other nodes by following a “link” to the “next” node Insertions and removals are done by changing the links. No shifting of data is ever required head List Object Next Data Node Object Data Object Next Data Next Data

10 Singly Linked List Each node is a “link” in a chain of “nodes”.
class SListNode { private SListNode next; private Object data; SListNode(Object d) { data = d; next = null; } SListNode(Object d, SListNode n) { next = n; public SListNode getNext() { return next; public Object getData() { return data; public void setNext(SListNode n) { public void setData(Object d) { Each node is a “link” in a chain of “nodes”. Each node can only see “forward”. Each node contains a data element.

11 Singly Linked List class SinglyLinkedList implements List{ private SListNode head; private int size; SinglyLinkedList() { head = null; size = 0; } public void addToFront(Object o) { public void addToTail(Object o) { public Object removeFirst() { public Object removeLast() { interface List{ public void addToFront(Object o); public void addToTail(Object o); public Object removeFirst(); public Object removeLast(); public Object first(); public Object last(); public int size(); public boolean isEmpty(); } The list keeps track of the first link (called the “head”) from which all other links can be accessed.

12 Singly Linked List Insertion
Inserting an item means changing links (not shifting data) How do we insert an item at the front of this list? Next Data Node Object Data Object head List Object Next Data

13 Singly Linked List Insertion
public void addToFront(Object o) { head = new SListNode(o, head); size++; } Show me the code! head List Object Next Data Node Object Data Object

14 Singly Linked List Removal
Removing an item means changing links (not shifting data) How do we remove an item from the front of this list? head List Object Next Data Node Object Data Object

15 Singly Linked List Removal
public Object removeFirst() { if(isEmpty()) { throw new NoSuchElementException(); } SListNode node = head; head = head.getNext(); size--; return node.getData(); nullPointerException! Aaargh!!! head List Object Next Data Node Object Data Object

16 Singly Linked List Example (lists are entertaining and fun!)
List list = new SinglyLinkedList(); for(int i=0; i<3; i++) { list.addToFront(new Integer(i)); } while(!list.isEmpty()) { System.out.println(list.removeFirst()); public void addToFront(Object o) { head = new SListNode(o, head); size++; } public Object removeFirst() { if(isEmpty()) { throw new NoSuchElementException(); } SListNode node = head; head = head.getNext(); size--; return node.getData();

17 Linked List Insertion head
What needs to happen to insert at the end of this list? Inserting at the end means changing the link of the last node! Since we only “know” about the first node we have to navigate through the list until the last node is found. We then change its link. head List Object Next Data Node Object Data Object Next Data Next Data

18 Singly Linked List Insertion
Inserting at the end means changing the link of the last node! Since we only “know” about the first node we have to navigate through the list until the last node is found. We then change its link. public void addToTail(Object value) { SListNode newNode = new SListNode(value, null); if(isEmpty()) { head = newNode; } else { SListNode n = head; while(n.getNext() != null) { n = n.getNext(); } n.setNext(newNode); size++; Um, Ah, ?, …, getNext!

19 Singly Linked List Removal
Removing at the end means changing the link of the second-to-last node! Since we only “know” about the first node we have to navigate through the list until the second-to-last node is found. We then change its link. public Object removeLast() { if(isEmpty()) { throw new NoSuchElementException(); } SListNode tmp = head, prev = null; while(tmp.getNext() != null) { prev = tmp; tmp = tmp.getNext(); if(prev == null) { head = null; } else { prev.setNext(null); size--; return tmp.getData();

20 Singly Linked List Example (lists are entertaining and fun!)
List list = new SinglyLinkedList(); for(int i=0; i<3; i++) { list.addToTail(new Integer(i)); } while(!list.isEmpty()) { System.out.println(list.removeLast()); public void addToTail(Object value) { SListNode newNode = new SListNode(value, null); if(isEmpty()) { head = newNode; } else { SListNode n = head; while(n.getNext() != null) { n = n.getNext(); } n.setNext(newNode); size++;

21 Singly Linked List Example (lists are entertaining and fun!)
List list = new SinglyLinkedList(); for(int i=0; i<3; i++) { list.addToTail(new Integer(i)); } while(!list.isEmpty()) { System.out.println(list.removeLast()); public Object removeLast() { if(isEmpty()) { throw new NoSuchElementException(); } SListNode tmp = head, prev = null; while(tmp.getNext() != null) { prev = tmp; tmp = tmp.getNext(); if(prev == null) { head = null; } else { prev.setNext(null); size--; return tmp.getData();

22 Singly Linked List Variations
There are variations on implementation that make coding somewhat simpler use a sentinel node as the head to simplify the code (doesn’t do much for singly-linked lists) sentinel node is always present (even in an empty list) sentinel node stores no data sentinel node serves only as a “bookend” public SinglyLinkedList implements List { private SListNode head; private int size; SinglyLinkedList() { head = new SListNode(null, null); size = 0; } If in an empty list head is not null then the list uses sentinel nodes.

23 Sentinal Node Example Sentinel Nodes No Sentinel Nodes
public void addToFront(Object o) { head.setNext(new SListNode(o, head.getNext()); size++; } public void addToFront(Object o) { head = new SListNode(o, head); size++; } Sentinel Nodes No Sentinel Nodes public Object removeFirst() { if(isEmpty()) { throw new NoSuchElementException(); } SListNode node = head.getNext(); head.setNext(head.getNext().getNext()); size--; return node.getData(); public Object removeFirst() { if(isEmpty()) { throw new NoSuchElementException(); } SListNode node = head; head = head.getNext(); size--; return node.getData();

24 Singly-Linked List Performance
Method Run-time performance void add(int index, Object element) O(n) boolean add(Object element) O(1) void clear() Object get(int index) int indexOf(Object element) Object remove(int index) Object set(int index, Object element)

25 List Implementation Next Next Next Prev Prev Prev Data Data Data
Doubly-Linked Implementation: Uses a recursively-defined “list node” structure to hold data elements Has dynamic capacity with little “wasted” memory Keep track of the “head” and “tail” nodes and can access all other nodes “Natural” operations are from the head and tail since they are “fast” Head Node Tail Node Next Next Next Prev Prev Prev Data Data Data

26 Doubly Linked List Each node is a “link” in a chain of “nodes”.
class DListNode { private DListNode previous, next; private Object data; DListNode(Object d) { data = d; next = null; previous = null; } DListNode(Object d, DListNode p, DListNode n) { previous = p; next = n; // accessors and mutators Each node is a “link” in a chain of “nodes”. Each node can see “forward” AND “backward” Each node contains a data element.

27 Doubly Linked List class DoublyLinkedList implements List{ private DListNode head, tail; private int size; DoublyLinkedList() { head = null; tail = null; size = 0; } public void addToFront(Object o) { public void addToTail(Object o) { public Object removeFirst() { public Object removeLast() { // other methods interface List{ public void addToFront(Object o); public void addToTail(Object o); public Object removeFirst(); public Object removeLast(); public Object first(); public Object last(); public int size(); public boolean isEmpty(); } The list keeps track of the first link (called the “head”) from which all other links can be accessed.

28 Add To Front Operation public void addToFront(Object o) { head = new DListNode(o, null, head); if(head.getNext() != null) { head.getNext().setPrevious(head); } if(tail == null) tail = head; size++; What needs to be done to insert an item at the head of this list? tail head size: 3 Next Prev Head Node Data Tail Node

29 Remove First Operation
public Object removeFirst() { if(isEmpty()) { throw new NoSuchElementException(); } Object result = head.getData(); head = head.getNext(); if(head != null) { head.setPrevious(null); } else { tail = null; size--; return result; What needs to be done to remove an item at the head of this list? tail head size: 3 Next Prev Data

30 Front Operations Example
public void addToFront(Object o) { head = new DListNode(o, null, head); if(head.getNext() != null) { head.getNext().setPrevious(head); } if(tail == null) tail = head; size++; public Object removeFirst() { if(isEmpty()) { throw new NoSuchElementException(); } Object result = head.getData(); head = head.getNext(); if(head != null) { head.setPrevious(null); } else { tail = null; size--; return result; List list = new DoublyLinkedList(); for(int i=0; i<3; i++) { list.addToFront(new Integer(i)); } while(!list.isEmpty()) { System.out.println(list.removeFirst());

31 Add To Tail Operation public void addToFront(Object o) { head = new DListNode(o, null, head); if(head.getNext() != null) { head.getNext().setPrevious(head); } if(tail == null) tail = head; size++; Since it is a doubly-linked list – the list “looks” the same both forward and backward. The methods are symmetrical! public void addToTail(Object o) { tail = new DListNode(o, tail, null); if(tail.getPrevious() != null) { tail.getPrevious().setNext(tail); } if(head == null) head = tail; size++;

32 Remove From Tail Operation
public Object removeFirst() { if(isEmpty()) { throw new NoSuchElementException(); } Object result = head.getData(); head = head.getNext(); if(head != null) { head.setPrevious(null); } else { tail = null; size--; return result; public Object removeLast() { if(isEmpty()) { throw new NoSuchElementException(); } Object result = tail.getData(); tail = tail.getPrevious(); if(tail != null) { tail.setNext(null); } else { head = null; size--; return result; The remove methods are also highly symmetrical.

33 Tail Operations Example
public Object removeLast() { if(isEmpty()) { throw new NoSuchElementException(); } Object result = tail.getData(); tail = tail.getPrevious(); if(tail != null) { tail.setNext(null); } else { head = null; size--; return result; public void addToTail(Object o) { tail = new DListNode(o, tail, null); if(tail.getPrevious() != null) { tail.getPrevious().setNext(tail); } if(head == null) head = tail; size++; List list = new DoublyLinkedList(); for(int i=0; i<3; i++) { list.addToTail(new Integer(i)); } while(!list.isEmpty()) { System.out.println(list.removeLast());

34 Doubly-Linked List Performance
Method Run-time performance void add(int index, Object element) O(n) boolean add(Object element) O(1) void clear() Object get(int index) int indexOf(Object element) Object remove(int index) Object set(int index, Object element)

35 List Implementation Next Next Next Prev Prev Prev Data Data Data
Sentinel nodes: Implementation technique to simplify the code Can be used with either doubly or singly linked lists Head (and tail) nodes are “dummy” nodes that hold no data Head (and tail) nodes never change and are always present Head Node Tail Node Next Next Next Prev Prev Prev Data Data Data “Sentinel” nodes contain no data

36 A Simple Problem Problem: Given a List – write a method to print the contents of the list without modifying the list! interface List{ public void addToFront(Object o); public void addToTail(Object o); public Object removeFirst(); public Object removeLast(); public Object first(); public Object last(); public int size(); public boolean isEmpty(); } public void printList(List list) { for(int i=0; i<list.size(); i++) { Object tmp = list.removeFirst(); System.out.println(tmp); list.addToTail(tmp); }

37 Enumerations!!! A better solution is to use an Enumeration
An interface in the “java.util” package Gives sequential read-only access to the contents of a linear collection Don’t need to know anything about the collection implementation interface Enumeration { public boolean hasMoreElements(); public Object nextElement(); } public void printList(List list) { Enumeration e = list.elements(); while(e.hasMoreElements()) { System.out.println(e.nextElement()); }

38 Enumeration class SinglyLinkedListEnumeration implements Enumeration {
class SinglyLinkedList implements List { private SListNode head; private int size; // other methods here Enumeration elements() { } class SinglyLinkedListEnumeration implements Enumeration { private SListNode current; SinglyLinkedListEnumeration(SListNode n) { current = n; } public boolean hasMoreElements() { return current != null; public Object nextElement() { if(!hasMoreElements()) { throw new NoSuchElementException(); Object result = current.getData(); current = current.getNext(); return result;

39 Java LinkedList Class Hierarchy
AbstractSequentialList AbstractList AbstractCollection Object


Download ppt "Linked Lists Linear collections."

Similar presentations


Ads by Google