You are on page 1of 39

AST20105

Data Structures & Algorithms


Chapter 4 - Array and Linked List
Array
Array:

● is a basic data structure representing a group of similar elements, accessed by


index;
● is an ordered collection of data contained in a variable and referenced by a
single variable name.

2
Array
Array can be used to store a list of values /
object instances.

The size of array is fixed once created


regardless created statically or dynamically
(using keyword new).

Elements are stored in contiguous positions


in the memory.

3
Array
Pros Cons
1. Can be effectively stored inside a 1. Not flexible in changing size. Requires an
machine; estimation of the max. size when creating an
2. Can efficiently return an element at array.
certain position (using subscript operator 2. Cost a lot of effort if an array need to be
[ ] in C++). resized. (Only works for dynamically built
3. Can search for an element with binary array).
search if the array is sorted. 3. If space in the array is not fully utilized,
memory space is wasted.
4. Insertion and deletion of element, due to
shifting element, is slow if order in the array
must be retained.
4
Array
Static Dynamic
1. Static array has a constant size and exists 1. Dynamic array is created during run-time
all the time while application is being and could be deleted (using delete[])
executed. when it is no longer needed.
2. Declaration syntax: type[size]; 2. Declaration syntax: ptr = new type[size];
E.g. int number[5]; E.g. int* p = new int[5];

5
Resizing an Array Use loop structure to go
through every element in the
Create a new dynamical old array. Copy values to the
array with bigger size. new array at their
corresponding position.
a b c d e
a b c d e

X
Free the memory
a b c d e
nullptr

Relocate original pointer pointing


occupied by the old Set the new pointer to null so
to the new array.
array. that only one pointer pointing at
6
the new array.
Resizing an Array
● Cost of resizing an array is heavy, O(n).
● It’s difficult to determine the new size is good enough.
● You must use deep copy instead of shallow copy.
p = newP;
DOES NOT WORK!!!!

a b c d e

● Despite there is a way to “resize” an array, it is still considered not nice when
resizing is frequently needed.

7
Linked-List

8
A node contains at least head
TWO elements: (a node pointer)
1) value(s)
2) a node* pointing to node
the next node (element) A head is simply a
structure. node* pointing to a
node structure.
Structure of every node is
identical while values are
different.

How linked-list works….


9
Singly Linked List
A singly linked list is another way of storing a list of elements (values / objects).

node
10
Singly Linked List
Idea:

● Each element has a pointer (next) that stores the address to the element after it.
● Unlike array, elements are not stored consecutively in the memory.
● The last element stores the address of the next object as NULL since no more object
after it.

node
11
Singly Linked List
● A singly linked list is a series of connected “nodes”.
● Each node contains:
○ Data
○ A pointer to the next node, generally named “next”.
● A head that is a pointer pointing to the first node.
● The pointer in the last node points to NULL.

12
Singly Linked List in C++
#ifndef SinglyList_h
#ifndef Node_h
#define SinglyList_h
#define Node_h
#include "Node.h"
class SinglyList{
class Node{ private:
public: // for lazy access of data // pointer to the 1st node
int data; Node* head;
Node* next;
}; public:
#endif /* Node_h */ SinglyList();
~SinglyList();
bool isEmpty();
Node* findNode(int);
void insertNode(int);
void deleteNode(int);
void displayList();
}; 13
#endif /* SinglyList_h */
Singly Linked List - Traverse
Assuming the linked list is not empty

1: Set a node ptr curr pointer to the beginning node


Node* curr = head;
curr
2: Move curr pointing to the next node until end of list
curr = curr->next;
3: Traversal of list stops when curr ptr reaches the end.
List values: 10 -3 21 curr == nullptr;

14
Singly Linked List in C++
SinglyList::SinglyList(){ bool SinglyList::isEmpty(){
head = nullptr; return (head == nullptr)? true : false;
numOfElement = 0; }
cout << "A list is created." << endl;
}

SinglyList::~SinglyList(){
Node* curr = head;
while(curr){
Node* nextNode = curr->next;
delete curr;
curr = nextNode;
}
cout <<"List is deleted" << endl;
}

