Sunteți pe pagina 1din 31

Bilgisayar Mühendisliği Bölümü

DATA STRUCTURES
AND
ALGORITHMS

Lecture Notes 7
Sequential Containers

Spring 2008

GIT – Computer Engineering Department


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 delete operations are slow
– Actually not constant time

GIT – Computer Engineering Department Simulation - Lecture Notes 6 2


Cursor Implementation of Linked List

SOLUTION: Implement linked list on an array called


CURSOR

GIT – Computer Engineering Department Simulation - Lecture Notes 6 3


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

GIT – Computer Engineering Department Simulation - Lecture Notes 6 4


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)

GIT – Computer Engineering Department Simulation - Lecture Notes 6 5


An Application: Ordered Lists

 Want to maintain a list of names


 Want them in alphabetical order at all
times
 Approach: Develop an Ordered_List
class
– For reuse, good if can work with other types:

GIT – Computer Engineering Department Simulation - Lecture Notes 6 6


Design of the Ordered_List class

Data Field Attribute


std::list<Item_Type> a_list A linked list to contain the data
Function Behavior
Inserts item into the list preserving the list’s
void insert(const Item_Type& item)
order
Return a const_iterator to the beginning
const_iterator begin()
of the list
Return a const_iterator to the end of the
const_iterator end()
list
size_t size() const Returns the size of the list.
public void remove(const Item_Type&
item) Removes item from the list.

GIT – Computer Engineering Department Simulation - Lecture Notes 6 7


Algorithm for Insertion
1. Find the first item in the list that is greater
than or equal to the item to be inserted.
2. Insert the new item before this one.

GIT – Computer Engineering Department Simulation - Lecture Notes 6 8


Refinement of algorithm
1.1 Create an iterator that starts at the
beginning of the list
1.2 while the iterator is not at the end, and the
item at the iterator position is less than the
item to be inserted
1.3 Advance the iterator
2. Insert the new item before the current
iterator position

GIT – Computer Engineering Department Simulation - Lecture Notes 6 9


Inserting "Bill" before "Caryn"

GIT – Computer Engineering Department Simulation - Lecture Notes 6 10


Ordered_List::insert
void insert(const Item_Type& an_item) {
typename std::list<Item_Type>::iterator itr =
a_list.begin();
while (itr != a_list.end() && *itr < an_item)
++itr;
// itr points to the first item >= an_item or the
end.
a_list.insert(itr, an_item);
}

GIT – Computer Engineering Department Simulation - Lecture Notes 6 11


Standard Library Containers

GIT – Computer Engineering Department Simulation - Lecture Notes 6 12


Common Requirements for Containers

typedefs Meaning
value_type The type of the object stored in the container.
iterator An iterator appropriate for the container.
const_iterator A const_iterator appropriate for the container
Constructors Purpose
X() Default constructor where X is the container type.
X(a)
Copy constructor where X is the container type and a is
an object of this type.
Functions Behavior
~X() Destructor
X& operator=(const X& a) Assignment operator
bool operator==(const X& a) const Equality operator
bool operator!=(const X& a) const Negation of equals
bool operator<(const X& a) const
bool operator>(const X& a) const Comparison operators. Compares each item in the two
bool operator<=(const X& a) const containers. Objects must implement < operator.
bool operator>=(const X& a) const
void swap(X& a) Swap the contents of this container with the other.
iterator begin()
const_iterator() begin() const Return an iterator to the beginning of the container
iterator end()
const_iterator end() const Return an iterator to one past the end of the container
size_t size() const Return the number of objects in the container
bool empty() const Returns true if the container is empty.

GIT – Computer Engineering Department Simulation - Lecture Notes 6 13


Common Requirements for Sequences
Constructors Purpose
X(size_t num, const Item_Type& initial)
Constructs the container of type X containing num
copies of initial.
Constructs the container of type X containing a copy of
X(const_iterator start, const_iterator stop) the items starting with the object referenced by start
and continuing up to but not including stop.
Functions Behavior
iterator insert(iterator pos, Insert a copy of item into the container before position
const Item_Type& item) pos. Return an iterator referencing the inserted object.
iterator erase(iterator pos)
Remove the item referenced by the iterator at pos.
Returns an iterator to the item following pos.
Item_Type& front()
const Item_Type& front() const Returns a reference to the first item in the container.
Item_Type& back()
const Item_Type back() const Returns a reference to the last item in the container
void push_back(const Item_Type& item) Insert a new item as the last item in the container.
void pop_back() Remove the last item from the container

GIT – Computer Engineering Department Simulation - Lecture Notes 6 14


Requirements Applicable to Some Sequences

Functions Behavior Required by


