CIS210 2
Two Foundational Data Structures
Most ADTs are implemented
Using an array-based indexed (contiguous)
structure
Using some kind of pointer-based linked
structure
Combination of two.
CIS210 3
Data Structures for ADTs
How to store a collection of data?
Array-based indexed structures
Pointer-based linked structures
CIS210 4
Data Structures for ADTs
Where to store a collection of data?
Statically allocated storage
Dynamically allocated storage
CIS210 6
An Array
Contains a fixed maximum number of
elements of the same type in contiguous
storage locations.
Are accessible directly by means of an index
or subscript.
Array
N = The fixed size of the array
0 1 2 3 4 5 6 . . . N-1Index
CIS210 7
Static Arrays
The amount of memory for an array is
allocated at compile time.
Statically allocated from stack!
The size of the array is determined at compile
time.
CIS210 8
Static Arrays in C++
// static array
// TypeName ArrayName [ ArraySize ];
// ArrayName[0] .. ArrayName[ ArraySize-1]
string a[2];
a[0] = “static”;
a[1] = “array”;
string a[] = {“static”, “array”};
//array manipulation
for (i=0; i<=1;i++)
cout << a[i] << endl;
CIS210 9
Dynamic Arrays
The amount of memory for an array is
allocated at run time.
Dynamically allocated from heap!
The size of the array is determined at run time.
CIS210 10
Dynamic Arrays in C++
// dynamic array
string* a ;
a = new string[2];
string* a;
typedef string* StrPtr;
StrPtr a;
cin >> ArraySize;
a = new string[ArraySize];
//array manipulation
for (i=0; i<=ArraySize-1;i++)
cout << a[i] << *(a+i) << endl;
delete [] a;
delete a[]; //illegal
CIS210 11
One-dimensional & Multidimensional Arrays
One-dimensional arrays
Two-dimensional arrays
Matrix
Multidimensional arrays
CIS210 13
Vectors in the STL
A generic flexible one-dimensional array
data structure + its operations
Size can be dynamically changed.
Storage is managed automatically.
CIS210 15
Vectors in the STL
Access in O(1) time
Insert at the end in O(1) time
Delete at the end in O(1) time
Arbitrary insert/ delete at a given position in O(n)
time
Insert at the beginning?
Delete at the beginning?
Insert at the i-th?
Delete at the i-th?
CIS210 16
Vectors in the STL
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional> // greater<>
using namespace std;
void main() {
int a[] = {1,2,3,4,5};
vector<int> v1;
// v1 is empty, size = 0, capacity = 0
for (int j = 1; j <= 5; j++)
v1.push_back(j);
// v1 = (1 2 3 4 5), size = 5, capacity = 8
vector<int> v2(3,7); // v2 = (7 7 7)
CIS210 17
Vectors in the STL
// v1 = (1 2 3 4 5), size = 5, capacity = 8
vector<int>::iterator i1 = v1.begin()+1;
vector<int> v3(i1,i1+2);
// v3 = (2 3), size = 2, capacity = 2
vector<int> v4(v1);
// v4 = (1 2 3 4 5), size = 5, capacity = 5
vector<int> v5(5); // v5 = (0 0 0 0 0)
v5[1] = v5.at(3) = 9; // v5 = (0 9 0 9 0)
CIS210 18
Vectors in the STL
// v3 = (2 3), size = 2, capacity = 2
v3.reserve(6);
// v3 = (2 3), size = 2, capacity = 6
// v4 = (1 2 3 4 5), size = 5, capacity = 5
v4.resize(7);
// v4 = (1 2 3 4 5 0 0), size = 7, capacity = 10
v4.resize(3);
// v4 = (1 2 3), size = 3, capacity = 10
v4.clear();
// v4 is empty, size = 0, capacity = 10 (!)
CIS210 19
Vectors in the STL
// v3 = (2 3), size = 2, capacity = 6
// v4 is empty, size = 0, capacity = 10 (!)
v4.insert(v4.end(),v3[1]); // v4 = (3)
v4.insert(v4.end(),v3.at(1)); // v4 = (3 3)
v4.insert(v4.end(),2,4); // v4 = (3 3 4 4)
// v1 = (1 2 3 4 5), size = 5, capacity = 8
v4.insert(v4.end(),v1.begin()+1,v1.end()-1);
// v4 = (3 3 4 4 2 3 4)
v4.erase(v4.end()-2);
// v4 = (3 3 4 4 2 4)
v4.erase(v4.begin(), v4.begin()+4); // v4 = (2 4)
CIS210 20
Vectors in the STL
// v4 = (2 4)
v4.assign(3,8); // v4 = (8 8 8)
// a = (1,2,3,4,5)
v4.assign(a,a+3); // v4 = (1 2 3)
vector<int>::reverse_iterator i3 = v4.rbegin();
for ( ; i3 != v4.rend(); i3++)
cout << *i3 << ' '; // print: 3 2 1
cout << endl;
CIS210 21
Vectors in the STL
// algorithms
// v5 = (0 9 0 9 0)
v5[0] = 3; // v5 = (3 9 0 9 0)
v5[0] = 3; v5[2] = v5[4] = 0; // v5 = (3 9 0 9 0)
replace(v5.begin(),v5.end(),0,7); // v5 = (3 9 7 9 7)
sort(v5.begin(),v5.end()); // v5 = (3 7 7 9 9)
// functional
sort(v5.begin(),v5.end(),greater<int>()); // v5 = (9 9 7 7 3)
}
CIS210 22
Iterator
How do we allow access to elements in a
container without knowing how the collection
is organized?
CIS210 23
Design Pattern: The Iterator Pattern
Container
Iterator
An iterator is an object of an iterator class!
CIS210 24
Iterator Operations
Overloaded operators!
Inequality compare (!=)
Dereference (*)
Increment (++)
CIS210 25
Iterators for Vectors
vector<int> v1;
vector<int>::iterator p;
for (p=v1.begin();p!= v1.end(); p++)
// Process *p
cout << *p << ” ”;
CIS210 26
Vector & Iterator Class Diagram
Vector VectorIterator
dependency
VectorVectorIterator
or
T T
TT
CIS210 28
Pointer-based Linked Structures
Linear linked structures
Singly-linked lists
Doubly-linked lists
Circular-linked lists
Skip linked lists
Self-organizing linked lists
Data Link … Link
CIS210 29
A Singly Linked List
A list of nodes s.t.
Each node consists of a piece of data and a
link to the next node.
All nodes are linked to one another such that
each node points to the next node in the list.
The pointer field of the final node contains the
null pointer (NULL).
A linked list is able to grow as needed!
CIS210 30
Singly Linked Lists
The access to the nodes in the linked list is
through one or more pointers:
Head pointer - A pointer to the first node.
Tail pointer - A pointer to the last node.
The Null pointer
A pointer that does not point anywhere.
(NULL)
CIS210 32
Int Singly Linked Nodes
class intSLListNode
{
public:intSLListNode() { }
intSLListNode(const int& theData, intSLListNode* theLink)
: data(theData), link(theLink) { }
int data;
intSLListNode* link;
};
CIS210 33
Int Singly Linked Lists
class intSLListNode
{
public:intSLListNode() { }
intSLListNode(const int& theData, intSLListNode* theLink)
: data(theData), link(theLink) { }
int data;
intSLListNode* link;};
class intSLList
{
public:
…
private:
intSLListNode *head;
};
CIS210 34
Singly Linked Lists – Using template
template <class T>
class SLListNode
{
public:SLListNode() { }
SLListNode(const T& theData, SLListNode<T>* theLink)
: data(theData), link(theLink) { }
T data;
SLListNode* link;
};
CIS210 35
Singly Linked Lists – Using template
template <class T>
class SLListNode
{
public:SLListNode() { }
SLListNode(const T& theData, SLListNode<T>* theLink)
: data(theData), link(theLink) { }
T data;
SLListNode* link;};
template <class T>
class SLList
{
public:
…
private:
SLListNode<T> *head;
};
CIS210 36
Singly Linked Lists – Using template
template <class T>
class SLListNode
{
public:
SLListNode() { }
SLListNode(const T& theData, SLListNode<T>* theLink)
: data(theData), link(theLink) { }
SSlistNode<T>* getLink() const {return link;}
const T getData() const {return data;}
void setData(const T& theData) {data = theData;}
void setLink(SLListNode<T>* pointer) {link=pointer;}
private:
T data;
SLListNode* link;};
CIS210 37
Singly Linked Lists – Using template
template <class T>
class SLListNode
{
public:
SLListNode() { }
SLListNode(const T& theData, SLListNode<T>* theLink)
: data(theData), link(theLink) { }
SSlistNode<T>* getLink() const {return link;}
const T getData() const {return data;}
void setData(const T& theData) {data = theData;}
void setLink(SLListNode<T>* pointer) {link=pointer;}
private:
T data;
SLListNode* link;
};
template <class T>
class SLList
{
public:
…
private:
SLListNode<T> *head;
};
CIS210 38
Singly Linked Lists – Using friend
template <class T>
class SLList;
template <class T>
class SLListNode
{
public:
SLListNode() { }
SLListNode(const T& theData, SLListNode<T>* theLink)
: data(theData), link(theLink) { }
friend class SLList<T>;
private:
T data;
SLListNode* link;
};
template <class T>
class SLList
{
public:
…
private:
SLListNode<T> *head;
};
CIS210 39
Variations of Singly Linked Lists
Ordered (sorted) linked list
Circular linked lists
Doubly linked lists
Skip linked lists
Self-organizing linked lists
...
CIS210 43
Lists in the STL
Access in O(n) time
Insert at the end in O(1) time
Delete at the end in O(1) time
Arbitrary insert/ delete at a given position in O(1)
time
Insert at the beginning?
Delete at the beginning?
Insert at the i-th?
Delete at the i-th?
CIS210 44
Lists in the STL
#include <iostream>
#include <list>
#include <algorithm>
#include <functional> // greater<>
using namespace std;
void main() {
list<int> lst1; // lst1 is empty
list<int> lst2(3,7); // lst2 = (7 7 7)
for (int j = 1; j <= 5; j++)
lst1.push_back(j);
// lst1 = (1 2 3 4 5)
CIS210 45
Lists in the STL
// lst1 = (1 2 3 4 5)
list<int>::iterator i1 = lst1.begin(), i2 = i1, i3;
i2++; i2++; i2++;
list<int> lst3(++i1,i2); // lst3 = (2 3)
list<int> lst4(lst1); // lst4 = (1 2 3 4 5)
CIS210 46
Lists in the STL
// lst4 = (1 2 3 4 5)
i1 = lst4.begin();
// lst2 = (7 7 7)
lst4.splice(++i1,lst2);
// lst4 = (1 7 7 7 2 3 4 5), lst2 is empty
lst4.remove(1); // lst4 = (7 7 7 2 3 4 5)
lst4.sort(); // lst4 = (2 3 4 5 7 7 7)
lst4.unique(); // lst4 = (2 3 4 5 7)
CIS210 47
Lists in the STL
// lst1 = (1 2 3 4 5)
// lst2 = (3 4 5)
lst1.merge(lst2);
// lst1 = (1 2 3 3 4 4 5 5), lst2 is empty
// lst3 = (2 3)
lst3.reverse(); // lst3 = (3 2)
// lst4 = (2 3 4 5 7)
lst4.reverse(); // lst4 = (7 5 4 3 2)
lst3.merge(lst4,greater<int>());
// lst3 = (7 5 4 3 3 2 2), lst4 is empty
}
CIS210 48
Design Pattern: The Iterator Pattern
Container
Iterator
An iterator is an object of an iterator class!
CIS210 49
Iterators for Lists
list<int> l1;
list<int>::iterator p;
for (p=l1.begin();p!=l1.end(); p++)
// Process *p
cout << *p << ” ”;
CIS210 52
Vector vs List in the STL
Vectors:
at(), capacity(), reserve()
Lists:
More other member functions
CIS210 53
Array Data Structures
fast access to elements
expensive to insert/remove elements
have fixed, maximum size
CIS210 54
Static Array-based Implementation
Can you predict in advance the maximum
number of data items in the ADT for a given
application?
Would you waste storage by declaring an
array to be large enough to accommodate the
maximum number of data items?
CIS210 55
Dynamic Array-based Implementation
We do not have to predict in advance the
maximum number of data items in the ADT
for a given application.
But, increasing the size of a dynamically array
can waste both storage and time!
CIS210 56
Linked Data Structures
fast insertion/deletion of element
slower access to elements
have flexible size (Size can vary during run-
time)
CIS210 58
A List ADT
A Linear Container
A collection (container) of data items of the
same type.
A list is a very simple, useful and common
abstract data type.
Two kinds of lists:
Unsorted lists
Sorted lists
CIS210 59
Unsorted List
An unsortedlist is a container which holds a
sequence of items.
The data organization is linear in that items
are one after another.
CIS210 60
Operations on an Unsorted_list
Create an empty list.
Insert an item in the list.
Find an item in the list.
Retrieve the item in the list.
Delete the item in the list.
Determine whether a list empty?
Determine the number of items (length) in a list?
Destroy a list.
...
CIS210 61
How to Represent an Unsorted_List ADT?
Array-based representation
Implementation via (statically allocated) array
Implementation via (dynamically allocated)
array
Pointer-based representation
Implementation via pointer (linear linked-list)
CIS210 63
List ADT
//--------------------------------------------------------------------
// listarr.h
// Class declaration for the array implementation of the List ADT
//--------------------------------------------------------------------
using namespace std;
const int defMaxListSize = 10; // Default maximum list size
typedef char DataType;
CIS210 64
List ADT
class List
{
public:
// Constructor
List ( int maxNumber = defMaxListSize );
// Destructor
~List ();
CIS210 65
List ADT
// List manipulation operations
void insert ( const DataType &newDataItem );
// Insert after cursor
void replace ( const DataType &newDataItem );
// Replace data item
void clear ();
// Clear list
CIS210 66
List ADT
// List status operations
bool isEmpty () const; // List is empty
bool isFull () const; // List is full
CIS210 67
List ADT
// List iteration operations
void gotoBeginning (); // Go to beginning
void gotoEnd (); // Go to end
bool gotoNext (); // Go to next data item
bool gotoPrior (); // Go to prior data item
DataType getCursor () const; // Return data item
CIS210 68
List ADT
// Output the list structure -- used in testing/debugging
void showStructure () const;
void moveToNth ( int n );
// Move data item to pos. n
bool find ( const DataType &searchDataItem );
// Find data item
CIS210 69
List ADT
private:
// Data members
int maxSize,
size, // Actual number of data item in the list
cursor; // Cursor array index
DataType *dataItems; // Array containing the list data item
};
CIS210 70
List ADT
List:: List ( int maxNumber )
// Creates an empty list.
//Allocates enough memory for maxNumber
// data items (defaults to defMaxListSize).
: maxSize(maxNumber),
size(0),
cursor(-1)
{
dataItems = new DataType[maxSize];
}
CIS210 71
List ADT
void List:: insert ( const DataType &newDataItem )
// Inserts newDataItem after the cursor.
{
int j; // Loop counter
for ( j = size ; j > cursor+1 ; j-- )
dataItems[j] = dataItems[j-1];
size++;
dataItems[++cursor] = newDataItem;
}
CIS210 72
List ADT
bool List:: find ( const DataType &searchDataItem )
// Searches a list for searchDataItem. Begins the search with the
// data items marked by the cursor.
{
while ( cursor < size && dataItems[cursor] != searchDataItem )
cursor++;
if ( cursor < size )
return true;
else
{ cursor--; return false;}
}
73
QUIZ: List ADT - Destructor
// Default destructor
// Shallow deallocate!
List:: ~List ()
{
?
}CIS210
CIS210 74
List ADT - Destructor
List:: ~List ()
// Frees the memory used by a list.
{
delete [] dataItems;
}
CIS210 75
QUIZ: List ADT – Copy Constructor
// Default copy constructor
// Shallow copy!
List:: List ( const List &srcList )
{
?
}
CIS210 76
QUIZ: List ADT – Overloaded Assignment Operator
// Default overloaded assignment operator
// Shallow copy!
const List & List:: operator = ( const List &rightList )
{
if ( this == &rightList ) // Check that not assigning to self
return *this;
?
}
CIS210 78
List ADT
//--------------------------------------------------------------------
// listlnk.h
// Class declarations for the linked list implementation of the
// List ADT
//--------------------------------------------------------------------
using namespace std;
CIS210 80
List ADT
template < class DT >
class ListNode // Facilitator class for the List class
{
private:
// Constructor
ListNode ( const DT &nodeData, ListNode *nextPtr );
// Data members
DT dataItem; // List data item
ListNode<DT> *next; // Pointer to the next list node
friend class List<DT>;
};
CIS210 81
List ADT
template < class DT >
ListNode<DT>:: ListNode
( const DT &nodeDataItem, ListNode<DT> *nextPtr )
// Creates a list node containing item elem and next pointer
// nextPtr.
: dataItem(nodeDataItem),
next(nextPtr)
{
}
CIS210 82
List ADT
template < class DT >
class List
{
public:
// Constructor
List ( int ignored = 0 );
// Destructor
~List ();
CIS210 83
List ADT
// List manipulation operations
void insert ( const DT &newData );
// Insert after cursor
// Replace data item
void replace ( const DT &newData );
// Clear list
void clear ();
CIS210 84
List ADT
// List status operations
bool isEmpty () const; // List is empty
bool isFull () const; // List is full
CIS210 85
List ADT
// List iteration operations
void gotoBeginning (); // Go to beginning
void gotoEnd (); // Go to end
bool gotoNext (); // Go to next data item
bool gotoPrior (); // Go to prior item
DT getCursor () const; // Return item
CIS210 86
List ADT
// Output the list structure -- used in testing/debugging
void showStructure () const;
void moveToBeginning (); // Move to beginning
CIS210 87
List ADT
private:
// Data members
ListNode<DT> *head, // Pointer to the beginning of the list
*cursor; // Cursor pointer
};
CIS210 88
List ADT
template < class DT >
List<DT>:: List ( int ignored )
// Creates an empty list.
// The argument is included for compatibility
// with the array implementation and is ignored.
: head(0),
cursor(0)
{}
CIS210 89
List ADT
template < class DT >
void List<DT>:: insert ( const DT &newDataItem )
// Inserts newDataItem after the cursor.
{
if ( head == 0 ) // Empty list
{
head = new ListNode<DT>(newDataItem,0);
cursor = head;
}
else // After cursor
{
cursor->next = new ListNode<DT>(newDataItem,cursor->next);
cursor = cursor->next;
}
}
CIS210 90
List ADT – Destructor !!!
// Destructor
// Frees the memory used by a list.
List<DT>:: ~List ()
// Default destructor
// Shallow deallocate!
CIS210 91
List ADT - Destructor
template < class DT >
List<DT>:: ~List ()
// Frees the memory used by a list.
{
clear ();
}
CIS210 92
List ADT - Destructor
template < class DT >
void List<DT>:: clear ()
// Removes all the items from a list.
{
ListNode<DT> *p, // Points to successive nodes
*nextP; // Points to next node
p = head;
while ( p != 0 )
{
nextP = p->next;
delete p;
p = nextP;
}
head = 0; cursor = 0;
}
CIS210 93
List ADT – Copy Constructor !!!
// Copy constructor
List ( const List<DT> &srcList );
// Default copy constructor
// Shallow copy!
CIS210 94
List ADT – Copy Constructor
template < class DT >
List<DT>:: List ( const List<DT> &srcList )
: head(0),
cursor(0)
{
ListNode<DT> *ptr,
*holdCursor;
ptr = srcList.head;
holdCursor = NULL;
while( ptr != NULL )
{
insert( ptr->dataItem );
if( ptr == srcList.cursor )
holdCursor = cursor;
ptr = ptr->next;
}
cursor = holdCursor;
}
CIS210 95
List ADT – Overloaded Assignment Operator !!!
// Overloaded assignment operator
const List<DT> & operator= ( const List<DT> &srcList );
// Default overloaded assignment operator
// Shallow copy!
CIS210 96
List ADT – Overloaded Assignment Operator
template < class DT >
const List<DT> & List<DT>:: operator = ( const List<DT> &rightList
// Sets the list to have the same/equivalent contents
// as another list.
{
if( this == &rightList ) // Check that not assigning to self
return *this;
clear();
ListNode<DT> *ptr,
*holdCursor;
ptr = rightList.head;
holdCursor = NULL;
CIS210 97
List ADT – Overloaded Assignment Operator
while( ptr != NULL )
{
insert( ptr->dataItem );
if( ptr == rightList.cursor )
holdCursor = cursor;
ptr = ptr->next;
}
cursor = holdCursor;
return *this;
}
CIS210 98
The Big Three !!!
Need any of three, then need all!!!
Copy constructor
• List ( const List<DT> &srcList );
Destructor
• ~List ();
Overloaded assignment operator
• const List<DT> & operator= ( const List<DT>
&srcList );
CIS210 100
List ADT
template < class DT >
class ListNode // Facilitator class for the List class
{
private:
// Constructor
ListNode ( const DT &data,
ListNode *priorPtr, ListNode *nextPtr );
// Data members
DT dataItem; // List data item
ListNode<DT> *prior, // Pointer to the previous data item
*next; // Pointer to the next data item
friend class List<DT>;
};