Sunteți pe pagina 1din 39

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

DATA STRUCTURES
AND
ALGORITHMS

Lecture Notes 5
Sequential Containers

Spring 2008

GIT – Computer Engineering Department


ROAD MAP
 Abstract Data Types (ADT)
 Sequential Containers
– The Vector ADT
– Implementation of Vector

GIT – Computer Engineering Department Simulation - Lecture Notes 5 2


Abstract Data Types (ADT)
 Definition: An ADT is a set of objects with a set of
operations

 Mathematical abstraction
– Data abstraction
– Procedural abstraction
 No implementation detail

 Examples:
Integers, reals, booleans, lists, sets, graphs,
stacks, queues
together with their operations

GIT – Computer Engineering Department Simulation - Lecture Notes 5 3


Why ADT ?
 Encapsulation and Information hiding
– Hide implementation details
– Access ADT only through the functions
– Easy to change of implementation, transparent to the
program using ADT
 Modularity
– easy to debug and maintain
– easy to modify
 Reuse
– Implement once use several times
 C++ class facilitates implementations of ADTs.
– Objects are private data members
– Operations are public methods

GIT – Computer Engineering Department Simulation - Lecture Notes 5 4


Abstract Data Types (ADT)
 Integer ADT?
– Objects
– Operations
 Set ADT?
– Objects
– Operations

GIT – Computer Engineering Department Simulation - Lecture Notes 5 5


The Vector ADT
 Ordered sequence of data items (elements)
– A0, A1, A2, …,AN-1
 size of the vector is N
– size of an empty vector is 0
 position (index) of Ai is i
 Ai+1 succeeds Ai
 Ai-1 preceeds Ai
 first element is A0 called “front”
 last element is AN-1 called “back”

Objects?
Operations ?

GIT – Computer Engineering Department Simulation - Lecture Notes 5 6


The Vector ADT
Operations:
–Print
–Empty
–Size
–Insert
–Erase
–Push back
–Pop back
–Find
–Index operator []
–Etc.

GIT – Computer Engineering Department Simulation - Lecture Notes 5 7


The Vector
 An enhancement of the array.
 Can be used like an array:
– Access a value via an index
x = v[i];
v[j] = z;
 Additional capabilities:
– Increase or decrease its length
– Insert an element at a specified position
– Remove an element from a specified position

 How to perform these on any type of data?

GIT – Computer Engineering Department Simulation - Lecture Notes 5 8


Template Container Classes
 A template container class is a class that stores and
processes a collection of information.
 The type of this information is a parameter that is specified
when the template class is instantiated.
 Example:
template<typename T>
class some_container { … }
 The parameter T is a placeholder for the actual data type

some_container<Item_Type> call_lengths; // holds Item_Type


Some_container<People> people; // holds People

 A separate instantiation of the class is created for each actual


data type at the compile time

GIT – Computer Engineering Department Simulation - Lecture Notes 5 9


The Vector ADT

GIT – Computer Engineering Department Simulation - Lecture Notes 5 10


The Vector ADT (cont.)

GIT – Computer Engineering Department Simulation - Lecture Notes 5 11


Vector Example

// Create a vector to hold strings.


vector<string> my_vector;
// Add some entries.
my_vector.push_back("Bashful");
my_vector.push_back("Awful");
my_vector.push_back("Jumpy");
my_vector.push_back("Happy");

GIT – Computer Engineering Department Simulation - Lecture Notes 5 12


Vector Example (2)

Had to slide
[2],[3] to [3],[4]
my_vector.insert(2, “Doc”);

GIT – Computer Engineering Department Simulation - Lecture Notes 5 13


Vector Example (3)

my_vector.push_back("Dopey"); // add at end

Cheap to add at end

GIT – Computer Engineering Department Simulation - Lecture Notes 5 14


Vector Example (4)
my_vector.erase(1);

Had to slide [2..5] to [1..4]


my_vector[2]=“Sneezy”;

Replacement is cheap

GIT – Computer Engineering Department Simulation - Lecture Notes 5 15


Example Applications of vector

vector<Item_Type> some_Item_Types;
Item_Type nums[] = {5, 7, 2, 15};
for (size_t i = 0; i < 4; i++)

some_Item_Types.push_back(nums[i])
;

Item_Type sum = 0;
for (size_t i = 0; i < 4; i++) {
sum += some_Item_Types[i];
}
cout << "sum is " << sum << endl;