15
Singly Linked List in C++ (Traversal)
Node* SinglyList::findNode(int val) { void SinglyList::displayList(){ //Traverse
Node* currNode = head; if(!isEmpty()){
while(currNode && currNode->data != cout << "Value(s) in the list: ";
val){ Node* curr = head;
currNode = currNode->next; while(curr){
} cout << curr->data << " ";
if(currNode) curr=curr->next;
return currNode; }
return nullptr; cout << endl;
} }else{
cout << "List is empty!" << endl;
}
}

16
Singly Linked List - Insertion
Four scenarios

1. Insert into an empty list


2. Insert as the first element in an non-empty list
3. Insert in between the list
4. Insert at the end of the list

node
17
Singly Linked List - Insertion Scenario 1
Insert into an empty list

newNode newNode

1: Create a new node ptr pointing to a node structure 3: Set head Node* pointing to the newly created node
2: Initialize both data and next of the node head = newNode;
Node* newNode = new Node;
newNode->data = 10;
newNode->next = nullptr; OR newNode->next = head
18
Singly Linked List - Insertion Scenario 2
Insert as the first element in an non-empty list 1: Create a new node ptr pointing to a node structure
2: Initialize data of the node
Node* newNode = new Node;
newNode->data = 4;
X 3: Set a new node’s next pointing to where head is pointing
newNode->next = head;
4: Set head Node* pointing to newly created node.
head = newNode;
In the case, head will no longer point to original node.

newNode

19
Singly Linked List - Insertion Scenario 3
Insert in between the list 1: Create a new node ptr pointing to a node structure
2: Initialize data of the node
Node* newNode = new Node;
newNode->data = 21;
3: Create a Node* curr pointing to the first node:
X Node* curr = head;
Use a loop to reach for the correct pos to be inserted.
4: When the position is found, set new node’s next
point to where curr is pointing.
newNode->next = curr->next;
5: Set the node (where curr is pointing)’s next to
newNode
curr curr->next = newNode;

newNode

20
Singly Linked List - Insertion Scenario 4
Insert at the end of the list 1: Create a new node ptr pointing to a node structure
2: Initialize data and next of the node
Node* newNode = new Node;
newNode->data = 4;
3: Create a Node* curr pointing to the first node:
Node* curr = head;

4: Use loop to move curr pointer until it is point to the


last node.

Set new node’s pointer to nullptr.


newNode->next = nullptr; OR
newNode->next = curr->next;
curr
5: Set the next ptr of the last node pointing to the new
node.
curr->next = newNode;
newNode

21
Singly Linked List in C++
void SinglyList::insertNode(int index, int if(index > 0 && currNode == nullptr){
val){ cout << "Invalid index!" << endl;
if(index < 0){ return;
cout << "Invalid index!" << endl; }
return;
} Node* newNode = new Node; Create new node
// Looking for the right pos newNode->data = val;
int currIndex = 1;
Node* currNode = head; if(index == 0) {
while(currNode && index > currIndex) { newNode->next = head; Scenario 1 & 2
currNode = currNode->next; head = newNode;
currIndex++; }else {
} newNode->next = currNode->next;
currNode->next = newNode;
}
} Scenario 3 & 4
22
Singly Linked List - Removal of Node
Four scenarios:

1. Remove the ONLY node in the list


2. Remove FIRST node in the list
3. Remove LAST node in the list
4. Remove a node in BETWEEN the list

node
23
Singly Linked List - Removal Scenario 1
Remove the ONLY node in the list (E.g. remove 10)
1: Create a Node* curr pointing to the first node.
Node* curr = head;

X
2: If there is only ONE node (how do we know?), set head back to
nullptr.

head = nullptr; OR head = curr->next;

3: Delete the node structure where curr is pointing.


delete curr;

curr

24
Singly Linked List - Removal Scenario 2
Remove FIRST node in the list (E.g. remove 4) 1: Create a Node* curr pointing to the first node.
Node* curr = head;

X
2: If the 1st node is to be deleted, set head pointing
to curr.
head = curr->next;

X 3: Delete the node structure where curr is pointing.


delete curr;

curr

25
Singly Linked List - Removal Scenario 3

X
Remove LAST node in the list (E.g. remove 21) 1: Create 2 Node* curr and prev:
Set curr pointing where head is pointing.
Set prev as nullptr.

