2. 2
ROAD MAP
īŽ Abstract Data Types (ADT)
īŽ The List ADT
īŽ Implementation of Lists
īŽ
Array implementation of lists
īŽ
Linked list implementation of lists
īŽ
Cursor implementation of lists
3. 3
Abstract Data Types (ADT)
īŽ Definition :
Is a set of operation
Mathematical abstraction
No implementation detail
īŽ Example :
Lists, sets, graphs, stacks are examples of
ADT along with their operations
4. 4
Why ADT ?
īŽ Modularity
īŽ divide program into small functions
īŽ easy to debug and maintain
īŽ easy to modify
īŽ group work
īŽ Reuse
īŽ do some operations only once
īŽ Easy to change of implementation
īŽ transparent to the program
5. 5
THE LIST ADT
īŽ Ordered sequence of data items called
elements
īŽ A1, A2, A3, âĻ,AN is a list of size N
īŽ size of an empty list is 0
īŽ Ai+1 succeeds Ai
īŽ Ai-1 preceeds Ai
īŽ position of Ai is i
īŽ first element is A1 called âheadâ
īŽ last element is AN called âtailâ
Operations ?
6. 6
THE LIST ADT
īŽ Operations
īŽ PrintList
īŽ Find
īŽ FindKth
īŽ Insert
īŽ Delete
īŽ Next
īŽ Previous
īŽ MakeEmpty
7. 7
THE LIST ADT
īŽ Example:
the elements of a list are
34, 12, 52, 16, 12
īŽ Find (52) ī 3
īŽ Insert (20, 3) ī 34, 12, 52, 20, 16, 12
īŽ Delete (52) ī 34, 12, 20, 16, 12
īŽ FindKth (3) ī 20
9. 9
ROAD MAP
īŽ Abstract Data Types (ADT)
īŽ The List ADT
īŽ Implementation of Lists
īŽ
Array implementation of lists
īŽ
Linked list implementation of lists
īŽ
Cursor implementation of lists
10. 10
Array Implementation of List ADT
īŽ Need to define a size for array
īŽ High overestimate (waste of space)
īŽ Operations Running Times
PrintList O(N)
Find
Insert O(N) (on avarage half needs to be moved)
Delete
FindKth
Next O(1)
Previous
11. 11
Array Implementation of List ADT
īŽ Disadvantages :
īŽ insertion and deletion is very slow
īŽ
need to move elements of the list
īŽ redundant memory space
īŽ
it is difficult to estimate the size of array
12. 12
ROAD MAP
īŽ Abstract Data Types (ADT)
īŽ The List ADT
īŽ Implementation of Lists
īŽ
Array implementation of lists
īŽ
Linked list implementation of lists
īŽ
Cursor implementation of lists
13. 13
Linked List Implementation of Lists
īŽ Series of nodes
īŽ not adjacent in memory
īŽ contain the element and a pointer to a node containing its
succesor
īŽ Avoids the linear cost of insertion and deletion !
16. 16
Linked List Implementation of Lists
īŽ Need to know where the first node is
īŽ the rest of the nodes can be accessed
īŽ No need to move the list for insertion and
deletion operations
īŽ No memory waste
17. 17
Linked List Implementation of Lists
Linked List Array
PrintList O(N) (traverse the list)
O(N)
Find
FindKth (L,i) O(i)
O(1)
Delete O(1)
O(N)
18. 18
Programming Details
īŽ There are 3 special cases for linked lists
īŽ Insert an element at the front of the list
īŽ
there is no really obvious way
īŽ Delete an element from the front of the list
īŽ
changes the start of the list
īŽ Delete an element in general
īŽ
requires to keep track of the node before the deleted one
How can we solve these three problems ?
19. 19
Programming Details
Keep a header node in position 0
īŽ Write a FindPrevious routine
īŽ returns the predecessor of the cell
īŽ To delete the first element
īŽ FindPrevious routine returns the position of
header
Use of header node is controversial !
20. 20
Type decleration for link list node
template <class Object>
class List; // Incomplete declaration.
template <class Object>
class ListItr; // Incomplete declaration.
template <class Object>
class ListNode {
ListNode( const Object & theElement = Object( ),
ListNode*n=NULL) : element(theElement),next(n)
{}
Object element;
ListNode *next;
friend class List<Object>;
friend class ListItr<Object>;
};
21. 21
Iterator class for linked lists
template <class Object>
class ListItr {
public:
ListItr( ) : current( NULL ) { }
bool isPastEnd( ) const { return current == NULL; }
void advance( )
{ if( !isPastEnd( ) ) current = current->next; }
const Object & retrieve( ) const
{ if( isPastEnd( ) )
throw BadIterator( );
return current->element; }
private:
ListNode<Object> *current; // Current position
ListItr(ListNode<Object> *theNode):current( theNode ) { }
friend class List<Object>; // Grant access to constructor
};
22. 22
List class interface
template <class Object>
class List {
public:
List( );
List( const List & rhs );
~List( );
bool isEmpty( ) const;
void makeEmpty( );
ListItr<Object> zeroth( ) const;
ListItr<Object> first( ) const;
void insert( const Object & x, const ListItr<Object> & p );
ListItr<Object> find( const Object & x ) const;
ListItr<Object> findPrevious( const Object & x ) const;
void remove( const Object & x );
const List & operator=( const List & rhs );
private:
ListNode<Object> *header;
};
23. 23
Function to print a list
template <class Object>
void printList( const List<Object> &the List)
{
if (theList.isEmpty())
cout<< âEmpty listâ << endl;
else
{
ListItr<Object> itr = theList.first();
for (; !itr.isPastEnd(); itr.advance())
cout << itr.retrieve() <<â â;
}
cout << endl;
}
24. 24
Some list one-liners
/* Construct the list */
template <class Object>
List<Object>::List( )
{
header = new ListNode<Object>;
}
/* Test if the list is logically empty */
template <class Object>
bool List<Object>::isEmpty( ) const
{
return header->next == NULL;
}
25. 25
Some list one liners
/* Return an iterator representing the header node
template <class Object>
ListItr<Object> List<Object>::zeroth( ) const
{
return ListItr<Object>( header );
}
/* Return an iterator representing the first node
in the list. This operation is valid for empty
lists. */
template <class Object>
ListItr<Object> List<Object>::first( ) const
{
return ListItr<Object>( header->next );
}
26. 26
Find routine
/* Return iterator corresponding to the first
node containing an item x. Iterator isPastEnd
if item is not found. */
template <class Object>
ListItr<Object> List<Object>::find( const
Object & x ) const
{
ListNode<Object> *itr = header->next;
while( itr != NULL && itr->element != x )
itr = itr->next;
return ListItr<Object>( itr );
}
27. 27
Deletion routine for linked lists
/* Remove the first occurrence of an item x. */
template <class Object>
void List<Object>::remove( const Object & x )
{
ListItr<Object> p = findPrevious( x );
if( p.current->next != NULL )
{
ListNode<Object> *oldNode = p.current->next;
p.current->next = p.current->next->next;
delete oldNode;
}
}
28. 28
findPrevious-the find routine for
use with remove
/*Return iterator prior to the first node containing an
item x.
template <class Object>
ListItr<Object> List<Object>::findPrevious( const Object &
x ) const
{
ListNode<Object> *itr = header;
while( itr->next != NULL && itr->next->element != x )
itr = itr->next;
return ListItr<Object>( itr );
}
29. 29
Insertion routine for linked lists
/* Insert item x after p. */
template <class Object>
void List<Object>::insert( const Object & x,
const ListItr<Object> & p )
{
if( p.current != NULL )
p.current->next = new ListNode<Object>
( x, p.current->next );
}
30. 30
makeEmpty and List destructor
/* Make the list logically empty. */
template <class Object>
void List<Object>::makeEmpty( )
{
while( !isEmpty( ) )
remove( first( ).retrieve( ) );
}
/* Destructor */
template <class Object>
List<Object>::~List( )
{
makeEmpty( );
delete header;
}
33. 33
Doubly Linked List
īŽ Traversing list backwards
īŽ not easy with regular lists
īŽ Insertion and deletion more pointer fixing
īŽ Deletion is easier
īŽ Previous node is easy to find
35. 35
ROAD MAP
īŽ Abstract Data Types (ADT)
īŽ The List ADT
īŽ Implementation of Lists
īŽ
Array implementation of lists
īŽ
Linked list implementation of lists
īŽ
Cursor implementation of lists
36. 36
Cursor Implementation of Linked List
Problems with linked list implementation:
īŽ Same language do not support pointers !
īŽ Then how can you use linked lists ?
īŽ new and free operations are slow
īŽ Actually not constant time
38. 38
Cursor Implementation of Linked List
īŽ Cursor operation simulates the features
īŽ Collection of structures
īŽ
uses array for nodes
īŽ Array index is pointer
īŽ new and delete operation
īŽ
Keep a free list
īŽ new returns an element from freelist
īŽ delete place the node in freelist
īŽ
Freelist
īŽ Use cell 0 as header
īŽ All nodes are free initially
īŽ 0 is a NULL pointer
39. 39
Cursor Implementation of Linked List
If L = 5, then L represents list (A, B, E)
If M = 3, then M represents list (C, D, F)
40. 40
Iterator for cursor implementation
of linked lists
template <class Object>
class ListItr
{
public:
ListItr( ) : current( 0 ) { }
bool isPastEnd( ) const {return current == 0; }
void advance( ){
if( !isPastEnd( ) )
current = List<Object>::cursorSpace[ current ].next; }
const Object & retrieve( ) const {
if( isPastEnd( ) ) throw BadIterator( );
return List<Object>::cursorSpace[ current ].element; }
private:
int current; // Current position
friend class List<Object>;
ListItr( int theNode ) : current( theNode ) { }
};
41. 41
Class skeleton for cursor-based List
template <class Object>
class ListItr; // Incomplete declaration.
template <class Object>
class List
{
public:
List( );
List( const List & rhs );
~List( );
bool isEmpty( ) const;
void makeEmpty( );
ListItr<Object> zeroth( ) const;
ListItr<Object> first( ) const;
void insert( const Object & x, const ListItr<Object> & p );
ListItr<Object> find( const Object & x ) const;
ListItr<Object> findPrevious( const Object & x ) const;
void remove( const Object & x );
42. 42
Class skeleton for cursor-based List
public:
struct CursorNode
{
CursorNode( ) : next( 0 ) { }
private:
CursorNode( const Object & theElement, int n )
: element( theElement ), next( n ) {}
Object element;
int next;
friend class List<Object>;
friend class ListItr<Object>;
};
const List & operator=( const List & rhs );
43. 43
Class skeleton for cursor-based List
private:
int header;
static vector<CursorNode> cursorSpace;
static void initializeCursorSpace( );
static int alloc( );
static void free( int p );
friend class ListItr<Object>;
};
44. 44
cursorSpace initialization
/* Routine to initialize the cursorSpace. */
template <class Object>
void List<Object>::initializeCursorSpace( )
{
static int cursorSpaceIsInitialized = false;
if( !cursorSpaceIsInitialized )
{
cursorSpace.resize( 100 );
for( int i = 0; i < cursorSpace.size( ); i++ )
cursorSpace[ i ].next = i + 1;
cursorSpace[ cursorSpace.size( ) - 1 ].next = 0;
cursorSpaceIsInitialized = true;
}
}
45. 45
Routines : alloc and free
/* Allocate a CursorNode
template <class Object>
int List<Object>::alloc( )
{
int p = cursorSpace[ 0 ].next;
cursorSpace[ 0 ].next = cursorSpace[ p ].next;
return p;
}
/* Free a CursorNode
template <class Object>
void List<Object>::free( int p )
{
cursorSpace[ p ].next = cursorSpace[ 0 ].next;
cursorSpace[ 0 ].next = p;
}
46. 46
Short routines for cursor-based lists
/* Construct the list
template <class Object>
List<Object>::List( )
{
initializeCursorSpace( );
header = alloc( );
cursorSpace[ header ].next = 0;
}
/* Destroy the list
template <class Object>
List<Object>::~List( )
{
makeEmpty( );
free( header );
}
47. 47
Short routines for cursor-based lists
/* Test if the list is logically empty. return true if
empty
template <class Object>
bool List<Object>::isEmpty( ) const
{
return cursorSpace[ header ].next == 0;
}
/* Return an iterator representing the first node in
the list. This operation is valid for empty lists.
template <class Object>
ListItr<Object> List<Object>::first( ) const
{
return ListItr<Object>( cursorSpace[ header ].next );
}
48. 48
find routine - cursor implementation
/*Return iterator corresponding to the first node containing
an item x. Iterator isPastEnd if item is not found.
template <class Object>
ListItr<Object> List<Object>::find( const Object & x ) const
{
int itr = cursorSpace[ header ].next;
while( itr != 0 && cursorSpace[ itr ].element != x )
itr = cursorSpace[ itr ].next;
return ListItr<Object>( itr );
}