GIT – Computer Engineering Department Simulation - Lecture Notes 5 16


Using vector in PhoneDirectory

vector<Directory_Entry> the_directory;

/** Adds a new entry


@param name The name of the person
@param new_number The new number
*/
void add(string name, string number) {
Directory_Entry new_entry(name, number);
the_directory.push_back(new_entry);
}

GIT – Computer Engineering Department Simulation - Lecture Notes 5 17


Using vector in PhoneDirectory (2)
string Phone_Directory::add_or_change_entry(
const string& name, const string& number)
{
string old_number = "";
Item_Type index = find(name);
if (index != -1) {
old_number = the_directory[index].get_number();
the_directory[index].set_number(number);
} else {
add(name, number);
}
modified = true;
return old_number;
}

GIT – Computer Engineering Department Simulation - Lecture Notes 5 18


Implementing a vector Class
KW::vector: is an implementation of vector ADT
 simpler than std::vector
 Physical size of array indicated by data field
current_capacity
 Number of data items indicated by the data field
num_items

GIT – Computer Engineering Department Simulation - Lecture Notes 5 19


KW::vector Fields, Constructor
template<typename
template<typename Item_Type>
Item_Type>
class vector {
private:
// Data fields
/** The initial capacity of the array */
static const size_t INITIAL_CAPACITY = 10;
/** The current capacity of the array */
size_t current_capacity;
current_capacity;
/** The current num_items of the array */
size_t num_items;
num_items;
/** The array to contain the data */
Item_Type*
Item_Type* the_data;
the_data;
public:
// Member Functions
/** Constructs<i> </i>an empty vector with the default
initial capacity.
*/
vector<Item_Type
vector<Item_Type>()
Item_Type>() : current_capacity(INITIAL_CAPACITY),
current_capacity(INITIAL_CAPACITY),
the_data(new Item_Type[INITIAL_CAPACITY]),
Item_Type[INITIAL_CAPACITY]), num_items(0)
{ }

GIT – Computer Engineering Department Simulation - Lecture Notes 5 20


Implementing vector::push_back

GIT – Computer Engineering Department Simulation - Lecture Notes 5 21


Implementing vector::push_back (2)

void push_back(const Item_Type&


Item_Type& the_value)
the_value) {
// Make sure there is space for the new item.
if (num_items
(num_items == current_capacity)
current_capacity) {
// Allocate an expanded array
reserve(2 * current_capacity);
current_capacity);
}
// Insert the new item.
the_data[num_items]
the_data[num_items] = the_value;
the_value;
num_items++;
num_items++;
}

GIT – Computer Engineering Department Simulation - Lecture Notes 5 22


Implementing vector::reserve

void reserve(size_t new_capacity)


new_capacity) {
if (new_capacity
(new_capacity > current_capacity)
current_capacity) {
if (new_capacity
(new_capacity > 2 * current_capacity)
current_capacity)
current_capacity = new_capacity;
new_capacity;
else
current_capacity *= 2; // Double the capacity.
Item_Type*
Item_Type* new_data = new Item_Type[current_capacity];
Item_Type[current_capacity];
// Copy the data over.
for (size_t
(size_t i = 0; i < num_items;
num_items; i++)
new_data[i]
new_data[i] = the_data[i];
the_data[i];
// Free the memory occupied by the old copy.
delete[] the_data;
the_data;
// Now point to the new data.
the_data = new_data;
new_data;
}
}

GIT – Computer Engineering Department Simulation - Lecture Notes 5 23


Implementing vector::insert

GIT – Computer Engineering Department Simulation - Lecture Notes 5 24


Implementing vector::insert (2)
void insert(size_t index, const Item_Type&
Item_Type& the_value)
the_value) {
// Validate index.
if (index > num_items)
num_items) {
throw std::out_of_range
("index to insert is out of range");
}
// Ensure that there is space for the new item.
if (num_items
(num_items == current_capacity)
current_capacity) {
reserve(2 * current_capacity);
current_capacity); // Allocate an expanded array
}
// Move data from index to num_items - 1 down.
for (size_t
(size_t i = num_items;
num_items; i > index; i--
i--)
--) {
the_data[i]
the_data[i] = the_data[i - 1];
}
// Insert the new item.
the_data[index]
the_data[index] = the_value;
the_value;
num_items++;
num_items++;
}

GIT – Computer Engineering Department Simulation - Lecture Notes 5 25


Implementing vector::erase

