360 likes | 552 Views
Stuff. Deadline for assn 3 extended to Monday, the 13 th . Please note that the testing class for assn 3 has changed. You will need to download a new copy. Solution to assn 2 is posted (you can use this with assn 3).
E N D
Stuff • Deadline for assn 3 extended to Monday, the 13th. • Please note that the testing class for assn 3 has changed. You will need to download a new copy. • Solution to assn 2 is posted (you can use this with assn 3). • Error in code shown last time for deleting the tail node in a singly linked list. • No separate lab exercise this week. CISC121 - Prof. McLeod
Singly Linked Lists • Singly linked list, so far: • Use of an inner class for the node. • Deleting the head node. • Deleting all nodes. • Searching for, and deleting an inner node. • Deleting the tail node in a singly linked list. • Deleting the tail node on a singly linked list is a lot of work – can we have a link to the previous node built in? CISC121 - Prof. McLeod
Today • Doubly linked lists. • Circular lists. • Skip lists. • Self – organizing lists. • Replacing sparse tables with linked lists. • LinkList<E> in java.util midterm CISC121 - Prof. McLeod
Deleting a Tail Node • So how is this going to work? • How can the tail pointer be moved up to the preceding node? tail head 20 15 10 5 null CISC121 - Prof. McLeod
public int removeTail () { int i = -1; if (!isEmpty()) { i = tail.info; if (head == tail) { head = null; tail = null;} else { IntNode pred = head; IntNode temp = head.next; while (temp.next != null) { pred = pred.next; temp = temp.next; } // end while tail = pred; tail.next = null; } // end else } // end if return i; } // end removeTail method was:temp != null CISC121 - Prof. McLeod
Deleting a Tail Node - Cont. • Of course, it is unlikely that you will every use that method! • Deleting the tail node this way is more time consuming than deleting an inner node. • Would it not be nice if the tail node already had a link pointing to the previous node? • No problem! Create a doubly linked list. CISC121 - Prof. McLeod
Doubly Linked Lists public class IntDLList { private IntDLNode head; private IntDLNode tail; private class IntDLNode { private int info; private IntDLNode next; private IntDLNode prev; // new link! public IntDLNode (int aNum) { this(aNum, null, null); } public IntDLNode (int aNum, IntDLNode n, IntDLNode p) { info = aNum; next = n; prev = p; } } // end IntDLNode // IntDLList constructors and methods } // end IntDLList CISC121 - Prof. McLeod
Doubly Linked List – Cont. • Structure: tail head 20 10 5 next null null prev CISC121 - Prof. McLeod
Doubly Linked List – Cont. • To add a node to the tail of the list: // better add a constructor too! public IntDLList () { head = null; tail = null; } public boolean isEmpty () { return head == null; } public void addToTail (int aNum) { if (!isEmpty()) { tail = new IntDLNode(aNum, null, tail); tail.prev.next = tail; } else { head = new IntDLNode(aNum); tail = head; } } // end addToTail CISC121 - Prof. McLeod
Doubly Linked List – Cont. dLList.addToTail(-10); After “new…”: head tail 20 10 5 -10 null null null head After tail=…; tail 20 10 5 -10 null null null head tail After tail.prev.next = tail; 20 10 5 -10 null null CISC121 - Prof. McLeod
Doubly Linked List – Cont. • To remove the tail node: public int removeFromTail () { int i = -1; if (!isEmpty()) { i = tail.info; if (head == tail) { // one node in list head = null; tail = null; } else { tail = tail.prev; tail.next = null; } } // end if return i; } // end removeFromTail CISC121 - Prof. McLeod
Doubly Linked List – Cont. int temp = dLList.removeFromTail(); head Before tail 20 10 5 -10 null null head tail After tail = tail.prev; 20 10 5 -10 null null head tail After tail.next = null; 20 10 5 -10 null null null CISC121 - Prof. McLeod temp is -10
Doubly Linked List – Cont. • Now the removeFromTail method is much easier. • So, adding or deleting head or tail nodes is “easy” - which operations will require iteration? Any operation that involves a node other than the head or tail! CISC121 - Prof. McLeod
Variations on Linked Lists • Circular Lists • Skip Lists • Self-Organizing Lists CISC121 - Prof. McLeod
Circular Lists • In a circular list, the last node’s “next” value is no longer null– it is linked to the head node. • A variable like “current” is needed to point to one of the nodes: current 20 15 10 5 CISC121 - Prof. McLeod
Circular Lists - Cont. • For a doubly linked list: current 20 15 10 5 CISC121 - Prof. McLeod
Circular Lists - Cont. • While this design seems “elegant”, it is really no improvement over the singly and doubly linked lists, with head and tail, described above. • You might use this to model a data structure that does not have a beginning or an end. The structure just grows and shrinks in size. (?) • But the next two List variations, on the other hand… CISC121 - Prof. McLeod
Skip Lists • The biggest problem with linked lists is that they require iteration to locate elements that are not at the head or tail of the list. • Even if nodes are ordered, a sequential search is still required. • Skip lists were suggested in 1990 as a way to speed up searching. • Structured in such a way that every second node contains a link that points two positions ahead, every fourth node has a link to a node four positions ahead, and so on. • Each node will contain an array of links: CISC121 - Prof. McLeod
Skip Lists – Cont. • Node class definition: public class IntSkipListNode { public int info; public IntSkipListNode[] next; public IntSkipListNode (int aNum, int n) { info = aNum; next = new IntSkipListNode[n]; for (int i = 0; i < n; i++) next[i] = null; } } // end IntSkipListNode CISC121 - Prof. McLeod
Skip Lists – Cont. • Singly linked skip list: • In order to search the skip list, the nodes must be in order by some attribute value. • Searching starts by skipping along the highest order links, and then by moving down into the lower order links when the upper order link moves past the target value. • Searching is now like the binary search. 1 7 5 9 3 6 8 10 CISC121 - Prof. McLeod
Skip Lists – Cont. • Consider what needs to happen when a node is added or deleted! • If the order of links is maintained, then all nodes on one side of the skip list have to be changed. This is very time consuming. • If the node is just inserted at the lowest level of the list, and all other nodes are kept the same then the link level order is not maintained. Eventually this will reduce the searching speed to be the same as a sequential search, and the list behaves just as a singly linked list. CISC121 - Prof. McLeod
Self-Organizing Lists • The idea here is to impose some organizational scheme on the list, in order to speed up searching. • Many different organizations can be used, depending on the nature of the data to be stored in the list. CISC121 - Prof. McLeod
Self-Organizing Lists - Cont. • Examples of organizations: • “Move to front” – when the desired element is located, move it to the front of the list. • “Transpose” – when the element is located, swap it with its predecessor, unless it is already at the head of the list. • “Count” – Order the list by the number of times elements are being accessed. • “Ordering” – Order by some criteria from the information being stored in the list. • Choice of organization depends on the how often new elements are added to the list and how often they are accessed. CISC121 - Prof. McLeod
Sparse Tables • A sparse table is defined as a table where the available cells are only partly populated. • For example, consider a table where the columns are student ID’s and the rows are courses taken, for the entire University: • A cell can contain a grade for a course taken by the student. • Of course, not all students take all courses, so only a small portion of each column is taken up with data. • Such a “sparse table” is probably not an efficient use of memory. CISC121 - Prof. McLeod
Sparse Tables – Cont. • Replace the table by a system of linked lists. Here is one possible design: • Have an ArrayList of course Objects. Each course Object contains all the necessary info about each course and a link to the first student enrolled in the course. • Have an ArrayList of student Objects. Each student Object contains the necessary student information and has a link to the first course taken by that student. • However, make the node design in such a way that the nodes are shared by both lists! CISC121 - Prof. McLeod
Sparse Tables – Cont. • Each node contains: • student number • class number • grade code (0 is “A”, 9 is “F”) • link to next student • link to next course • One node for each course the student has taken. No empty nodes. • See the structure on the next slide: Data Links CISC121 - Prof. McLeod
1 CISC121 - Prof. McLeod
Sparse Tables – Cont. • (I don’t know why SN and course# have to be in each node in the diagram…) • How to navigate through this structure? • Start with a student or start with a course. • But from any given node you can flip the direction of your navigation. • At the moment, you have to follow links from oldest to newest in one direction – this would be a painful way of finding recent students in a course that has been around for a while! How would you fix this? CISC121 - Prof. McLeod
Sparse Tables – Cont. • More efficient use of memory because there are no empty table elements. • Uses 17% of the memory used by the sparse table for a typical University setting. • Can easily grow as required. CISC121 - Prof. McLeod
Linked Lists in java.util • java.util contains a class called “LinkedList<E>”. • (E is the element type to be stored in the list.) • As does the ArrayList class, LinkedList contains many useful pre-defined methods. • LinkedList implements a linked list as a “generic doubly-linked list with references to the head and tail”. • Many of the LinkedList methods throw Exceptions for illegal parameters. • LinkedList only stores “Objects” of type E. CISC121 - Prof. McLeod
Linked Lists in java.util – Cont. • Methods include (“ob” is an object of type E): • void add(ob) // adds ob to end of list. • void add(pos, ob) // adds ob at pos. • void addFirst(ob) // adds ob at beginning of list. • void addLast(ob) // same as add(ob). • void clear() // removes all objects from the list. • boolean contains(ob) // returns true if the list contains ob. CISC121 - Prof. McLeod
Linked Lists in java.util – Cont. • Object get(pos) // returns the object at pos. • Object getFirst() // returns first object in list. • Object getLast() // returns last object in list. • int indexOf(ob) // returns position of first occurrence of ob, or –1 if ob is not found. • boolean isEmpty() // returns true if list is empty, false otherwise. CISC121 - Prof. McLeod
Linked Lists in java.util – Cont. • Iterator iterator() // generates and returns an iterator for the list. • LinkedList() // creates an empty linked list. • boolean remove(ob) // removes first occurrence of ob and returns true. • Object removeFirst() // removes and returns first element in list. CISC121 - Prof. McLeod
Linked Lists in java.util – Cont. • Object removeLast() // removes and returns last element in list. • int size() // returns number of elements in list. CISC121 - Prof. McLeod
Linked Lists - Summary • Linked lists really take advantage of Java’s use of Objects, by creating a structure based on pointers. • A structure that can be easily tailored to suit the needs of a particular data structure. • Only uses the space it needs, no empty data nodes, does not need contiguous memory. • Remember to compare linked lists to arrays when choosing a data structure - advantages and disadvantages. • (Hint: use diagrams to help write linked list code!) CISC121 - Prof. McLeod