Você está na página 1de 21

Data Structures

Linked Lists
(Part 3)

Objectives
By the end of this lesson, you will be able to:
Improve implementation of some operations on
linked lists
Create an abstract linked list type using C++
templates

CT077-3-2-DSTR

Data Structures

Improving Operations
Inserting a new item at beginning of a linked list is
fast (no traversal required)
X

X
lastNode

newNode

newNode

While inserting at the end of the list required us to


traverse the whole list to reach the last element

CT077-3-2-DSTR

Data Structures

Improving Operations
If in a program there is a need to frequently insert
items at end of the list, its worth to change the data
structure to allow more efficient implementation
class LinkedList {
public:
NodeType* head;
NodeType* tail;
int size;
// .. the other implemented
methods
};

CT077-3-2-DSTR

Data Structures

Insert at the End


Now insert at end can be implemented efficiently
void insertAtEnd(int value){
NodeType * newNode= new NodeType;
newNode->info = value;
newNode->link = NULL;
if (head == NULL)//inserting to an empty list
head = tail = newNode;
else{
tail->link = newNode;
tail = newNode;
}
size++;
}

X
5
CT077-3-2-DSTR

newNode
Data Structures

Change Previous Implementations


Note however that other implemented operations
may have to be changed as well to consider the
new tail field and properly update it if necessary

CT077-3-2-DSTR

Constructor and destructor


clear()
insertAtBeginning()
deleteFirst(), deleteLast(), and deleteItemAt()
insertItemAt()
no change necessary if it depends on inserting at
beginning and end methods

Data Structures

Necessary Modifications
For example, the constructor will be modified to:
Inserting a new item at
the beginning of a list
will affect the tail ONLY
if the list was empty

CT077-3-2-DSTR

LinkedList(){
this->size = 0;
this->head= NULL;
this->tail= NULL;
}
void insertAtBeginning(int
value){
NodeType * newNode= new
NodeType;
newNode->info = value;
newNode->link = head;
head = newNode;
size++;
if(tail == NULL)
tail = newNode;
}

Data Structures

Necessary Modifications
deleteFirst() should also be changed
Deleting first item in the list will affect tail ONLY if
the list becomes empty after deletion
void deleteFirst(){
if(size > 0){//else, may want to give a message or
error
NodeType * toBeDeleted = head;
head = head->link;
delete toBeDeleted;
size--;
if(head == NULL)
tail = NULL;
}
}

CT077-3-2-DSTR

Data Structures

deleteLast efficiency improvement?


Note that deleteLast() will not benefit from the tail
pointer to improve efficiency, since we still need a
pointer to the item before the last one

beforeLast

This can be solved later when doubly linked lists


are introduced
CT077-3-2-DSTR

Data Structures

Linked Lists of Other Types


The linked lists we dealt with so far are lists of
integer numbers
class NodeType {
public:
int info;
NodeType* link;
};

class LinkedList {
public:
NodeType* head;
NodeType* tail;
int size;
};

What must be changed if we also need a linked list


of double numbers?
Probably we will create new very similar classes

class DoubleLinkedList {
public:
DoubleNode* head;
DoubleNode* tail;
int size;
};

class DoubleNode {
public:
double info;
DoubleNode*
link;
};
CT077-3-2-DSTR

Data Structures

10

Linked Lists of Other Types


We will also have to repeat all the methods
(probably copy-paste) with only small changes
related to the type change
class DoubleLinkedList {
//..data members and other methods
double getItemAt(int index){ ... }
void setItemAt(double value, int index)
{ ... }
void insertAtBeginning(double value){ ... }
void insertAtEnd(double value){ ... }
//and so on ...
};

What if we needed a list of float numbers, books,


students, cars, etc. ?
CT077-3-2-DSTR

Data Structures

11

Generic Linked Lists


Using C++ templates, we can build abstract
LinkedList data type that works for any type of items
template <class T>
class NodeType {
public:
T info;
NodeType<T> *
link;
};

template <class T>


class LinkedList {
public:
NodeType<T> * head;
NodeType<T> * tail;
int size;
};

You can use any name instead of T, which serves as


