Data Structures - Lecture 2 - English
Data Structures - Lecture 2 - English
Linked Lists
Dr. Ali El Masri
1
Part A
2
Array Definition
• An array is a sequenced collection of variables all of the same type
• Each variable, or cell, in an array has an index, which uniquely refers to the value stored in that cell
• Since the length of an array determines the maximum number of things that can be stored in the array, we will sometimes
refer to the length of an array as its capacity
3
An array can store primitive elements, such as characters
4
First way: Declaration and Initialization
The first way to create an array is to use an assignment to a literal form when initially declaring the array, using a syntax as:
The elementType can be any C++ base type or class name, and arrayName can be any valid C++ identifier
elementType arrayName[arraySize];
In both ways, array size is specified at the moment of array declaration and cannot be changed during the program run time
5
• Data collection
• No space overhead
• Size = length * sizeof(element)
7
• A linked list is a fundamentally different way of storing collections
• A linked list is a series of connected nodes, where each node is a data structure
Node
Linked List
8
• Data collection
• No fixed size
• can easily grow or shrink in size during the program run time
• Space overhead
• Each element must store an additional pointer
• Size = length * sizeof(element) + length * sizeof(pointer)
10
To implement a linked list, we need two C++ classes:
Object of the
Linked List class
11
This is another way to implement a linked list
Object of the
Linked List class
12
One more way to implement a linked list
Object of
Object of the the Node
We are going to Linked List class class
implement this
example
14
Data: Any type of data (C++ or user-
defined) can be used. For simplicity,
SLLNode.h we consider the int type.
class SLLNode {
private: Pointer to next node
int data;
SLLNode* next;
public:
SLLNode(int dataValue, SLLNode* nextNode);
SLLNode.cpp
To let the SinglyLinkedList #include "SLLNode.h"
class access private
variables of the SLLNode
class SLLNode::SLLNode(int dataValue, SLLNode* nextNode) {
data = dataValue;
next = nextNode;
}
Implementation of
the constructor 15
SinglyLinkedList.h
class SinglyLinkedList { Pointer to first node in the list
private:
SLLNode* head; Pointer to last node in the list
SLLNode* tail; Number of nodes in the list
int size;
public:
SinglyLinkedList();
Add a node at the Constructor
beginning of the list ~SinglyLinkedList();
void addToHead(int data); Destructor
Add a node at the end void addToTail(int data);
of the list void addAtIndex(int index, int data);
int removeFromHead();
Add a node at a given
place in the list int removeFromTail(); Remove a node from the
int removeFromIndex(int index); beginning of the list
bool isEmpty();
Check if the list is Remove a node from the
empty bool isInList(int data); end of the list
void print();
int getSize(); Remove a node from a
Print the content of given place in the list
};
the list
head = NULL;
tail = NULL;
Constructor: Linked-List initialization
size = 0;
17
List before adding the new node
Steps: Implementation:
Allocate new node
if (size == 0)
head = tail = new SLLNode(data, NULL);
else
head = new SLLNode(data, head);
size++;
}
19
List before adding the new node
Steps: Implementation:
Allocate a new node
} else {
Have next of old tail pointing to new node
tail->next = newNode;
tail = newNode;
}
Update tail to point to new node
size++;
}
Increment the list size
21
List before removing the new node
Steps: Implementation:
22
int SinglyLinkedList::removeFromHead() {
There is no constant-time way to update the tail to point to the previous node
We have to traverse the whole list in order to have a pointer to the predecessor of the tail
26
Steps: Allocate a new node Implementation:
SLLNode* newNode = new SLLNode(data, NULL);
Insert new data
int i = 0;
while (i < index - 1) {
Traverse the list and stop at (index – 1) tmp = tmp->next;
i++;
}
29
int SinglyLinkedList::removeFromIndex(int index) {
if (size == 0)
Special case: Empty list cout << "Empty list" << endl;
31
void SinglyLinkedList::print() {
if (size == 0)
cout << "Empty list" << endl;
else {
cout << "List: ";
SLLNode* tmp = head; int SinglyLinkedList::getSize() {
while (tmp != NULL) { return size;
cout << tmp->data << " --> "; }
tmp = tmp->next;
}
cout << " NULL " << endl;
}
} bool SinglyLinkedList::isEmpty() {
return size == 0;
}
SinglyLinkedList::~SinglyLinkedList() {
while (size != 0)
removeFromHead();
}
32
int SinglyLinkedList::getHead() {
if (size == 0)
return -1;
return head->data;
}
int SinglyLinkedList::getTail() {
if (size == 0)
return -1;
return tail->data;
}
33
Method Running time
addToHead(int data) O(1)
addToTail(int data) O(1)
addAtIndex(int index, int data) O(n)
removeFromHead() O(1)
removeFromTail() O(n)
removeFromIndex(int index) O(n)
34
Part D
35
• A doubly linked list can be traversed forward and backward
36
Data: Any type of data (C++ or user-
defined) can be used. For simplicity,
DLLNode.h we consider the int type.
class DLLNode {
private: Pointer to next node
int data;
DLLNode* next;
DLLNode* prev; Pointer to previous node
public:
DLLNode(int dataValue, DLLNode* nextNode, DLLNode* prevNode); Constructor
To let the DoublyLinkedList
friend class DoublyLinkedList; class access private variables
}; of the DLLNode class
DLLNode.cpp
#include "DLLNode.h"
DLLNode::DLLNode(int dataValue, DLLNode* nextNode, DLLNode* prevNode) {
data = dataValue;
next = nextNode;
Implementation of
prev = prevNode; the constructor
}
37
DoublyLinkedList.h
class DoublyLinkedList { Pointer to first node in the list
private:
DLLNode* head; Pointer to last node in the list
DLLNode* tail; Number of nodes in the list
int size;
public:
DoublyLinkedList();
Add a node at the Constructor
beginning of the list ~DoublyLinkedList();
void addToHead(int data); Destructor
Add a node at the end void addToTail(int data);
of the list void addAtIndex(int index, int data);
int removeFromHead();
Add a node at a given
place in the list int removeFromTail(); Remove a node from the
int removeFromIndex(int index); beginning of the list
bool isEmpty();
Check if the list is Remove a node from the
empty bool isInList(int data); end of the list
void print();
int getSize(); Remove a node from a
Print the content of given place in the list
};
the list
if (size == 0)
Special case:
Empty list head = tail = new DLLNode(data, NULL, NULL);
else {
size++;
} Increment list size
40
List before removing the new node
Steps: Implementation:
41
int DoublyLinkedList::removeFromTail() {
Special case: Empty list
if (size == 0)
return -1;
Save data of old tail Unlike Singly Linked List:
int data = tail->data;
Special case: List consisting • Removing at the tail of a doubly linked
of a single node if (size == 1) { list is efficient!
}
Decrement the list size size--;
return data; Return data of old tail
42
}
Part E
43
A linked list in which the last node points to the first node
In a circular linked list with more than one node, it is convenient to make the pointer first point to the last node of the list
Then by using first you can access both the first and the last node of the list
For example, first points to the last node and first->next points to the first node
We can traverse the whole list by starting from any node (we just need to stop when the first visited node is visited again)
44
Part F
45
Exercise 1: Write a method (to be added to the SinglyLinkedList class) that takes as parameter an integer (int index).
The method should return the sum of all nodes after the specified index. You can use any of the methods of the
class SinglyLinkedList:
// missing codes
Exercise 2: Write a method (to be added to the SinglyLinkedList class) that takes as parameters two linked lists and
appends the second list at the end of the first one. You can use any of the methods of the class SinglyLinkedList:
// missing codes
46
Exercise 3: Implement the method “void addAtIndex(int index, int data){}” for the DoublyLinkedList class. Assume
that the method “void addAtHead(int data){}” and the method “void addAtTail(int data){}” are already implemented.
void DoublyLinkedList::addAtIndex(int index, int data) {
// missing codes
Exercise 4: Implement the method “int removeFromIndex(int data){}” for the DoublyLinkedList class. Assume that
the method “int removeFromHead(){}” and the method “int removeFromTail(){}” are already implemented.
// missing codes
47
Part G
48
• Data Structures and Algorithms in C++, 4th Edition, Adam Drozdek
• Data Structures & Algorithm Analysis in C++, 4th Edition, by M.A. Weiss
• Data Structures and Algorithms in C++, 2nd Edition, by M.T. Goodrich, R. Tamassia, and D.M. Mount
• Data Structures and Algorithms in Java, 6th Edition, by M.T. Goodrich and R. Tamassia
• Data Structures and Program Design in C++, 1st Edition, by R.L. Kruse and A.J. Ryba
49