void push_front(const
Insert a new item as the first item in the container list, deque
Item_Type& item)
void pop_front() Remove the first item from the container list, deque
Item_Type&
operator[](size_t index) Randomly access an item in the container via an vector, deque
const Item_Type& index.
operator[](size_t index) const
Item_Type& Randomly access an item in the container via an
at(size_t index) vector, deque
const Item_Type& index. If the index is out of bounds (>= size())
at(size_t index) const throw invalid argument exception.

GIT – Computer Engineering Department Simulation - Lecture Notes 6 15


The Standard Library Algorithms
 Function to find an Item_Type in a list<Item_Type>
list<Item_Type>::iterator find(list<Item_Type>& a_list,
Item_Type target) {
for (list<Item_Type>::iterator itr = a_list.begin();
itr != a_list.end(); ++itr) {
if (*itr == target)
return itr;
}
return a_list.end();
}

 Observe that this function only works


for Item_Type.

GIT – Computer Engineering Department Simulation - Lecture Notes 6 16


Template version of find
template <typename Item_Type>
list<Item_Type>::iterator find(list<Item_Type>& a_list,
const Item_Type& target) {
typedef typename list<Item_Type>::iterator iterator;
for (iterator itr = a_list.begin(); itr != a_list.end();
++itr) {
if (*itr == target)
return itr;
}
return a_list.end();
}

 This only works for a vector.


 What if we want to search a list?

GIT – Computer Engineering Department Simulation - Lecture Notes 6 17


General Version of find
template <typename Iterator, typename Item_Type>
Iterator find(Iterator first, Iterator last,
const Item_Type& target) {
while (first != last) {
if (*first == target)
return first;
}
return first;
}
 first references the first item in the sequence
 last references one past the last item in the
sequence

GIT – Computer Engineering Department Simulation - Lecture Notes 6 18


The algorithm library
 The standard library header <algorithm>
defines several template functions.
 These perform fairly standard operation on
sequences within containers
– find an item (find)
– apply a function to each item (for_each)
– copy values from one container to another (copy)
– sort the contents of a container (sort)

GIT – Computer Engineering Department Simulation - Lecture Notes 6 19


Why use algorithm library
 Most of the algorithms in <algorithm> are
fairly simple.
 Why not code them in-line in your program
yourself?
– No need to “reinvent the wheel”
– While they are fairly simple, they have all been
thoroughly tested.
– Compiler can generate more optimal code from
standard library

GIT – Computer Engineering Department Simulation - Lecture Notes 6 20


Selected Members of <algorithm>
Function Behavior
template<typename II, typename F> Applies the function fun to each
F for_each(II first, II last, F fun)
object in the sequence. The function
fun is not supposed to modify its
argument. The iterator argument
II is required to be an input iterator.
This means that the sequence is
traversed only once.
template<typename II, typename T> Finds the first occurrence of target
II find(II first, II last, T target)
in the sequence. If not found, last is
returned.
template<typename II, typename P> Finds the first occurrence of an item
II find_if(II first, II last, P pred)
in the sequence for which function
pred returns true. If not found, last
is returned.
template<typename FI> Finds the min/max element in the
FI min_element(FI first, FI last);
template<typename FI> sequence first..last. FI is a
FI max_element(FI first, FI last) forward iterator.

GIT – Computer Engineering Department Simulation - Lecture Notes 6 21


Function Behavior
template<typename II, typename OI> Copies the sequence first..last
OI copy(II first, II last, OI result)
into result..(result + (last -
first)). II is an input iterator, and
OI is an output iterator.
template<typename II, typename OI, Applies op to each element of the
typename OP>
OI transform(II first, II last, OI sequence first..last and places
result, OP op) the result in result..(result +
(last - first)).
template<typename II1, typename Applies bin_op to each pair of
II2,typename OI, typename BOP>
OI transform(II1 first1, II1 last1, elements of the sequences
II2 first2, OI result, BOP bin_op) first1..last1 and
first2..(first2 + (last1 -
first1)) and places the result in
result..(result + (last1 -
first1))
template<typename T> Exchanges the contents of a and b.
void swap(T& a, T& b)
template<typename FI1, typename FI2> Exchanges the values referenced by
void iter_swap(FI1 a, FI1 b)
iterators a and b.
template<typename BI> Reverses the sequence first..last.
void reverse(BI first, BI last)
BI is a bidirectional iterator.

GIT – Computer Engineering Department Simulation - Lecture Notes 6 22