a parameter to be used in class implementation
Parametric Polymorphism concept

Specific type must be provided later when objects of


the class are created
CT077-3-2-DSTR

Data Structures

12

Using Generic Linked Lists


When the list is created, type T can be determined
to be int, float, double, Book, Student, Car, etc.
void main(){
LinkedList<int> list1;
LinkedList<double> list2;
LinkedList<char *> list3;
list1.insertAtBeginning(1);
list1.insertAtEnd(2);
list2.insertAtBeginning(3.3);
list2.insertAtBeginning(4.4);
list2.insertAtEnd(5.5);
list3.insertAtEnd("Bye");
list3.insertAtBeginning("Hello");
list1.print();
list2.print();
list3.print();
}
CT077-3-2-DSTR

Data Structures

13

Generic Linked List Implementation


Class implementation need not know about what
type of items will be stored in the linked list
Implementation uses type T as if it is already defined,
and the real type will be determined later
template <class T>
class LinkedList {
//..data members and other methods
void insertAtBeginning(T value){
NodeType<T> * newNode= new NodeType<T>;
newNode->info = value;
newNode->link = head;
head = newNode;
size++;
if(tail == NULL)
tail = newNode;
}
};
CT077-3-2-DSTR

Data Structures

14

Generic Implementation Issues


But be aware of any type specific operations used
in implementation. For example:
Parameters of type T being passed and returned by
value or by reference
template <class T>
class LinkedList {
//..data members and other methods
void insertAtBeginning(T value){...}
void insertAtEnd(T value){...}
void insertItemAt(T value, int index){...}
T & getItemAt(int index){...}
void setItemAt(int index, T & value){...}
bool search(T & value){...}
};

CT077-3-2-DSTR

Data Structures

15

Generic Implementation Issues


But be aware of any type specific operations used
in implementation. For example:
Printing an object by passing it to << operator of cout
Cant directly print an object of type Book for example

Proper printing function must be provided


template <class T>
class LinkedList {
//..data members and other methods
void print(){
// .. code before ...
cout << current->info << " ";
// .. code after ...
}
};

CT077-3-2-DSTR

Data Structures

16

Generic Implementation Issues


But be aware of any type specific operations used
in implementation. For example:
Comparing two objects of type T usually doesnt work for
class objects
Cant directly compare two objects of type Book

Proper comparison function must be provided


template <class T>
class LinkedList {
//..data members and other methods
bool search(T & value){
// .. code before ...
if (current->info == value)
// .. code after ...
}
};
CT077-3-2-DSTR

Data Structures

17

Generic Linked List Implementation


One solution to the previous issues is through
operator overloading for the << and == operators
Advanced C++ topic! Use as is for now
class Book{
public: int id; double price; string title;
friend ostream& operator << (ostream & ostr, Book & b) {
return ostr << "[Title="<<b.title << ",ID=" << b.id
<< ",Price=" << b.price << "]";
}
friend bool operator == (const Book & lhs, const Book & rhs)
{
if ( (lhs.id == rhs.id) && (lhs.price == rhs.price)
&& (lhs.title == rhs.title) )
return true;
else
return false;
}
CT077-3-2-DSTR };

Data Structures

18

Generic Implementation Issues


But be aware of any type specific operations used
in implementation. For example:
Assignment of an object to another copies each
respected field from RHS object to the LHS object
If you have dynamically allocated memory in an object,
the = operator must be overloaded properly
template <class T>
class LinkedList {
//..data members and other methods
void setItemAt(int index, T & value){
// .. code before ...
current->info = value;
}
};
CT077-3-2-DSTR

Data Structures

19

Homework
Using C++ Templates, modify the implementation of
LinkeList and NodeType classes to be generic
Change info to be of template type T instead of integer
Apply all necessary changes to the implemented methods

Define a linked list of Students and test list functionalities


using a main driver function, where Student is:
Define a default constructor for Student because the code to create
a NodeType<Student> object will create a Student object
class Student{
public:
int id;
string firstName;
string lastName;
float cgpa;
};
CT077-3-2-DSTR

Data Structures

20

CT077-3-2-DSTR

Data Structures

21

Você também pode gostar