X Node* curr = head, prev = nullptr;

2: Use a loop to move both curr and prev pointers


until the node is found (pointed by curr) or curr has
reached to the end of list.

prev = curr;
curr = curr->next;

3: If found at the curr Node*:


Set prev node’s next to curr node’s next.
prev curr
prev->next = curr->next;

4: Delete the node.


delete curr;
26
Singly Linked List - Removal Scenario 4

X
Remove a node in between the list (E.g. remove 10) 1: Create 2 Node* curr and prev:
Set curr pointing where head is pointing.
Set prev as nullptr.

X Node* curr = head, prev = nullptr;

2: Use a loop to move both curr and prev pointers


until the node is found (pointed by curr) or curr has
reached to the end of list.
prev = curr;
curr = curr->next;

3: If found at the curr Node*:


Set prev node’s next to curr node’s next.

prev curr prev->next = curr->next;

4: Delete the node.


delete curr;
27
Singly Linked List in C++
void SinglyList::deleteNode(int val) { cout << "Node not found!" << endl;
Node* prevNode = NULL; return;
Node* currNode = head; }
while(currNode && currNode->data != val){
prevNode = currNode;
currNode = currNode->next;
}
if(currNode) {

Scenario 3 & 4
if(prevNode) {
prevNode->next = currNode->next;
delete currNode;
Scenario 1 & 2

}else {
head = currNode->next;
delete currNode;
}
cout << "First encounter node with "
<< val << " is deleted." << endl;
return;
28
}
Other Kinds of Linked-List

29
Doubly Linked List
● The problem of using a Singly List is that there is only one traversal direction (from head
to tail).
● To resolve this problem, Doubly Linked List is introduced. Each node contains 2
pointers prev and next.
● These 2 pointers are pointing at the previous and the next node.
● Beside Node* head, Node* tail is also used to keep track the last node of the list.

30
Doubly Linked List
● The good side is traversal of the list could be both way.
● Ideally speaking, traversal could be O(n/2) when searching for a node. This applies
ONLY if you know where the node is.
● In many cases, traversal complexity is still O(n).
● More spaces consumed as every node contains an additional Node* prev.

31
Circular Linked List
● Each node has a successor.
● It is used in timesharing environment in O/S.
● The operating system must maintain a list of present users and must alternately allow
each user to use a small slice of CPU time, one user at a time.
● The operating system will pick a user, let him/her use a small amount of CPU time and
then move on to the next user, etc.

32
Skip List
● Linked list has a serious drawback
○ Sequential scanning could be costly.
● In the following skip list:
○ Every second node points to the node 2 position ahead.
○ Every fourth node points to the node 4 position ahead.

33
Skip List
● The skip list (in the previous page) is accomplished by having different numbers of ptr
in nodes on the list
○ ½ of nodes have 1 pointer
○ ¼ of nodes have 2 pointers
○ ⅛ of nodes have 3 pointers
● Have you travelled with rail in Japan?

34
Array vs Linked List

35
Key Differences between Array and Linked List
Array Linked-List
An array is the data structure that contains Linked list is considered as non-primitive
a collection of similar type data elements. data structure contains a collection of
unordered linked elements known as
nodes.
Elements belong to indexes, i.e., if you want You have to start from the head and work
to get into the fourth element you have to your way through until you get to the fourth
write the variable name with its index or element.
location within the square bracket.

36
Key Differences between Array and Linked List
Array Linked-List
Accessing an element in an array is fast. Linked list takes linear time, so it is quite a
bit slower.
Operations like insertion and deletion in The performance of insertion and deletion
arrays consume a lot of time. is fast.
Fixed size. Linked lists are dynamic and flexible and can
expand and contract its size.

37
Key Differences between Array and Linked List
Array Linked-List
Memory is assigned during compile time Nodes in the linked list it is allocated during
(for static). execution or runtime.
Elements are stored consecutively. Elements are stored randomly.

The requirement of memory is less due to There is a need for more memory in Linked
actual data being stored within the index in Lists due to storage of additional next and
the array. previous referencing elements.
Memory utilization is inefficient. Memory utilization is efficient.

38
Q&A

39

You might also like