View
222
Download
2
Tags:
Embed Size (px)
Citation preview
E.G.M. Petrakis lists, stacks, queues 1
Lists
• List: finite sequence of data elements– Ordered: each element has a position in list– All elements has the same data type– The operations depend on the type of the list
and not on the data type• List: the most general type
• Stacks, Queues: restricted versions of lists– Not all operations are allowed
E.G.M. Petrakis lists, stacks, queues 2
listinfo
next
list
New element
Insertions
current
E.G.M. Petrakis lists, stacks, queues 3
list
list
Deleted element
Deletions
current
E.G.M. Petrakis lists, stacks, queues 4
• 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/descending
order
E.G.M. Petrakis lists, stacks, queues 5
• Operations on lists:– 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/prev element– clear: delete all elements– insert: inserts an element in current position– append: inserts an element at “tail”– remove: delete the “current” element – find(k): set current to the first occurrence of “k”– isInList: true/false if current position is in list– isEmpty: true/false if list is empty
E.G.M. Petrakis lists, stacks, queues 6
class list { // List class ADT in C++public:
list(const int = LIST_SIZE); //constructor~list( ); //destructorvoid clear ( ); // remove all elementsvoid insert(const ELEM &); // inset at currentvoid append(const ELEM&); // insert at tailELEM remove ( ); // remove currentvoid setFirst ( ); // set current to HEADvoid prev ( ) ; // set current to previousvoid next ( ); // set current to nextint length ( ) const; // return size of listvoid setPos(const int); // set current to new posvoid setValue(const ELEM&) // set current’s valuesbool isEmpty( ) const; // true/false on emptybool isInList( ) const; // true/false if current is in listbool find(const ELEM&); // find value of current in list
};
E.G.M. Petrakis lists, stacks, queues 7
• 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)
E.G.M. Petrakis lists, stacks, queues 8
• Implementation, two approaches:– Array-based
• The elements are stored in array
• Fixed size
• Fast implementation
• Actual number or element less than size allocated
– Linked list• Dynamic: allocates memory for new elements
• No restriction on number of elements except physical memory size
• Slower but more efficient
E.G.M. Petrakis lists, stacks, queues 9
• Array implementation (1) : – Stores elements in continuous array positions– Head of list at pos 0– Insertion/deletion causes shifting of elements
E.G.M. Petrakis lists, stacks, queues 10
class list{ //Array based list classprivate:
int msize //Maximum size of listint numinlist //Actual number of ELEMsint curr; //Position of “current”ELEM* listarray; //Array holding ELEMs
Public:
list (const int=LIST_SIZE); // Constructor~list(); // Destructorvoid clear(); // Remove all ELEMs from listvoid insert(const ELEM&); // Insert ELEM at current positionvoid append(const ELEM&); // Insert ELEM at tail of listELEM remove(); // Remove and return current ELEMvoid setFirst(); // Set curr to first position;void prev(); // Move curr to previous position;void next(); // Move curr to next position;int length() const; // Return current length of listvoid setPos(const int); // Set curr to specified positionvoid setValue(const ELEM&); // Set current ELEM's valueELEM currValue() const; // Return current ELEM's valuebool isEmpty() const; // Return TRUE if list is emptybool isInList() const; // TRUE if curr is within listbool find(const ELEM&); // Find value (from current position)
};
E.G.M. Petrakis lists, stacks, queues 11
List::List(int sz) // Constructor: initialize { msize = sz; numinlist = 0; curr = 0; listarray = new Elem[sz]; }
List::~List() // Destructor: return array space { delete [] listarray; }
void List::clear() // Remove all Elems from list { numinlist = 0; curr = 0; } // Simply reinitialize values
void List::insert(const Elem item) { // Insert Elem at current position // Array must not be full and curr must be a legal position assert((numinlist < msize) && (curr >=0) && (curr <= numinlist)); for(int i = numinlist; i > curr; i--) // Shift Elems up to make room listarray[i] = listarray[i - 1]; listarray[curr] = item; numinlist++; // Increment current list size }
void List::append(const Elem item) { // Insert Elem at tail of list assert(numinlist < msize); // List must not be full listarray[numinlist++] = item; // Increment list size }
E.G.M. Petrakis lists, stacks, queues 12
Elem List::remove( ) { // Remove and return current Elem assert( !isEmpty() && isInList() ); // Must be an Elem to remove Elem temp = listarray[curr]; // Store removed Elem for (int i=curr; i < numlist-1; i++) // shift elements down listarray[i] = listarray[i+1]; numinlist--; // Decrement current list size return temp;}
void List::setFirst( ) // Set curr to first position { curr = 0; }
void List::prev( ) // Move curr to previous position { curr--; }
void List::next( ) // Move curr to next position { curr++; }
int List::length( ) const // Return current length of list { return numinlist; }
void List::setPos(int pos) // Set curr to specified position {curr = pos; }
E.G.M. Petrakis lists, stacks, queues 13
void List::setValue(const Elem val) { // Set current Elem's value assert(isInList( )); // Curr must be at valid position listarray[curr] = val; }
Elem List::currValue( ) const { // Return current Elem's value assert(isInList( )); // Must be at a valid position return listarray[curr]; }
bool List::isEmpty( ) const // Return TRUE if list is empty { return numinlist == 0; }
bool List::isInList( ) const // TRUE if curr is within list { return (curr >= 0) && (curr < numinlist); }
bool List::find(int val) { // Find value (starting at curr) while (isInList( )) // Stop if reach end if (key(currValue( )) == val) return TRUE; // Found it else next( ); return FALSE; // Not found
}
E.G.M. Petrakis lists, stacks, queues 14
• Array implementation(2): pointers to elems
1 115 26list
1 11
11 12
5 10
26 0
8
9
10
11
12
13
nodes
NULL
E.G.M. Petrakis lists, stacks, queues 15
313 14 376 5 12List 1
17 26List 2
31 19 32List 3
1 18 13 11 4 15List 4
E.G.M. Petrakis lists, stacks, queues 16
1 26 0
2 11 10
3 5 16
4 1 25
5 17 1
6 13 2
7
8 19 19
9 14 13
10 4 22
11
12 31 8
13 6 3
14
15
16 37 24
17 3 12
18
19 32 0
20
21 7 9
22 15 0
23
24 12 0
25 18 6
List 4List 2
List 3
List 1
E.G.M. Petrakis lists, stacks, queues 17
class list { //Array based list classprivate:
int msize //Maximum size of listint numinlist //Actual number of ELEMsint curr; //Position of “current”
int next; // next element int avail; // next available position
ELEM* listarray; //Array holding ELEMs plus pointers to next ELEMsint get_node( ); //get position of available nodevoid free_node( ); //return node in arrayvoid insert(p, x); //insert node after the node pointed by pvoid delete(p, x); //delete node after the node pointed by p
public:list (const int=LIST_SIZE); // Constructor~list( ); // Destructorvoid clear( ); // Remove all ELEMs from listvoid insert(const ELEM&); // Insert ELEM at current positionvoid append(const ELEM&); // Insert ELEM at tail of listELEM remove( ); // Remove and return current ELEMvoid setFirst( ); // Set curr to first position;void prev( ); // Move curr to previous position;void next( ); // Move curr to next position;int length( ) const; // Return current length of list………. // More member functions
};
E.G.M. Petrakis lists, stacks, queues 18
list::list(int sz) { // Constructor: initialize msize = sz; numinlist = 0; curr = 0; listarray = new Elem[sz]; // put all (available) elements in a stack avail = 0; // the first available element for (i=0; i < msize; i++) listarray[i].next = i+1; // each elements points to its
successor listarray[msize-1].next = nothing; // the last elem has no next }
list::~list( ) // Destructor: return array space { delete [] listarray; }
E.G.M. Petrakis lists, stacks, queues 19
int list::get_node( ) { if (avail == nothing) error(‘list overflow’) else { int pos = avail; avail = listarray[avail].next; return pos; }}
void list::free_node (int p) { node[p].next = avail; avail =p;}
E.G.M. Petrakis lists, stacks, queues 20
void insert::list (int p, int x) { if (p == null) error (‘void insertion’) else { int q = get_node( ); node[q].info = x; node[q].next = node[p].next; node[p].next=q; }}void delete::list (int p; int x) { if ( p == 0) error (‘void deletion’); else { int q = node[p].next; x = node[q].info; node[p].next = node[q].next; free_node(q); }}
E.G.M. Petrakis lists, stacks, queues 21
• Linked List implementation: makes use of pointers to elements– Allocates memory for new elements as needed– Each node is a distinct object
• The node class Class link { // A linked-list node public:
ELEM element // node valuelink *next; // pointer to next nodelink(const ELEM& val, link *nextval = NULL);{element = val; next = nextval;}link(link *nextval = NULL) {next = nextval;} ~link( ) { }
}
E.G.M. Petrakis lists, stacks, queues 22
class List { // Linked list class private: Link* head; // Pointer to list header Link* tail; // Pointer to last Elem in list Link* curr; // Position of "current" Elem public: List( ); // Constructor ~List( ); // Destructor void clear( ); // Remove all Elems from list void insert(const Elem); // Insert Elem at current position void append(const Elem); // Insert Elem at tail of list Elem remove( ); // Remove and return current Elem void setFirst( ); // Set curr to first position void prev( ); // Move curr to previous position void next( ); // Move curr to next position int length( ) const; // Return current length of list void setPos(int); // Set curr to specified position void setValue(const Elem); // Set current Elem's value Elem currValue( ) const; // Return current Elem's value bool isEmpty( ) const; // Return TRUE if list is empty bool isInList( ) const; // TRUE if curr is within list bool find(int); // Find value (from current position) };
E.G.M. Petrakis lists, stacks, queues 23
List::List( ) // Constructor { head = new Link; tail = head; curr = head; } // Initialize
List::~List( ) { // Destructor while(head != NULL) { // Return link nodes to free store curr = head; head = headnext; delete curr; } }
void List::clear( ) { // Remove all Elems from list while (headnext != NULL) { // Return link nodes to free
store curr = headnext; // keeps header node !! headnext = currnext; // otherwise, similar to ~List( ) delete curr; } curr = head; tail = head; // Reinitialize }
E.G.M. Petrakis lists, stacks, queues 24
void List::insert(const Elem item) // Insert Elem at current position { assert(curr != NULL); // Must be pointing to list Elem currnext = new Link(item, currnext); if (tail == curr) // Appended new Elem tail = currnext; }
void List::append(const Elem item) // Insert Elem at tail of list { tail = tailnext = new Link(item, NULL); }
Elem List::remove( ) { // Remove and return current Elem assert(isInList( )); // Must be valid position in
list Elem temp = currnextelement; // Remember value Link* ltemp = currnext; // Remember link node currnext = ltempnext; // Remove from list if (tail == ltemp) tail = curr; // Removed last Elem: set tail delete ltemp; // Send link to free store return temp; // Return value removed }
void List::setFirst( ) // Set curr to first position { curr = head; }
E.G.M. Petrakis lists, stacks, queues 25
void List::next( ) // Move curr to next position { if (curr != NULL) curr = currnext; }
void List::prev( ) { // Move curr to previous position
Link* temp = head; if ((curr == NULL) || (curr == head)) // No previous Elem { curr = NULL; return; } // so just return while ((temp!=NULL) && (tempnext != curr)) temp=tempnext; curr = temp; }
int List::length( ) const { // Return current length of list int cnt = 0; for (Link* temp = headnext; temp != NULL; temp = tempnext) cnt++; // Count Elems and return cnt; }
void List::setPos(int pos) { // Set curr to specified position curr = head; for (int i = 0; (curr != NULL) && (i < pos) i++) curr = currnext;}
E.G.M. Petrakis lists, stacks, queues 26
void List::setValue(const Elem val) { // Set current Elem's value assert(isInList()); currnext->element = val; }
Elem List::currValue() const // Return value of current Elem { assert(isInList( )); return currnextelement; }
bool List::isEmpty() const // Return TRUE if list is empty { return headnext == NULL; }
bool List::isInList() const // TRUE if curr is within list { return (curr != NULL) && (currnext != NULL); }
bool List::find(int val) { // Find value (starting at curr) while (isInList( )) if (key(currnext->element) == val) return TRUE; else curr = currnext; return FALSE; // Not found
}
E.G.M. Petrakis lists, stacks, queues 27
• Comparison of implementations– Array-Based Lists:
• Insertion and deletion are (n) instead of (1) • Prev and direct access are (1) instead of (n) • Array must be allocated in advance• No overhead if all array positions are full• Faster in some cases
– Linked Lists:• Insertion and deletion are (1) • Prev and direct access are (n)• Space grows with number of elements• Every element requires overhead
E.G.M. Petrakis lists, stacks, queues 28
• Doubly linked list: allows direct access to both next and previous elements of the current pointer– insert (delete) operations update both next/prev
pointers– Easy implementation
curr next = new (item, currnext, curr);
if (currnext != NULL)
currnextprev = currnext
E.G.M. Petrakis lists, stacks, queues 29
current
current
Insertion in doubly linked list
E.G.M. Petrakis lists, stacks, queues 30
current
current
Deletion from doubly linked list
E.G.M. Petrakis lists, stacks, queues 31
• Circular linked lists: the next pointer of the last element points to the first element– The tail points is no longer needed– Implementation: left as an exercise