EECE 330 Chapter, Fall 2011

American University of Beirut · Data Structures and Algorithms · 26 pages · Prof. Hassan Artail

All EECE 330 files
EECE 330 Chapter, Fall 2011, page 1

Stuck on a question? A tutor can walk you through it.

EECE 330 Chapter, Fall 2011, page 2 EECE 330 Chapter, Fall 2011, page 3 EECE 330 Chapter, Fall 2011, page 4 EECE 330 Chapter, Fall 2011, page 5 EECE 330 Chapter, Fall 2011, page 6 EECE 330 Chapter, Fall 2011, page 7 EECE 330 Chapter, Fall 2011, page 8 EECE 330 Chapter, Fall 2011, page 9 EECE 330 Chapter, Fall 2011, page 10

Showing the first 10 of 26 pages. Download the PDF to see all of it.

More EECE 330 files

Show the text of this chapter
EECE 330 Data Structures & Algorithms Singly-Linked Lists Singly-Linked Lists © Hassan Artail American University of Beirut Lists A list is a finite, ordered sequence of data items. Important concept: List elements have a position. Notation: <a0, a1, …, an-1> What operations should we implement? List Implementation Concepts The list implementation will support the concept of a current position. We do this by defining the list in terms of left and right partitions. • Either or both partitions may be empty. Partitions are separated by the fence. <20, 23 | 12, 15> List ADT template <class Elem> class List { public: virtual void clear() = 0; virtual bool insert(const Elem&) = 0; virtual bool append(const Elem&) = 0; virtual bool remove(Elem&) = 0; virtual void setStart() = 0; virtual void setEnd() = 0; virtual void prev() = 0; virtual void next() = 0; List ADT (cont) virtual int leftLength() const = 0; virtual int rightLength() const = 0; virtual bool setPos(int pos) = 0; virtual bool getValue(Elem&) const = 0; virtual void print() const = 0; }; List ADT Examples List: < , 32, 15> MyList.insert(99); Result: < , 99, 32, 15> Iterate through the whole list: for (MyList.setStart(); MyList.getValue(it); MyList.next()) DoSomething(it); 12 12 List Find Function // Return true iff K is in list bool find(List<int>& L, int K) { int it; for (L.setStart(); L.getValue(it); L.next()) if (K == it) return true; // Found it return false; // Not found } Array-Based List Insert Array-Based List Class (1) template <class Elem> // Array-based list class AList : public List<Elem> { private: int maxSize; // Maximum size of list int listSize; // Actual elem count int fence; // Position of fence Elem* listArray; // Array holding list public: AList(int size=DefaultListSize) { maxSize = size; listSize = fence = 0; listArray = new Elem[maxSize]; } Array-Based List Class (2) ~AList() { delete [] listArray; } void clear() { delete [] listArray; listSize = fence = 0; listArray = new Elem[maxSize]; } void setStart() { fence = 0; } void setEnd() { fence = listSize-1; } void prev() { if (fence != 0) fence--; } void next() { if (fence < listSize) fence++; } int leftLength() const { return fence+1; } int rightLength() const { return listSize – fence -1; } Array-Based List Class (3) bool setPos(int pos) { if ((pos >= 0) && (pos < listSize)) fence = pos; return (pos >= 0) && (pos < listSize); } bool getValue(Elem& it) const { if (rightLength() == 0) return false; else { it = listArray[fence+1]; return true; } } }; Insert // Insert at front of right partition template <class Elem> bool AList<Elem>::insert(const Elem& item) { if (listSize == maxSize) return false; for(int i=listSize; i>fence; i--) // Shift Elems up to make room listArray[i] = listArray[i-1]; listArray[fence+1] = item; listSize++; // Increment list size return true; } Append // Append Elem to end of the list template <class Elem> bool AList<Elem>::append(const Elem& item) { if (listSize == maxSize) return false; listArray[listSize++] = item; return true; } Remove // Remove and return first Elem in right partition template <class Elem> bool AList<Elem>::remove(Elem& it) { if (rightLength() == 0) return false; it = listArray[fence]; // Copy Elem for(int i=fence; i<listSize-1; i++) // Shift them down listArray[i] = listArray[i+1]; // Decrement size listSize--; return true; } Link Class Dynamic allocation of new list elements // Singly-linked list node template <class Elem> class Link { public: Elem element; // Value for this node Link *next; // Pointer to next node //First Constructor Link(const Elem& elemval, Link* nextval =NULL) { element = elemval; next = nextval; } //Overloaded Constructor Link(Link* nextval =NULL) { next = nextval; } }; Linked List Position (2) Linked List Class (1) // Linked list implementation template <class Elem> class LList: public List<Elem> { private: Link<Elem>* head; // Point to list header Link<Elem>* tail; // Pointer to last Elem Link<Elem>* fence;// Last element on left int leftcnt; // Size of left int rightcnt; // Size of right void init() { // Intialization routine fence = tail = head = new Link<Elem>; leftcnt = rightcnt = 0; } Linked List Class (2) void removeall() { // Return link nodes to free store while(head != NULL) { fence = head; head = head->next; delete fence; } } public: LList(int size=DefaultListSize) { init(); } ~LList() { removeall(); } // Destructor void clear() { removeall(); init(); } Linked List Class (3) void setStart() { fence = head; rightcnt += leftcnt; leftcnt = 0; } void setEnd() { fence = tail; leftcnt += rightcnt; rightcnt = 0; } void next() { // Don't move fence if right empty if (fence != tail) { fence = fence->next; rightcnt--; leftcnt++; } } int leftLength() const { return leftcnt; } int rightLength() const { return rightcnt; } bool getValue(Elem& it) const { if(rightLength() == 0) return false; it = fence->next->element; return true; } }; Insertion Insert/Append // Insert at front of right partition template <class Elem> bool LList<Elem>::insert(const Elem& item) { fence->next = new Link<Elem>(item, fence->next); if (tail == fence) tail = fence->next; rightcnt++; return true; } // Append Elem to end of the list template <class Elem> bool LList<Elem>::append(const Elem& item) { tail = tail->next = new Link<Elem>(item, NULL); rightcnt++; return true; } Removal Remove // Remove and return first Elem in right partition template <class Elem> bool LList<Elem>::remove(Elem& it) { if (fence->next == NULL) return false; it = fence->next->element; // Remember value // Remember link node Link<Elem>* ltemp = fence->next; fence->next = ltemp->next; // Remove if (tail == ltemp) // Reset tail tail = fence; delete ltemp; // Reclaim space rightcnt--; return true; } Prev // Move fence one step left; no change if left is empty template <class Elem> void LList<Elem>::prev() { Link<Elem>* temp = head; if (fence == head) return; // No prev Elem while (temp->next!=fence) temp=temp->next; fence = temp; leftcnt--; rightcnt++; } Setpos // Set the size of left partition to pos template <class Elem> bool LList<Elem>::setPos(int pos) { if ((pos < 0) || (pos > rightcnt+leftcnt)) return false; fence = head; for(int i=0; i<pos; i++) fence = fence->next; return true; } Comparison of Implementations Array-Based Lists: • Insertion and deletion are (n). • Prev and direct access are (1). • Array must be allocated in advance. • No overhead if all array positions are full. Linked Lists: • Insertion and deletion are (1). • Prev and direct access are (n). • Space grows with number of elements. • Every element requires overhead.