Function Behavior
template<typename RI> Randomly rearranges the contents of
void random_shuffle(RI first, RI last)
first..last. RI is a random-access
iterator.
template<typename RI> Sorts the contents of first..last
void sort(RI first, RI last)
based on the less-than operator
applied to pairs of elements.
template<typename RI, typename COMP> Sorts the contents of first..last
void sort(RI first, RI last,
COMP comp) based on the binary operator COMP (a
function operator). COMP is a function
class that takes two arguments and
returns a bool.
template<typename II, typename T> Computes init plus the sum of the
T accumulate(II first, II last,
T init) elements in first..last. Note that
this function is defined in the header
<numeric>.
template<typename II1, typename II2> Compares each element in the
bool equal(II1 first1, II1 last1, II2
first2); sequence first1..last1 to the
template<typename II1, typename II2, corresponding elements in the
typename BP) sequence first2..first2 +
bool equal(II1 first1, II1 last2, II2
first2, BP pred) (last1 - first1). If they are all
equal, then this returns true. The
second form uses the function object
pred to perform the comparison.

GIT – Computer Engineering Department Simulation - Lecture Notes 6 23


Copy one a list to a vector

a_vector.resize(a_list.size());
copy(a_list.begin(), a_list.end(),
a_vector.begin());

GIT – Computer Engineering Department Simulation - Lecture Notes 6 24


A more complicated example
// Sort a vector
sort(a_vector.begin(), a_vector.end());
// Accumulate the sum
int sum = accumulate(a_vector.begin(), a_vector.end(),
0);
cout << "Sum is " << sum << endl;
// Check first element to see if it is the smallest
if (*a_vector.begin() !=
*min_element(a_vector.begin(), a_vector.end())
cerr << "Error in sort\n";
// Check last element to see if it is the largest
if (*--a_vector.end() !=
*max_element(a_vector.begin(), a_vector.end())
cerr << "Error in sort\n";

GIT – Computer Engineering Department Simulation - Lecture Notes 6 25


Specializing the swap function
 Swap is defined as:
template <typename T>
void swap(T& x, T& y) {
T temp(x); // Make copy of x
x = y;
y = temp;
}

 What if we call this with


swap(vector1, vector2);

 This will expand to:


vector<int> temp(vector1); //Make a copy of vector 1
vector1 = vector2; //Make a copy of vector 2
vector2 = temp; //Make a copy of temp

GIT – Computer Engineering Department Simulation - Lecture Notes 6 26


Specializing swap (2)
 The vector (and all other containers) define a member
function swap that swaps the contents without copying.
 Therefore, we need to define a swap function for vector (and
the other containers) that will call this member function:
template<typename
template<typename Item_Type>
Item_Type>
inline void swap(vector<
swap(vector<Item_Type>&
Item_Type>& x,
vector<Item_Type
vector<Item_Type&
Item_Type& y) {
x.swap(y);
x.swap(y);
}
 Then the call
swap(vector1, vector2)
will expand to
vector1.swap(vector2);
 This is called a template specialization
 The definition is placed in the <vector> header.
 A specialization of swap is defined for each container.

GIT – Computer Engineering Department Simulation - Lecture Notes 6 27


Function Objects
 If f is a function, then the expression
f(x)
 will call this function with the parameter x.
 A class may overload the function call operator
(operator()).
class Divisible_By {
private:
int divisor;
public:
Divisible_By(int x) : divisor(x)
divisor(x) {}
bool operator()(int x) {
return x % divisor == 0;
}
};
 A class that defines operator() is known as a function class.
 An object of a function class is known as a function object.
 A function object can be used like a function.
GIT – Computer Engineering Department Simulation - Lecture Notes 6 28
The find_if function
 Recall the find function searched a container for a
target value.
 The find_if funciton searches a container for a
value that satisfies a given condition (predicate)
template<typename Iterator, typename P>
Iterator find_if(Iterator first, Iterator last, P pred)
{
while (first != last) {
if (pred(*first))
return first;
++first;
}
return first;
}
GIT – Computer Engineering Department Simulation - Lecture Notes 6 29
Using find_if and Divisible_By
// Find the first number divisible by 3
list<int>::iterator iter;
iter = find_if(list_1.begin(), list_1.end(), Divisible_By(3));
if (iter != list_1.end())
cout << "First number divisible by 3 is " << *iter << endl;
else
cout << "No number is divisible by 3\n";
// Find the first number divisible by 5
iter = find_if(list_1.begin(), list_1.end(), Divisible_By(5));
if (iter != list_1.end())
cout << "First number divisible by 5 is " << *iter << endl;
else
cout << "No number is divisible by 5\n";
// Find the first number divisible by 3

GIT – Computer Engineering Department Simulation - Lecture Notes 6 30


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)


Insert

GIT – Computer Engineering Department Simulation - Lecture Notes 6 31