Data Structures With C++
Data Structures With C++
– Time Complexity
– Space Complexity
09/11/2021 Asst.lec.Asan Bakir 6
Time Complexity
• Time complexity of an algorithm signifies the
total time required by the program to run to
completion. The time complexity of algorithms
is most commonly expressed using the big O
notation.
• Time Complexity is most commonly estimated
by counting the number of elementary
functions performed by the algorithm.
– Instruction Space : Its the space required to store the executable version
of the program. This space is fixed, but varies depending upon the
number of lines of code in the program.
– Data Space : Its the space required to store all the constants and
variables value.
– Environment Space : Its the space required to store the environment
information needed to resume the suspended function.
name[index]
(remember that array indices always begin with zero).
#define WIDTH 5
#define WIDTH 5
#define HEIGHT 3
#define HEIGHT 3
int jimmy [HEIGHT * WIDTH];
int jimmy [HEIGHT][WIDTH];
int n,m;
int n,m;
int main ()
int main ()
{
{
for (n=0; n<HEIGHT; n++)
for (n=0; n<HEIGHT; n++)
for (m=0; m<WIDTH; m++)
for (m=0; m<WIDTH; m++)
{
{
jimmy[n][m]=(n+1)*(m+1);
jimmy[n*WIDTH+m]=(n+1)*(m+1);
}
}
}
}
Note that the code uses defined constants for the width
and height, instead of using directly their numerical values.
This gives the code a better readability, and allows changes
in the code to be made easily in one place.
Notice how after the content of the string itself, a null character ('\0') has been
added in order to indicate the end of the sequence. The panels in gray color
represent char elements with undetermined values.
– a[5] = 0; // a [offset of 5] = 0
– *(a+5) = 0; // pointed to by (a+5) = 0
These two expressions are equivalent and valid, not only if a is a pointer,
but also if a is an array.
2nd stage
• Like we can see in the above example, merge sort first breaks the unsorted list
into sorted sublists, and then keep merging these sublists, to finlly get the
complete sorted list.
09/11/2021 Asst.lect. Asan Bakir 73
Sorting using Merge Sort Algorithm
• /* a[] is the array, p is starting index, that is 0, and r is the last
index of array. Lets take a[5] = {32, 45, 67, 2, 7} as the array to
be sorted. */
void mergesort(int a[], int p, int r){
int q;
if(p < r) { q = floor( (p+r) / 2);
mergesort(a, p, q);
mergesort(a, q+1, r);
merge(a, p, q, r);
}
}
88
Stacks
• Stack is an abstract data type with a bounded
(predefined) capacity. It is a simple data
structure that allows adding and removing
elements in a particular order. Every time an
element is added, it goes on the top of the
stack, the only element that can be removed is
the element that was at the top of the stack,
just like a pile of objects.
89
Stack data structure
90
Basic features of Stack
• Stack is an ordered list of similar data type.
• Stack is a LIFO structure. (Last in First out).
• push() function is used to insert new elements into
the Stack and pop() is used to delete an element
from the stack. Both insertion and deletion are
allowed at only one end of Stack called Top.
• Stack is said to be in Overflow state when it is
completely full and is said to be in Underflow state
if it is completely empty.
91
Applications of Stack
• The simplest application of a stack is to
reverse a word. You push a given word to stack
- letter by letter - and then pop letters from
the stack.
• There are other uses also
like : Parsing, Expression Conversion(Infix to
Postfix, Postfix to Prefix etc) and many more.
92
Implementation of Stack
• Stack can be easily implemented using an
Array or a Linked List. Arrays are quick, but are
limited in size and Linked List requires
overhead to allocate, link, unlink, and
deallocate, but is not limited in size. Here we
will implement Stack using array.
93
94
Push Operation
• The process of putting a new data element onto
stack is known as a Push Operation. Push
operation involves a series of steps −
– Step 1 − Checks if the stack is full.
– Step 2 − If the stack is full, produces an error and exit.
– Step 3 − If the stack is not full, increments top to point
next empty space.
– Step 4 − Adds data element to the stack location,
where top is pointing.
– Step 5 − Returns success.
95
96
Pop Operation
• Accessing the content while removing it from
the stack, is known as a Pop Operation. In an
array implementation of pop() operation, the
data element is not actually removed,
instead top is decremented to a lower position
in the stack to point to the next value. But in
linked-list implementation, pop() actually
removes data element and deallocates
memory space.
97
• A Pop operation may involve the following
steps −
– Step 1 − Checks if the stack is empty.
– Step 2 − If the stack is empty, produces an error
and exit.
– Step 3 − If the stack is not empty, accesses the
data element at which top is pointing.
– Step 4 − Decreases the value of top by 1.
– Step 5 − Returns success.
98
99
• Stacks have some useful terminology associated with
them:
• Push To add an element to the stack
• Pop To remove an element from the stock
• Peek To look at elements in the stack without removing
them
• LIFO Refers to the last in, first out behavior of the stack
• FILO Equivalent to LIFO
100
Position of Top Status of Stack
-1 Stack is Empty
101
Data Structures
102
Queue Data Structures
• Queue is also an abstract data type or a linear data
structure, in which the first element is inserted from
one end called REAR(also called tail), and the
deletion of existing element takes place from the
other end called as FRONT(also called head). This
makes queue as FIFO data structure, which means
that element inserted first will also be removed first.
• The process to add an element into queue is
called Enqueue and the process of removal of an
element from queue is called Dequeue.
103
104
Basic features of Queue
• Like Stack, Queue is also an ordered list of elements of similar
data types.
105
Applications of Queue
• Queue, as the name suggests is used whenever we need to have any
group of objects in an order in which the first one coming in, also gets
out first while the others wait for there turn, like in the following
scenarios :
• In real life, Call Center phone systems will use Queues, to hold people
calling them in an order, until a service representative is free.
106
Implementation of Queue
• Queue can be implemented using an Array, Stack or
Linked List. The easiest way of implementing a
queue is by using an Array.
• Initially the head(FRONT) and the tail(REAR) of the
queue points at the first index of the array (starting
the index of array from 0). As we add elements to
the queue, the tail keeps on moving ahead, always
pointing to the position where the next element will
be inserted, while the head remains at the first
index.
107
Queue Using Array
• structure can be implemented using one dimensional array. But,
queue implemented using array can store only fixed number of
data values. The implementation of queue data structure using
array is very simple, just define a one dimensional array of specific
size and insert or delete the values into that array by using FIFO
(First In First Out) principle with the help of variables 'front' and
'rear'. Initially both 'front' and 'rear' are set to -1.
• Whenever, we want to insert a new value into the queue,
increment 'rear' value by one and then insert at that position.
Whenever we want to delete a value from the queue, then
increment 'front' value by one and then display the value at 'front'
position as deleted element.
108
enQueue(value) - Inserting value into the
queue
• In a queue data structure, enQueue() is a function used to insert a
new element into the queue. In a queue, the new element is
always inserted at rear position. The enQueue() function takes one
integer value as parameter and inserts that value into the queue.
We can use the following steps to insert an element into the
queue...
109
deQueue() - Deleting a value from the
Queue
• In a queue data structure, deQueue() is a function used to delete an
element from the queue. In a queue, the element is always deleted
from front position. The deQueue() function does not take any value as
parameter. We can use the following steps to delete an element from
the queue...
110
111
• When we remove element from Queue, we can follow two possible
approaches (mentioned [A] and [B] in the diagram).
• In [A] approach, we remove the element at head position, and then
one by one move all the other elements on position forward. In
approach [B] we remove the element from head position and then
move head to the next position.
112
Introduction to Linked Lists
Data Structures
2nd stage
Linked List
• Linked List is a linear data structure and it is
very common data structure which consists of
group of nodes in a sequence which is divided
in two parts. Each node consists of its own
data and the address of the next node and
forms a chain. Linked Lists are used to create
trees and graphs.
Advantages of Linked Lists
• They are a dynamic in nature which allocates
the memory when required.
• Insertion and deletion operations can be easily
implemented.
• Stacks and queues can be easily executed.
• Linked List reduces the access time.
Disadvantages of Linked Lists
• The memory is wasted as pointers require
extra memory for storage.
• No element can be accessed randomly; it has
to access each node sequentially.
• Reverse Traversing is difficult in linked list.
Applications of Linked Lists
• Linked lists are used to implement stacks,
queues, graphs, etc.
• Linked lists let you insert elements at the
beginning and end of the list.
• In Linked Lists we don’t need to know the size
in advance.
Types of Linked Lists
1. Singly Linked List : Singly linked lists contain
nodes which have a data part as well as an
address part i.e. next, which points to the next
node in sequence of nodes. The operations we
can perform on singly linked lists are insertion,
deletion and traversal.
Singly Linked List
Types of Linked Lists
2. Doubly Linked List : In a doubly linked list,
each node contains two links the first link
points to the previous node and the other link
points to the next node in the sequence.
Doubly Linked List
Types of Linked Lists
Similarly you can call any of the functions of the LinkedList class, add as many Nodes you
want to your List.
Nonlinear Data structures
2nd Stage
Linear data structures
• Linear data structures organize their data elements in a linear fashion,
where data elements are attached one after the other. Data elements in a
liner data structure are traversed one after the other and only one
element can be directly reached while traversing. Linear data structures
are very easy to implement, since the memory of the computer is also
organized in a linear fashion. Some commonly used linear data structures
are arrays, linked lists, stacks and queues. An arrays is a collection of data
elements where each element could be identified using an index. A linked
list is a sequence of nodes, where each node is made up of a data
element and a reference to the next node in the sequence. A stack is
actually a list where data elements can only be added or removed from
the top of the list. A queue is also a list, where data elements can be
added from one end of the list and removed from the other end of the
list.
Nonlinear data structures
• In nonlinear data structures, data elements are not organized in a
sequential fashion. A data item in a nonlinear data structure could
be attached to several other data elements to reflect a special
relationship among them and all the data items cannot be
traversed in a single run.
• Data structures like multidimensional arrays, trees and graphs are
some examples of widely used nonlinear data structures.
– A multidimensional array is simply a collection of one-dimensional arrays.
– A tree is a data structure that is made up of a set of linked nodes, which
can be used to represent a hierarchical relationship among data elements.
– A graph is a data structure that is made up of a finite set of edges and
vertices. Edges represent connections or relationships among vertices that
stores data elements.
Difference between Linear and Nonlinear
Data Structures
• Main difference between linear and nonlinear data structures
lie in the way they organize data elements. In linear data
structures, data elements are organized sequentially and
therefore they are easy to implement in the computer’s
memory. In nonlinear data structures, a data element can be
attached to several other data elements to represent specific
relationships that exist among them. Due to this nonlinear
structure, they might be difficult to be implemented in
computer’s linear memory compared to implementing linear
data structures. Selecting one data structure type over the
other should be done carefully by considering the relationship
among the data elements that needs to be stored.
Graph
• A graph is a set of items that are connected by
edges and each item is known as node or
vertex. In other words, a graph can be defined
as the set of vertices and there is a binary
relation between these vertices.
• In implementation of a graph, the nodes are implemented
as objects or structures. The edges can be represented in
different ways. One of the ways is that each node can be
associated with an incident edges array. If the information
is to be stored in nodes rather than edges then the arrays
acts as pointers to nodes and also represent edges. One of
the advantages of this approach is that additional nodes
can be added to the graph. Existing nodes can be
connected by adding elements to arrays. But there is one
disadvantage because time is required in order to
determine whether there is an edge between the nodes.
• Other way to do this is to keep a two
dimensional array or matrix M that has
Boolean values. The existence of edge from
node i to j is specified by entry Mij. One of the
advantages of this method is to find out if
there is any edge between two nodes.
Tree
• Tree is also a data structure used in computer science. It is
similar to the structure of the tree and has a set of nodes
that are linked to each other.
• A node of a tree may contain a condition or value. It can
also be a tree of its own or it can represent a separate
data structure. Zero or more nodes are present in a tree
data structure. If a node has a child then it is called parent
node of that child. There can be at most one parent of a
node. The longest downward path from the node to a leaf
is the height of the node. The depth of node is
represented by the path to its root.
• In a tree, the topmost node is called root
node. The root node has no parents as it is the
top most one. From this node, all tree
operations begin. By using links or edges,
other nodes can be reached from the root
node. The bottom-most level nodes are called
leaf nodes and they don’t have any children.
The node that has number of child nodes is
called inner node or internal node.
Difference between graph and tree:
• A tree can be described as a specialized case of graph with
no self loops and circuits.
• There are no loops in a tree whereas a graph can have
loops.
• There are three sets in a graph i.e. edges, vertices and a set
that represents their relation while a tree consists of nodes
that are connected to each other. These connections are
referred to as edges.
• In tree there are numerous rules spelling out how
connections of nodes can occur whereas graph has no rules
dictating the connection among the nodes.
Tree data structure
2nd Stage
Tree
• Tree: So far, we have been studying mainly linear
types of data structures: arrays, lists, stacks and
queues. Now we defines a nonlinear data structure
called Tree. This structure is mainly used to
represent data containing a hierarchical relationship
between nodes/elements e.g. family trees and
tables of contents. There are two main types of tree:
• General Tree
• Binary Tree
General Tree
• General Tree: A tree where a node can has any
number of children / descendants is called
General Tree. For example:
Following figure is also an example of general
tree where root is “Desktop”.
Binary Tree
• Binary Tree: A tree in which each element may has 0-child
, 1-child or maximum of 2-children. A Binary Tree T is
defined as finite set of elements, called nodes, such that
• a) T is empty (called the null tree or empty tree.) b) T
contains a distinguished node R, called the root of T, and
the remaining nodes of T form an ordered pair of disjoint
binary trees T1 and T2.
• If T does contain a root R, then the two trees T1 and T2
are called, respectively, the left sub tree and right sub tree
of R.
• If T1 is non empty, then its node is called the left successor of R;
similarly, if T2 is non empty, then its node is called the right
successor of R. The nodes with no successors are called the
terminal nodes.
• If N is a node in T with left successor S1 and right successor S2,
then N is called the parent(or father) of S1 and S2. Analogously, S1
is called the left child (or son) of N, and S2 is called the right child
(or son) of N.
• Furthermore, S1 and S2 are said to siblings (or brothers). Every
node in the binary tree T, except the root, has a unique parent,
called the predecessor of N.
• The line drawn from a node N of T to a successor is called an edge,
and a sequence of consecutive edges is called a path.
• A terminal node is called a leaves, and a path ending in a leaves is
called a branch.
• The depth (or height) of a tree T is the maximum
number of nodes in a branch of T. This turns out to
be 1 more than the largest level number of T. Level of
node & its generation: Each node in binary tree T is
assigned a level number, as follows.
• The root R of the tree T is assigned the level number
0, and every other node is assigned a level number
which is 1 more than the level number of its parent.
Furthermore, those nodes with the same level
number are said to belong to the same generation.
Complete Binary Tree
• Complete Binary Tree: Consider a binary tree
T. each node of T can have at most two
children. Accordingly. A tree is said to be
complete if all its levels, except possibly the
last have the maximum number of possible
nodes, and if all the nodes at the last level
appear as far left as possible.
Extended Binary Tree: 2-Tree
• Extended Binary Tree: 2-Tree:
• A binary tree T is said to be a 2-tree or an
extended binary tree if each node:
– N has either 0 or 2 children.
– In such a case, the nodes, with 2 children are
called internal nodes,
– node with 0 children are called external node.
Traversing of Binary Tree:
Traversing of Binary Tree:
Preparing a Tree from an infix arithmetic
expression
Binary Search Tree:
• Suppose T is a binary tree, the T is called a
binary search tree or binary
• sorted tree if each node N of T has the
following property:
– The values of at N (node) is greater than every
value in the left sub tree of
– N and is less than every value in the right sub tree
of N.
• Binary Search Tree using these values: (50, 30,
55, 25, 10, 35, 31,37, 20, 53, 60, 62)
Following figure shows a binary search tree. Notice that this
tree is obtained by inserting the values 13, 3, 4, 12, 14, 10, 5,
1, 8, 2, 7, 9, 11, 6, 18 in that order, starting from an empty
tree.
sorting
• Sorting: Note that inorder traversal of a binary
search tree always gives a sorted
• sequence of the values. This is a direct
consequence of the BST property.
• This provides a way of sorting a given sequence of
keys: first, create a BST with these keys and then
do an inorder traversal of the BST so created.
• Inorder Travers (LNR) : 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
11, 12, 13, 15, 18
Search
• Search: is straightforward in a BST. Start with
the root and keep moving left or right using
the BST property. If the key we are seeking is
present, this search procedure will lead us to
the key. If the key is not present, we end up in
a null link.
Insertion
• Insertion in a BST is also a straightforward
operation. If we need to insert an element n,
we traverse tree starting from root by
considering the above stated rules. Our
traverse procedure ends in a null link. It is at
this position of this null link that n will be
included.
Deletion in BST
• Deletion in BST: Let x be a value to be deleted
from the BST and let N denote the node
containing the value x. Deletion of an element
in a BST again uses the BST property in a critical
way. When we delete the node N containing x,
it would create a "gap" that should be filled by a
suitable existing node of the BST. There are two
possible candidate nodes that can fill this gap,
in a way that the BST property is not violated:
• 1) Node containing highest valued element among
all descendants of left child of N.
• 2)Node containing the lowest valued element
among all the descendants of the right child of N.
There are three possible cases to consider:
– Deleting a leaf (node with no children): Deleting a leaf is easy, as we
can simply remove it from the tree.
– Deleting a node with one child: Delete it and replace it with its child.
– Deleting a node with two children: Call the node to be deleted "N". Do
not delete N. Instead, choose its in-order successor node "S". Replace
the value of “N” with the value of “S”. (Note: S itself has up to one child.)
• As with all binary trees, a node's in-order
successor is the left-most child of its right
subtree. This node will have zero or one child.
Delete it according to one of the two simpler
cases above.
Graph data structure
Data structure
2nd stage
Directed and Undirected Graphs
A graph is a mathematical structure consisting of a set of
vertices and a set of edges connecting the vertices. Formally, we
view the edges as pairs of vertices; an edge (v, w) connects
vertex v with vertex w. We write G = (V,E) to denote that G is a
graph with vertex set V and edge set E.
A graph G = (V,E) is undirected if for all vertices v,w Є V we have
(v,w) Є E if, and only if, (w, v) Є E, that is, if all edges go both
ways. If we want to emphasise that the edges have a direction,
we call a graph directed. For brevity, a directed graph is often
called a digraph, and an undirected graph is simply called a
graph. We shall not use this convention here; for us `graph‘
always means `directed or undirected graph'.
When drawing graphs, we represent a vertex
by a point or circle containing the name of the
vertex, and an edge by an arrow connecting
two vertices. When drawing undirected
graphs, instead of drawing two arrows (one in
each direction) between all vertices, we just
draw one line connecting the vertices.
• Figure shows a drawing of the
(directed) graph G = (V,E) with
vertex set
V ={ 0,1,2, 3, 4, 5, 6}
and edge set
E = {(0, 2), (0, 4), (0, 5), (1; 0), (2,1), (2, 5),
(3, 1), (3, 6), (4, 0), (4, 5), (6, 3), (6, 5)}
Use of graph
• Graphs are a useful mathematical model for
numerous .real life. problems and structures.
Here are a few examples:
• Airline route maps:
Vertices represent airports, and there is an edge
from vertex A to vertex B if there is a direct
flight from the airport represented by A to the
airport represented by B.
• Road Maps.
Edges represent streets and vertices represent
crossings.
• Electrical Circuits.
Vertices represent diodes, transistors,
capacitors, switches, etc., and edges represent
wires connecting them.
• Computer Networks.
Vertices represent computers and edges
represent network connections (cables)
between them.
• The World Wide Web.
Vertices represent webpages, and edges
represent hyperlinks.
• Flowcharts.
A flowchart illustrates the flow of control in a
procedure. Essentially, a flowchart consists of
boxes containing statements of the procedure
and arrows connecting the boxes to describe
the flow of control. In a graph representing a
flowchart, the vertices represent the boxes
and the edges represent the arrows.
Data structures for graphs
• Let G = (V,E) be a graph with n vertices. We
assume that the vertices of G are numbered 0,
…., n - 1 in some arbitrary manner.
The adjacency matrix data structure
• For example, the adjacency matrix for the
graph in Figure
The adjacency list data structure
• The adjacency list representation of a graph G
with n vertices consists of an array vertices
with n entries, one for each vertex. The entry
for vertex v is a list of all vertices w such there
is an edge from v to w. We make assumptions
on the order in which the vertices adjacent to
a vertex v appear in the adjacency list, and our
algorithms should work for any order.
• shows an adjacency list representation of the
graph in Figure
Traversing Graphs
• Most algorithms for solving problems on
graphs examine or process each vertex and
each edge of the graph in some particular
order. The skeleton of such an algorithm will
be a traversal of the graph, that is, a strategy
for visiting the vertices and edges in a suitable
order.
• Breadth-first search (BFS) and depth-first search (DFS) are
two traversals that are particularly useful. Both start at
some vertex v and then visit all vertices reachable from v
(that is, all vertices w such that there is a path from v to
w).