GIT – Computer Engineering Department Simulation - Lecture Notes 5 26


Implementing vector::erase (2)

void erase(size_t index) {


// Validate index.
if (index > num_items)
num_items) {
throw std::out_of_range
("index to insert is out of range");
}
// Move items below the removed one up.
for (size_t
(size_t i = index + 1; i < num_items;
num_items; i++) {
the_data[i - 1] = the_data[i];
the_data[i];
}
num_items--
num_items--;
--;
}

GIT – Computer Engineering Department Simulation - Lecture Notes 5 27


Implementing vector::operator[]

Item_Type&
Item_Type& operator[](size_t index) {
// Verify that the index is legal.
if (index < 0 || index >= num_items)
num_items) {
throw std::out_of_range
("index to operator[] is out of
range");
}
return the_data[index];
the_data[index];
}

GIT – Computer Engineering Department Simulation - Lecture Notes 5 28


The copy constructor
 The compiler defines a special constructor, known
as the copy constructor, that constructs a copy of a
given object.
 This constructor is automatically invoked
– when objects are passed by value to a function
– when values are returned
– when an object is initialized with another object
 For example.
vector<Item_Type> v2(v1);
will construct the vector v2 to be a copy of v1.

GIT – Computer Engineering Department Simulation - Lecture Notes 5 29


Shallow Copy versus Deep Copy
 The copy constructor that is automatically created by the
compiler (known as the default copy constructor) makes
a copy of each data member.
 Note that the data member the_data in both v1 and v2
point to the same array.

GIT – Computer Engineering Department Simulation - Lecture Notes 5 30


Shallow Copy after v1.push_back(20)

GIT – Computer Engineering Department Simulation - Lecture Notes 5 31


Deep Copy of a Vector

GIT – Computer Engineering Department Simulation - Lecture Notes 5 32


Copy Constructor That Makes Deep Copy

vector<Item_Type>(const vector<Item_Type>& other) :


current_capacity(other.capacity),
num_items(other.num_items),
the_data(new Item_Type[other.current_capacity]) {
for (size_t i = 0; i < num_items; i++)
the_data[i] = other.the_data[i];
}

GIT – Computer Engineering Department Simulation - Lecture Notes 5 33


Destructor
 When a vector is constructed, space for the data
array is allocated via the new operator.
 All space that is allocated with the new operator
should be returned to the free storage pool via the
delete operator when it is no longer needed.
 Failure to return allocated memory results in a
memory leak and can lead to your program crashing
because memory is not available.
 When an object is no longer needed, its destructor is
called.
 It is the destructor’s responsibility to free any
allocated memory.

GIT – Computer Engineering Department Simulation - Lecture Notes 5 34


The vector’s destructor

virtual ~vector<Item_Type>() {
delete[] the_data;
}

GIT – Computer Engineering Department Simulation - Lecture Notes 5 35


The swap function
 The swap function swaps the data fields of
two vectors.

void swap(vector<Item_Type>& other) {


std::swap(num_items, other.num_items);
std::swap(current_capacity, other.current_capacity);
std::swap(the_data, other.the_data);
}

GIT – Computer Engineering Department Simulation - Lecture Notes 5 36


The assignment operator
 The statement:
v2 = v1;
invokes the assignment operator.
 Like the copy constructor, it should make a deep copy.
 We can use the copy constructor and swap function to
implement the assignment operator.

vector<Item_Type>& operator=(const vector<Item_Type>& other) {


// Make a copy of the other vector.
vector<Item_Type> the_copy(other);
// Swap contents of self with the copy.
swap(the_copy);
// Return -- upon return the old value will be destroyed.
return *this;
}

GIT – Computer Engineering Department Simulation - Lecture Notes 5 37


The Rule of Three
 A class that dynamically allocates memory (or
other resources) should define:
– A copy constructor
– A destructor
– An assignment operator
 Corollary: If a class defines one of:
– Copy constructor
– Destructor
– Assignment operator
then it should define all three.
GIT – Computer Engineering Department Simulation - Lecture Notes 5 38
Performance of the vector Class

 Index operator executes in constant time: O(1)


 Inserting or removing general elements is linear
time: O(n)
 Adding at end is (usually) constant time: O(1)
– With our reallocation policy the average is O(1)
– The worst case is O(n) because of reallocation

GIT – Computer Engineering Department Simulation - Lecture Notes 5 39

S-ar putea să vă placă și