290 likes | 378 Vues
Lists. List : finite sequence of data elements all elements have the same data type The operations depend on the type of the list and not on the data type List : the most general type Ordered : element is ascending order Stacks , Queues : not all operations are allowed. list or head.
E N D
Lists • List: finite sequence of data elements • all elements have the same data type • The operations depend on the type of the list and not on the data type • List: the most general type • Ordered: element is ascending order • Stacks, Queues: not all operations are allowed lists
list or head rear or tail current next info Insertion after current position list new element lists
list or head rear or tail current Insertion at current position list new element lists
list or head rear or tail current Deletion after current position list or head deleted element lists
list or head rear or tail current Deletion at current position list or head deleted element lists
Terminology • empty: contains no elements • length: number of elements in list • head, or list: pointer to the beginning of the list • tail: pointer to the last element • current: pointer to current element • ordered: elements in ascending or descending order lists
Operations • setFirst: set “current” to “head” • setPos(i): sets current to the i-th element • currValue: returns value of “current” element • next/prev: “current” points to next/previous element • clear: delete all elements • insert: inserts an element at/after current position • append: inserts an element at “tail” • remove: delete the element at/after “current” position • isInList: true/false if current position is in list • isEmpty: true/false if list is empty lists
ADT List interface List { // List ADT in Java public void clear(); // Remove all Objects public void insert(Object item); // Insert at curr pos public void append(Object item); // Insert at tail public Object remove(); // Remove/return curr public void setFirst(); // Set to first pos public void next(); // Move to next pos public void prev(); // Move to prev pos public int length(); // Return curr length public void setPos(int pos); // Set curr position public void setValue(Object val); // Set current value public Object currValue(); // Return curr value public boolean isEmpty(); // True if empty list public boolean isInList(); // True if in list } // interface List lists
Iteration • Iterate through the whole list : MyList for (MyList.first( ); MyList.isInList( ); MyList.next( )) DoSomething(MyList.currValue( )); • If MyList: (12 32 15) and current points to 32 then MyList.insert(90) changes the list to be (12 32 90 15) lists
List Implementations • Array-based: very fast • the elements are stored in array • static: actual number of elements less than size allocated • Dynamic Memory: slower, more efficient • allocates memory for new elements • dynamic: no restriction on number of elements (except memory size) lists
Array Implementation (1) • Elements in continuous array positions • Head of list at pos 0 • Insertion and Deletion cause shifting of elements lists
class AList implements List { // Array-based list class private static final int defaultSize = 10; private int msize; // Maximum size of list private int numInList; // Actual list size private int curr; // Position of curr private Object[] listArray; // Array holding list AList() { setup(defaultSize); } // Constructor AList(int sz) { setup(sz); } // Constructor private void setup(int sz) { // Do initializations msize = sz; numInList = curr = 0; ListArray = new Object[sz]; // Create listArray } public void clear()// Remove all Objects from list { numInList = curr = 0; } // Simply reinitialize values lists
public void insert(Object it) { // Insert at curr pos Assert.notFalse(numInList < msize, "List is full"); Assert.notFalse((curr >=0) && (curr <= numInList),"Bad value for curr"); for (int i=numInList; i>curr; i--) // Shift up listArray[i] = listArray[i-1]; listArray[curr] = it; numInList++; // Increment list size } public void append(Object it){ // Insert at tail Assert.notFalse(numInList < msize, "List is full"); listArray[numInList++] = it; // Increment list size } public Object remove() { // Remove and return Object Assert.notFalse(!isEmpty(), "No delete: list empty"); Assert.notFalse(isInList(), "No current element"); Object it = listArray[curr]; // Hold removed Object for(int i=curr; i<numInList-1; i++) // Shift down listArray[i] = listArray[i+1]; numInList--; // Decrement list size return it; } lists
public void setFirst() { curr = 0; } // Set to first public void prev() { curr--; } // Move curr to prev public void next() { curr++; } // Move curr to next public int length() { return numInList; } public void setPos(int pos) { curr = pos; } public boolean isEmpty() { return numInList == 0; } public void setValue(Object it) { // Set current value Assert.notFalse(isInList(), "No current element"); listArray[curr] = it; } public boolean isInList()// True if curr within list { return (curr >= 0) && (curr < numInList); } }// Array-based list implementation lists
1 list 5 11 26 1 11 8 9 nodes 11 12 10 5 10 11 12 26 0 NULL 13 Array Implementation (2) lists
3 31 6 37 12 14 5 List 1 17 26 List 2 31 19 32 List 3 1 18 13 11 4 15 List 4 lists
List 4 List 2 List 3 List 1 lists
class AList implements List { // Array-based list class private static final int defaultSize = 10; private int msize; // Maximum size of list private int numInList; // Actual list size private int curr; // Position of curr private int avail; // next available position private Object[] listArray; // Array holding list private int[] listarray_next; // array holding pointers to next Object private void setup(int sz){ // Doinitializations msize = sz; numinlist = curr = 0; listarray = new Object[sz]; listarray_next = new int[sz]; avail = 0; // the first available element for (i=0; i < msize; i++) listarray_next[i] = i+1; // each elem points to its successor listarray_next[msize-1] = nothing; // the last elem has no next } lists
private int get_node( ) { // Get next available node if (avail == nothing) // from stack error(‘list overflow’) else { int pos = avail; avail = listarray_next[avail]; return pos; } } private void free_node (int p) { // make node available listarray_next[p] = avail; // push node back to stack avail =p; } private void insert(int p, Object x) { // insert after node pointed to by “p” if (p < 0 || p >= msize) error (‘void insertion’) else { int q = get_node( ); listarray[q] = x; listarray_next[q] = listarray_next[p]; listarray_next[p] = q; } } lists
private void delete(int p, Object x) { if ( p > 0 || p >= msize) // deletes elem after elem error (‘void deletion’); // pointed to by “p” else { int q = listarray_next[p]; x = listarray[q]; listarray_next[p] = listarray_next[q]; free_node(q); } } public AList() { setup(defaultSize); } // Constructor public AList(int sz) { setup(sz); } // Constructor public void clear( ) {…} // remove all ELEMs from list public void insert(Object it) {…} // insert ELEM at current position public void append(Object it) {…} // insert ELEM at tail of list public Object remove( ) {…} // remove and return current ELEM public void setFirst( ) {…} // set curr to first position; public void prev( ) {…} // move curr to previous position; public void next( ) {…} // move curr to next position; public int length( ) {…} // return current length of list }// Array-based list implementation lists
Dynamic Memory • Allocates memory for new elements as needed • Each node is a distinct object • The node class class Link{// A linked-list node private Object element; // Object for this node private Link next; // Pointer to next node Link(Object it, Link nextval) // Constructor { element = it; next = nextval; } Link(Link nextval) { next = nextval; } // Constructor Link next() { return next; } Link setNext(Link nextval) { return next = nextval; } Object element() { return element; } Object setElement(Object it) { return element = it; } } lists
class LList implements List{// Linked list class private Link head; // Pointer to list header private Link tail; // Pointer to last Object in list protected Link curr; // Position of current Object LList(int sz) { setup(); } // Constructor LList() { setup(); } // Constructor private void setup() { tail = head = curr = new Link(null); } public void setFirst() { curr = head; } public void next(){ if (curr != null) curr = curr.next(); } public void prev() { // Move to previous position Link temp = head; if ((curr == null) || (curr == head)) // No prev { curr = null; return; } // so return while ((temp != null) && (temp.next() != curr)) temp = temp.next(); curr = temp; } lists
public Object currValue() { // Return current Object if (!isInList()) return null; return curr.next().element(); } public boolean isEmpty() // True if list is empty { return head.next() == null; } public void insert(Object it) { // Insert Object at current position Assert.notNull(curr, "No current element"); curr.setNext(new Link(it, curr.next())); if (tail == curr) // Appended new Object tail = curr.next(); } public Object remove() { // Remove/return curr Object if (!isInList()) return null; Object it = curr.next().element(); // Remember value if (tail == curr.next()) tail = curr; // Set tail curr.setNext(curr.next().next()); // Cut from list return it; // Return value } lists
public void append(Object it)// insert Elem at tail of list { tail.setNext(new Link(it, NULL)); } public int length( ) { // return current length of list int cnt = 0; for (Link temp = head.next(); temp != NULL; temp = temp.next()) cnt++; // count Elems return cnt; } public void setPos(int pos) { // set curr to position curr = head; for(int i=0; (curr!=NULL) && (i < pos) i++) curr = curr.next(); } public void setValue(Object val) { // set current Elem's value Assert.notFalse(isInList(), "No current element"); curr.next().setElement(val); } public boolisInList()// TRUE if curr is within list { return (curr != NULL) && (curr.next() != NULL); } } // Linked list class implementation lists
Comparison • Array-Based Lists: • insertion and deletion are (n) • prev and direct access are (1) • fixed space allocated in advance • space reorganization if the array is full • faster in most cases • Linked Lists: • insertion and deletion are (1) • prev and direct access are (n) • space grows with number of elements • every element requires overhead • slower lists
Doubly Linked List • Allows for direct access to both next and previous elements of the current pointer • insert (delete) operations update both “next” and “prev” pointers • easy implementation curr.setNext(new DLink(it, curr.next(), curr)); if (curr.next().next() != null) curr.next().next().setPrev(curr.next()); if (tail == curr) // Appended new Object tail = curr.next(); lists
current current Insertion in Doubly Linked List lists
Deletion in Doubly Linked List current current lists
Circular Linked Lists • The next pointer of the last element points to the first element lists