You are on page 1of 106

Data Structures (2)

Dr. S.S.Shehaby

1
ADT: Abstract data types (copied)
• A set of data values and associated operations
that are precisely specified independent of any
particular implementation.
• A kind of data abstraction where a type's
internal form is hidden behind a set of access
functions. Values of the type are created and
inspected only by calls to the access
functions. This allows the implementation of
the type to be changed without requiring any
changes outside the module in which it is
defined.
• Objects and ADTs are both forms of data
abstraction, but objects are not ADTs. Objects
use procedural abstraction (methods), not type
abstraction.
2
ADT and DT (what is abstract)

• Abstract data types, commonly abbreviated


ADTs, are a way of classifying data structures
based on how they are used and the behaviors
they provide. They do not specify how the data
structure must be implemented but simply
provide a minimal expected interface and set
of behaviors.
• Data Structure is a concrete implementation of
a data type. It’s possible to analyze the time
and memory complexity of a Data Structure but
not from a data type. The Data Structure can
be implemented in several ways (Data Storage
Model)
• ADT: Model of a data structure. It is just an
idea for a data structure, implementation does
not matter

3
Array ADT

• The array is an abstract data type (ADT) that


holds a collection of elements accessible by
an index.
• Minimal Required Functionality:
• set(i,v) -> Sets value of element of index i to v
• get(i) -> Returns the value of element if index i
• Dynamic arrays are implemented in a way they
are capable of resizing and holding more
elements as needed.
• Storage Model: contiguous, sparse,
triangular, pointers, jagged, ...etc.

4
Living with Ambiguities/vagueness
• A Class in OO is a data structure with other
meta concepts associated like inheritance,
polymorphism/late binding.
• An interface in Java or Abstract Classes which
contains only pure virtual functions in C++
may be considered as representation of an ADT.
• a container is a class, a data structure, or
an abstract data type (ADT) whose instances
are collections of other objects with basic
operations:
• Create/delete a container (constructor)
• Destroy a container
• Insert/delete objects
• access the object(s)
• May be Traverse/Iterate may be with an ordering
relation
5
The Matrix ADT
• Logical Horizontal/Vertical Contiguity, homogenous
m
𝑎00 𝑎01 𝑎02
n 𝑎10 𝑎11 𝑎12 …

• Basic Functionality: set/get element at (i,j)
• Implementation using an Array data structure
(physical contiguity memory model: [𝑎00 , 𝑎01 ,
𝑎02 ,... 𝑎0,𝑚−1 , 𝑎10 , 𝑎11 , 𝑎12 ,...]
• Total Storage = n*m*s ;where s=sizeof(element)
• Relative Address of (i,j) element= (i*m+j)*s
𝑎00 0 0
• Triangular n*n Matrix: 𝑎 … implementation
10 𝑎11 0

storing only non Zero elements [𝑎00 , 𝑎10 , 𝑎11 ,...]:
• Total Storage = n*(n+1)/2*s ;
• Relative Address of (i,j): if j>i element=0
else relative address= (i*(i+1)/2 +j)*s
6
The Stack ADT, LIFO
A classic example of an ADT is a stack data type
for which functions might be provided to create
an empty stack, to push values onto a stack and
to pop values from a stack.
A stack can have any abstract data type as an
element, but is characterized by two fundamental
operations, called push and pop.
first proposed in 1946, in the computer design
of Alan M. Turing (who used the terms "bury"
and "unbury") as a means of calling and returning
from subroutines.
Applications: functions, simulation (planes,
garages,…), parsing, …
7
Stacks
#include <stdio.h>
#include <stdlib.h>
#define TYPE int
#define STACKSIZE 1000

typedef struct {
int top;
TYPE items[STACKSIZE];
} Stack;

int main()
{
Stack s; //or Stack *ps

return 0;
}

8
Stacks
#include <stdio.h>
#include <stdlib.h>
#define TYPE int
#define STACKSIZE 1000

typedef struct {
int top;
TYPE items[STACKSIZE];
} Stack;

void push(Stack *s,TYPE value) {s->items[s->top++]=value;}


TYPE pop(Stack *s) {return s->items[--s->top];}
int main()
{
Stack s; push(&s,5); push(&s,6);
printf("[%d]",pop(&s));printf("[%d]",pop(&s));
return 0;
}

9
Stacks
#include <stdio.h>
#include <stdlib.h>
#define TYPE int [6][5]
#define STACKSIZE 1000
Process returned 0 (0x0) …
typedef struct {
int top;
TYPE items[STACKSIZE];
} Stack;
Stack* initialize() {Stack *s=malloc(sizeof(Stack));
s->top=0; return s;}
void push(Stack *s,TYPE value) {s->items[s->top++]=value;}
TYPE pop(Stack *s) {return s->items[--s->top];}
int isfull(Stack *s) {return s->top<STACKSIZE?0:1 ;}
int isempty(Stack *s) {return s->top==0?1:0;}int main()
{
Stack *s=initialize(); s.top=0; push(s,5); push(s,6);
while (!isempty(s) printf("[%d]",pop(s));;
return 0;
}

10
The C++ style (the header .h ADT)
#include <stdlib.h>
#include <stdio.h>
#define TYPE int
#define STACKSIZE 1000
class Stack{
private: // default
int top;
TYPE *items;
public:
Stack () ; // constructor
void push(TYPE value) ;
TYPE pop() ;
int isfull() ;
int isempty() ;
int peek();
void dispStack();
// Overloading
Stack (int capacity) ;
~Stack(); // destructor
};
11
The C++ style (the .cpp DT)
Stack::Stack(){
top=0;// or this.top=0;
items=(TYPE*) malloc(STACKSIZE*sizeof(TYPE));
capacity=STACKSIZE;}
void Stack::push(TYPE value) {items[top++]=value;}
TYPE Stack::pop() {return items[--top];};
TYPE Stack::peek() {return items[top-1];};
int Stack::isempty() {return top==0?1:0;}
int Stack::isfull() {return top<capacity?0:1;}
Stack::Stack(int capacity){
top=0;// or this.top=0;
items=(TYPE*) malloc(capacity*sizeof(TYPE));
this->capacity=capacity; }
Stack::~Stack(){ delete items;}
void Stack::dispStack(){
int i;printf("|");
for (i=0;i<top;i++) printf("%c",items[i]);
12 printf("|"); }
Some Stack operations and Big O
 int getSum(Stack *s), int getMax(Stack*s), int
count(Stack *s), etc. How to?
 How Complex, how to measure time performance and space
requirements
 Why time and number of bytes are not suitable?
 The relation between number of computations abd size of
problem
 The big O Notation is a mathematical notation that
describes the limiting behavior of a function when the
argument tends towards a large values (unstated
infinity):
f(x)=O(g(x))   x>x’ : f(x) ≤ C * g(x) (x->∝)
if and only if For all Constants
Constant Tends to infinity
13
Some Stack operations and Big O
f(x)=O(g(x))   x>x’ : f(x) ≤ C * g(x) (x->∝)

14
Some Stack operations and Big O
f(x)=O(g(x))   x>x’ : f(x) ≤ C * g(x) (x->∝)
Time Complexity:
 Define type of basic operation (compare, add, multiply)
 Define size of problem N (number of elements, …)
 Count, big O for large N
Example array of size N:
 Get / Set element by index: constant=O(1)
 Search element by value ?
 Best case O(1)
 Average /Worst case O(n)
 Insert/delete element: O(n)
 Binary search a sorted array=N+N/2+N/4+…+1=O(log2(N))
15
Some Stack operations and Big O
f(x)=O(g(x))   x>x’ : f(x) ≤ C * g(x) (x->∝)
Time Complexity:
 Define type of basic operation (compare, add, multiply)
 Define size of problem N (number of elements, …)
 Count, big O for large N
Example Stack of size N elements:
 push(Stack *), pop(), isFull(), … peek(): constant=O(1)
 int getSum(Stack *s), int getMax(*Stack*s), int count(Stack
*s), search(Stack *s, int value): c*N=O(N)
 However: int getSum(Stack *s), int getMax(*Stack*s),
int count(Stack *s) can be done in O(1) with extra
memory storage !

16
Example - Decimal to binary
Stack *s=initialize(); O(number of digits)
int x=777;
1100001001
while(x) {push(s,x%2);x/=2;}
while(! isempty(s)) printf("%d",pop(s));

Example – Reverse words


Stack *s=initialize(); O(number of words)
char str[]=“How are you”; you are how
char *pt=strtok(str,” ”);
while(pt) {push(s,pt); pt=strtok(NULL,” ”);}
while(! isempty(s)) printf("%s",pop(s));

Example – Expression notation


Infix notation((1+2)*3)-4 O(number of ops)
Polish/Prefix Notation:-*+1234
Reverse Polish/Postfix Notation:12+3*4-
17
Examples - Evaluate Postfix
/* Evaluate Postfix Notation/Reverse Polish Notation [Łukasiewicz]
124*+3+
if operand push it else pop 2 and evaluate and push it again */
void error() {printf("error");exit(-1);}
int main()
{
Stack *s=initialize();
char *postExp="1 2 4 * + 3 +";int i;
for (i=0;i<strlen(postExp);i++)
if (postExp[i]==' ') continue;
if (postExp[i]<='9' && postExp[i]>='0') push(s,postExp[i]-'0');
else {
int a,b; if (isempty(s)) error(); else a=pop(s);
if (isempty(s)) error(); else b=pop(s);
switch(postExp[i]) {
case '+': push(s,a+b);break; case '-': push(s,a-b);break;
case '*': push(s,a*b);break; case '/': push(s,a/b);break;
default:error(); } // switch
}
printf("%s=%d",postExp,pop(s)); 1 2 4 * + 3 +=12
return 0;
18 }
Infix to postfix ( No parenthesis, No Precedence)

1. Read an token input, if no token Go to step (3) 1+2->1 2


2. Switch case on input: +
case:
1+2 *->1 2 +
Number (2.2) Print, Go to step (1) *
Operator (2.3) Push into stack, Go to
step (1)
1+2 * 3->1 2 +3
*

(2.4.3) Else: Report


Error/stop
3. if stack is empty Go to 4
(3.1) pop from stack and print
(3.2) Go to 3 1+2 * 3->1 2 +3 *
4. End

19
Infix to postfix (No Brackets, No op Precedence)
Input: String inf – Output: String post
Variables used: Stack stack, String temp
while inf not empty do 1+2->1 2
tok=getNext (inf) +
if tok is value then concat tok to post
1+2 *->1 2 +
*

1+2 * 3->1 2 +3
*
else /* tok must be operator */

push (stack,tok)
end
end
while(s not empty) do/*remaining */
1+2 * 3->1 2 +3 *
concat pop(stack) to post
end
20
Infix to postfix (No op Precedence)
( 1+(2->1 2
1. Read an token input, if no token Goto step (3) +
2. Switch case on input:
case Opening brackets (2.1) Push into stack, Go to *
step (1) ( 1+(2 *->1 2 +
Number (2.2) Print, Go to step (1) +
Operator (2.3) Push into stack, Go to
step (1)
Closing brackets (2.4) Pop it from the stack 1+(2 * 3)->1 2 3 *
(2.4.1) If it is an operator, +
print it, Go to (2.4)
(2.4.2) If it is an opening
bracket, discard, Go
to step (1)
(2.4.3) Else: Report
Error/stop
3. if stack is empty Go to 4
(3.1) pop from stack and print
1+2 * 3->1 2 +3 * +
(3.2) Go to 3
4. End

21
Infix to postfix (No op Precedence)
Input: String inf – Output: String post (
Variables used: Stack stack, String tok, temp 1+(2->1 2
+
while inf not empty do :
tok=getNext(inf) *
if tok is value then concat tok to post ( 1+(2 *->1 2 +
else if tok is '(' push(stack,'(') +
else if tok is ')' then
while (stack not empty)
1+(2 * 3)->1 2 3 *
temp=pop(stack) +
if temp is '(' break
concat temp to post
else /* tok must be operator */
while(s not empty)
temp=pop(stack)
if temp <>'(' concat temp to post
push (stack,tok)
while(s not empty) /*remaining */
1+2 * 3->1 2 +3 * +
if (temp=peek(s) is '(') err();
concat pop(stack) to post
22
Examples – Infix to Postfix
Stack *s=initialize();// NO OP priority
1 2 3 4
// Input (((8+1)-(7-4))/(9-8))
// Output: 8 1 + 7 4 - - 9 8 - /
+
char * inStr="(((8 + 1) - (7 - 4)) / (11 - 9))";
( ( (
int i; char ch,ch1,*pt=inStr;
( ( ( (
while (ch=*pt++){ // step 1
if (ch>='0' && ch<='9') printf("%c ",ch);
( ( ( (
else switch(ch) { (((8 (((8+ (((8+1 (((8+1)
case '(': 8 8 8 1 8 1 +
case '+': case '-': case '*': case '/':
push(s,ch);break; 6
case ')': while (!isempty(s)) {
ch1=pop(s); 5 ( 7
if (ch1=='(') break; -
(
printf("%c ",ch1); (
}
- -
(
} ( (
( (((8+1)-( (
}
81+
while(!isempty(s)) {if (peek(s)=='(') err(); (((8+1)- (((8+1)-(7
printf("%c ",pop(s);}// remaining 81+ 81+7
23
Examples – Infix to Postfix
Stack *s=initialize();// NO OP priority (((8+1)-(7-4))+(9-8))
// Input (((8+1)-(7-4))/(9-8)) (< |(| pfx:
// Output: 8 1 + 7 4 - - 9 8 - / (< |((| pfx:
char * inStr="(((8 + 1) - (7 - 4)) / (11 - 9))"; (< |(((| pfx:
8< |(((| pfx:8
int i; char ch,ch1,*pt=inStr;
+< |(((+| pfx:8
while (ch=*pt++){ // step 1
1< |(((+| pfx:81
if (ch>='0' && ch<='9') printf("%c ",ch); )< |((| pfx:81+
else switch(ch) { -< |((-| pfx:81+
case '(': (< |((-(| pfx:81+
case '+': case '-': case '*': case '/': 7< |((-(| pfx:81+7
push(s,ch);break; -< |((-(-| pfx:81+7
case ')': while (!isempty(s)) { 4< |((-(-| pfx:81+74
ch1=pop(s); )< |((-| pfx:81+74-
if (ch1=='(') break; )< |(| pfx:81+74--
+< |(+| pfx:81+74--
printf("%c ",ch1);
(< |(+(| pfx:81+74--
}
9< |(+(| pfx:81+74--9
} -< |(+(-| pfx:81+74--9
} 8< |(+(-| pfx:81+74--98
while(!isempty(s)) {if (peek(s)=='(') err(); )< |(+| pfx:81+74--98-
printf("%c ",pop(s);}// remaining )< || pfx:81+74--98-+
postfix: 81+74--98-+
8 1 + 7 4 - - 9 8 - +
24
Reminder (No op Precedence)
Input: String inf – Output: String post
Variables used: Stack stack, String tok, temp
while inf not empty: 1+2->1 2
+
tok=getNext(inf)
if tok is value then concat tok to post
1+2 *->1 2 +
else if tok is '(' push(stack,'(') *
else if tok is ')' then
while (stack not empty)
1+2 * 3->1 2 +3
temp=pop(stack) *
if temp is '(' break
concat temp to post
else /* tok must be operator */
while(s not empty)
temp=pop(stack)
if temp <>'(' concat temp to post
push (stack,tok)
while(s not empty) /*remaining */ 1+2 * 3->1 2 +3 *
if (temp=peek(s) is '(') err();
concat pop(stack) to post
25
Infix to postfix
Input: String inf – Output: String post
Variables used: Stack stack, String tok, temp
while inf not empty: 1+2->1 2
+
tok=getNext(inf)
if tok is value then concat tok to post * 1+2 *->1 2
else if tok is '(' push(stack,'(') +
else if tok is ')' then
while (stack not empty) * 1+2 * 3->1 2 3
temp=pop(stack) +
if temp is '(' break
concat temp to post
else /* tok must be operator */
while(s not empty && isLowerPrec (tok,peek(stack))
temp=pop(stack)
if temp <>'(' concat temp to post
push (stack,tok)
while(s not empty) /*remaining */
if (temp=peek(s) is '(') err(); 1+2 * 3->1 2 3 * +
concat pop(stack) to post
26
(((8 + 1) - (7 - 4)) / (6 - 9))<-->
Infix to postfix 81+74--69-/
input: String inf - output: String post, a+b/c<-->a b c / +
variables Stack stack, String tok, temp a/b+c<-->a b / c +
while inf not empty: .
tok=getNext(inf)
if tok is value then concat tok to post
else if tok is '(' push(stack,'(')
else if tok is ')' then
while (stack not empty)
temp=pop(stack)
if temp is '(' break
concat temp to post
else /* tok must be operator */
while(s not empty && isLowerPrec (tok,peek(stack))
temp=pop(stack)
if temp <>'(' concat temp to post
push (stack,tok)
while(s not empty) /*remaining */
if (temp=peek(s) is '(') err();
concat pop(stack) to post
27
Infix to Postfix int prec(char c){
switch (c) {
case '+' : case '-' : return 1;
void err() {printf("Error in expression");exit(0);}
case '*' : case '/' : return 2;
void infix_postfix(char*inf) {
default : printf("Error ");return -1;
char ch,post[strlen(inf)+1]; Stack *s=initialize();
}
printf("%s\n",inf); }
while (ch=*inf++) { int isLowerPrec (char ch1,char ch2){
if (ch==' ' ) continue; return prec(ch1)<prec(ch2);
if (ch>='0' && ch<= '9') post[index++]=ch; }
else if (ch=='(') push(s,ch);
else if (ch==')') // pop up to (
{ while(!isempty(s) && peek(s)!='(') post[index++]=pop(s);
if (isempty(s)|| peek(s)!='(') err();
pop(s); }
else { // operator
while(!isempty(s) && peek(s)!='(' && isLowerPrec (ch,peek(s)) )
{char x=pop(s); if (x!='(') post[index++]=x;}
push(s,ch); }
}
while(!isempty(s)) {if (peek(s)=='(') err();
post[index++]=pop(s);}// remaining
post[index++]=0;printf("postfix: %s\n",post);
for (index=0;index<strlen(post);index++) printf("%c ",post[index]);printf("\n");
}
28
Infix to Postfix int prec(char c){
switch (c) {
case '+' : case '-' : return 1;
void err() {printf("Error in expression");exit(0);}
case '*' : case '/' : return 2;
void infix_postfix(char*inf) {
case '(' : return 9;
char ch,post[strlen(inf)+1]; Stack *s=initialize();
default : printf("Error ");return -1;
printf("%s\n",inf); }
while (ch=*inf++) { }
if (ch==' ' ) continue; int isLowerPrec (char ch1,char ch2){
if (ch>='0' && ch<= '9') post[index++]=ch; return prec(ch1)<prec(ch2);
// else if (ch=='(') push(s,ch); }
else if (ch==')') // pop up to (
{ while(!isempty(s) && peek(s)!='(') post[index++]=pop(s);
if (isempty(s)|| peek(s)!='(') err();
pop(s); }
else { // operator
while(!isempty(s) && peek(s)!='(' && isLowerPrec(ch,peek(s)) )
{char x=pop(s); if (x!='(') post[index++]=x;}
push(s,ch); }
}
while(!isempty(s)) {if (peek(s)=='(') err();
post[index++]=pop(s);}// remaining
post[index++]=0;printf("postfix: %s\n",post);
for (index=0;index<strlen(post);index++) printf("%c ",post[index]);printf("\n");
}
29
1+2-3*4
1< || pfx:1
+< |+| pfx:1
2< |+| pfx:12
-< |+-| pfx:12 C:-+ isLower failed
3< |+-| pfx:123
*< |+-*| pfx:123 C:*- isLower failed
4< |+-*| pfx:1234
postfix: 1234*-+

1*2/3+4
1< || pfx:1
*< |*| pfx:1
2< |*| pfx:12
/< |*/| pfx:12 C:/* isLower failed
3< |*/| pfx:123
+< |+| pfx:123/* C:+/ True C:+* True
4< |+| pfx:123/*4
postfix: 123/*4+
30
(((8+1)-(7-4))/(9-8))
(< |(| pfx:
(< |((| pfx:
(< |(((| pfx:
8< |(((| pfx:8
+< |(((+| pfx:8
1< |(((+| pfx:81
)< |((| pfx:81+
-< |((-| pfx:81+
(< |((-(| pfx:81+
7< |((-(| pfx:81+7
-< |((-(-| pfx:81+7
4< |((-(-| pfx:81+74
)< |((-| pfx:81+74-
)< |(| pfx:81+74--
/< |(/| pfx:81+74--
(< |(/(| pfx:81+74--
9< |(/(| pfx:81+74--9
-< |(/(-| pfx:81+74--9
8< |(/(-| pfx:81+74--98
)< |(/| pfx:81+74--98-
)< || pfx:81+74--98-/
postfix: 81+74--98-/
8 1 + 7 4 - - 9 8 - /

31
Infix to Postfix int prec(char c){
switch (c) {
case '#' : return 0;
void err() {printf("Error in expression");exit(0);}
case '(' : return 1;
void infix_postfix(char*inf) {
case '+' : case '-' : return 2;
char ch,post[strlen(inf)+1]; Stack *s=initialize();
case '*' : case '/' : return 3;
printf("%s\n",inf); push (s,’#’); default : printf("ERR");
while (ch=*inf++) { return -1;}
if (ch==' ' ) continue;
if (ch>='0' && ch<= '9') post[index++]=ch; int isLowerPrec (char ch1,char ch2){
else if (ch=='(') push(s,ch); return prec(ch1)<prec(ch2);
else if (ch==')') // pop up to ‘(‘ }
{ while( peek(s)!='(') post[index++]=pop(s);
if (isempty(s)|| peek(s)!='(') err();
pop(s); }
else { // operator
while( isLowerPrec(ch,peek(s)) )
{char x=pop(s); if (x!='(') post[index++]=x;}
push(s,ch); }
}
while(!isempty(s)) {if (peek(s)=='(') err();
post[index++]=pop(s);}// remaining
post[index++]=0;printf("postfix: %s\n",post);
for (index=0;index<strlen(post);index++) printf("%c ", post[index]); printf("\n");
}
32
main.cpp
(((8+1)-(7-4))/(9-8)) Stack.h
(< |#(| pfx: Stack.cpp
(< |#((| pfx:
(< |#(((| pfx:
8< |#(((| pfx:8
+< |#(((+| pfx:8 C:+(
1< |#(((+| pfx:81
)< |#((| pfx:81+
-< |#((-| pfx:81+ C:-(
(< |#((-(| pfx:81+
7< |#((-(| pfx:81+7
-< |#((-(-| pfx:81+7 C:-(
4< |#((-(-| pfx:81+74
)< |#((-| pfx:81+74-
)< |#(| pfx:81+74--
/< |#(/| pfx:81+74-- C:/(
(< |#(/(| pfx:81+74--
9< |#(/(| pfx:81+74--9
-< |#(/(-| pfx:81+74--9 C:-(
8< |#(/(-| pfx:81+74--98
)< |#(/| pfx:81+74--98-
)< |#| pfx:81+74--98-/
postfix: 81+74--98-/

33
Assignment
Generalize:
 Integers instead of single digits
 Operators are strings not characters
 Unary operators
 Variables, symbol table

 Examples: 123 >> 2 * 3 / neg(-5)


-> 123 2 >> 3 * 5 neg /
x+3*z
scanf(x,z) -> x 3 z * +

34
Realated Problems (1)

Parse HTML/XML (Tagged Syntax)


<!DOCTYPE html>
<html>
<body>
<h1>My First Heading</h1>
<p>My first paragraph.</p>
</body>
</html>
Formal Languages, Grammars:
 Type 3: regular -> finite state automaton
 Type 2:context free -> push down automaton
 ... etc
dfdf

35
The Queue Abstract Data
Type
A queue is a data structure that
models/enforces the first-come first-
serve order, or equivalently the first-in
first-out (FIFO) order.
That is, the element that is inserted first
into the queue will be the element that
will deleted first, and the element that is
inserted last is deleted last.
A waiting line is a good real-life example
of a queue. (In fact, the British word for
“line” is “queue”.)

36
A Graphic Model of a
Queue

Head:
Tail:
All items are
All new items
deleted from
are added on
this end this end

37
Operations on Queues
Insert(item): (also called enqueue)
 It adds a new item to the tail of the queue
Remove( ): (also called delete or dequeue)
 It deletes the head item of the queue, and returns to the caller. If
the queue is already empty, this operation returns NULL
getHead( ):
 Returns the value in the head element of the queue (peekHead())
getTail( ):
 Returns the value in the tail element of the queue (peekTail())
isEmpty( )
 Returns true if the queue has no items
size( )
 Returns the number of items in the queue

38
Examples of Queues
An electronic mailbox is a queue
 The ordering is chronological (by arrival
time)
A waiting line in a store, at a service
counter, on a one-lane road
Equal-priority processes waiting to run
on a processor in a computer system

39
How head and tail Change
Head/Front increases by 1 after each dequeue( )/get()

Tail/Rear increases by 1 after each enqueue( )/put()

tail head
Now:
49 48 47 4 3 2 1 0
tail head
After enqueue:
49 48 47 4 3 2 1 0
tail head
After dequeue:
40
49 48 47 4 3 2 1 0
A Circular Queue
Allow the head (and the tail) to be moving
targets
When the tail end fills up and front part of the
array has empty slots, new insertions should go
into the front end
tail head

49 48 47 4 3 2 1 0

Next insertion goes into slot 0, and tail tracks


it. The insertion after that goes into a lot 1, etc.

41
Illustration of Circular
Queues
Current state: head

49 48 47 4 3 2 1 0
tail
After One Call to enqueue()
head tail

49 48 47 4 3 2 1 0

After One Call to enqueue()


head tail

49 48 47 4 3 2 1 0
42
Numerics for Circular
Queues
head increases by (1 modulo capacity)
after each dequeue( ):
head = (head +1) % capacity;
tail increases by (1 modulo capacity)
after each enqueue( ):
tail = (tail +1) % capacity;

43
Implementing a Queue
#define TYPE int
typedef struct {
int front,rear,numberItems;
int Capacity;
TYPE *items;
} Queue;
Queue * initialize(int size) {
Queue *s=malloc(sizeof(Queue));
s->rear=0;s->front=0;
s->numberItems=0; s->Capacity=size;
s->items=malloc(size*sizeof(TYPE));
return s ;}
void enqueue(Queue *s,TYPE value) {
s->items[s->rear++]=value;
s->rear%=s->Capacity;
s->numberItems++;}
TYPE dequeue(Queue *s) {
s->front%=s->Capacity; /*can do better?*/
s->numberItems--;
return s->items[s->front++];}

44
Implementing a Queue
#define TYPE int

typedef struct {
int front,rear,numberItems;
int Capacity;
TYPE *items;
} Queue;

int isfull(Queue *s) {


return s->numberItems==s->Capacity?1:0 ;}
int isempty(Queue *s) {
return s->numberItems==0?1:0; }
void dispose(Queue *s) {free(s->items); free(s);}

45
Implementing a Queue
#define TYPE int

typedef struct {
int front,rear,numberItems;
int Capacity;
TYPE *items;
} Queue;

int main()
{
Queue *q=initialize(100);
int i;for (i=0;i<q->Capacity+10;i++) if (!isfull(q))
enqueue(q,i);
while (!isempty(q)) printf("[%d]",dequeue(q));
dispose(q);
enqueue(q,7);/// ERROR
return 0;
}
[0][1][2][3][4]...[98][99]

46
Queue applications
Simulation
System scheduling
Search for solution (breadth first in
problem solving)
...

47
Queue applications
Simulation
System scheduling
Search for solution (breadth first in
problem solving)
...

48
Queue applications (Radix Sort)
#define RADIX 10
void radix_sort(int *arr, const int size) {
Queue *queues[RADIX];int i,j,mx,count,exp=1;
for (j=0;j<RADIX;j++) queues[j]=newQueue();
mx=*arr; for (i=1;i<size;i++) if (arr[i]>mx) mx=arr[i]; // get max
count=0; while (mx) {count++;mx/=RADIX;} // get max # of digits
printf("Radix %d, max_digits=%d\n",RADIX,count);
while(count--) {
for (i=0;i<size;i++) enqueue(queues[arr[i]/exp%RADIX],arr[i]);
i=0;
for (j=0;j<RADIX;j++)
while (!isEmpty(queues[j])) arr[i++]=dequeue(queues[j]);
printArr(arr,size);
exp*=RADIX; }
}
49
Queue applications (Radix Sort)
#define RADIX 10
int main(){
int data[] = { 20903,980, 99999,111, 42, 1111, 21 , 997, 1,1111};
radix_sort(data,sizeof(data)/4);
}
Radix 10, max_digits=5
980 111 1111 21 1 1111 42 20903 997 99999
1 20903 111 1111 1111 21 42 980 997 99999
1 21 42 111 1111 1111 20903 980 997 99999
1 21 42 111 20903 980 997 1111 1111 99999
1 21 42 111 980 997 1111 1111 20903 99999

50
Queue applications (Radix Sort)
#define RADIX 2
int main(){
int data[] = { 20903,980, 99999,111, 42, 1111, 21 , 997, 1,1111};
radix_sort(data,sizeof(data)/4);}
Radix 2, max_digits=17
980 42 20903 99999 111 1111 21 997 1 1111
980 21 997 1 42 20903 99999 111 1111 1111
1 42 980 21 997 20903 99999 111 1111 1111
1 980 21 997 20903 1111 1111 42 99999 111
1 997 20903 42 111 980 21 1111 1111 99999
1 980 21 1111 1111 99999 997 20903 42 111
1 21 99999 20903 42 980 1111 1111 997 111
1 21 42 1111 1111 111 99999 20903 980 997
1 21 42 1111 1111 111 99999 20903 980 997
1 21 42 1111 1111 111 20903 99999 980 997
1 21 42 111 20903 980 997 1111 1111 99999
1 21 42 111 20903 980 997 1111 1111 99999
1 21 42 111 980 997 1111 1111 99999 20903
1 21 42 111 980 997 1111 1111 99999 20903
1 21 42 111 980 997 1111 1111 99999 20903
1 21 42 111 980 997 1111 1111 20903 99999
51
1 21 42 111 980 997 1111 1111 20903 99999
Some C++ (Optional)
Structure:File Stack.h Class: File Stack.hpp
#ifndef STACK_H_INC #ifndef STACK_H_INCLUDED
#define STACK_H_INC #define STACK_H_INCLUDED
#define STACKSIZE 100 #define STACKSIZE 100
typedef struct { class Stack{
////// // NOT VERY DESCENT TO comment the
} Stack; following 3 lines
/*private: // default
//int top;
int *items;
*/
//However you can do !
public:
Stack * initialize() ; Stack () ; // constructor
void push(Stack *s,int value) ; void push(int value) ;
TYPE pop(Stack *s) ; int pop() ;
int isfull(Stack *s) ; int isfull() ;
int isempty(Stack *s) ; int isempty() ;
// Extra features: Overloading
Stack*initialize2(int capacity); Stack (int capacity) ;
void destruct(Stack *); ~Stack(); // destructor
#endif // STACK_H_INCLUDED } ;
52 #endif // STACK_H_INCLUDED
Some C++
Structure:File main.c Class: File main.cpp
#include "Stack.h" #include "Stack.h"
void display(Stack *s) { void display(Stack *s) {
Stack *cop=initialize(); Stack *cop=new Stack();
printf("["); printf("[ ");
while (!isempty(s)) { while (!s->isempty()) {
int x=pop(s); int x=s->pop();
printf("%i ",x); cout << x << " ";
//OR printf("%i ",x);
push(cop,x); cop->push(x);
} }
printf("]\n"); cout << "]"<<endl ;
while (!isempty(cop)) //OR printf("]\n");
push (s,pop(cop)); while (!cop->isempty())
} s->push (cop->pop());
}

53
Some C++
Structure:File main.c Class: File main.cpp
int main() int main()
{ {
Stack *s=initialize(); Stack *s=new Stack() ;
int i;
for (i=0;i<10;i++) for (int i=0;i<10;i++)
push(s,i); s->push(i);
display(s); display(s);
destruct(s); delete s;

s=s=initialize2(5); s=new Stack(5);


for (i=0;i<10;i++) for (int i=0;i<10;i++)
if (!isfull(s)) if (!s->isfull())
push(s,i); s->push(i);
display(s); display(s);
return 0;} return 0;}
[9876543210]
54
[43210]
Some C++
Structure:File Stack.c Class: File Stack.cpp
#define STACKSIZE 100 #define STACKSIZE 100
class Stack {
private:
int top;
TYPE *items;
int capacity;
typedef struct {
public:
int top;
Stack () ; // constructor
int *items;
void push(TYPE ) ;
int capacity;
int pop() ;
} Stack;
int isfull() ;
int isempty() ;
// overloading
Stack (int) ;
~Stack(); // destructor
} ;

55
Some C++
Structure:File Stack.c Class: File Stack.cpp
Stack* initialize2 Stack::Stack(){
(int capacity){ top=0;// or this.top=0;
Stack *s=malloc( items= malloc(
sizeof(Stack)); STACKSIZE*sizeof(TYPE));
s->top=0; capacity=STACKSIZE;
s->items=malloc( }
capacity*sizeof(int)); //overloading constructor
s->capacity=capacity; Stack::Stack(int capacity)
return s;} {top=0;// or this.top=0;
items=malloc(capacity
Stack* initialize(){ *sizeof(TYPE));
initialize2(STACKSIZE); this->capacity=capacity;
} }

56
Some C++
Structure:File Stack.c Class: File Stack.cpp
void destruct(Stack*s){ Stack::~Stack(){
free(s- delete items;
>items);free(s); }
} void Stack::push(int value)
void push(Stack *s {
,int value) items[top++]=value;
{ }
s->items[s->top++]=
value;
}

int isempty(Stack *s) int Stack::isempty()


{return s->top==0?1:0;} {return top==0?1:0;}

57
A Linked List Implementation of the Stack
and the Queue ADTs’

The container for items can be a linked list


!! What is that?
A linked list is a sequence of items
(objects) where every item is linked to the
next.

data data data data

Start End

58
Definition Details
Each item has a data part (one or more data
members), and a link that points to the next
item
One natural way to implement the link is as a
pointer; that is, the link is the address of the
next item in the list
It makes good sense to view each item as an
object, that is, as an instance of a class.
We call that class: Node
The last item does not point to anything. We
set its link member to NULL.

59
A Linked List Implementation of the Stack
and the Queue ADTs’

The container for items can be a linked


list !!
 What is that?
data data data data

Start/Head list ! End/Tail list !

Easy to insert Easy to insert


Easy to delete

Stack: TOP Stack: -


Queue: Front, Head Queue: Rear, Tail
60
Examples of Linked Lists
(A Polynomial)
Better Space complexity for Sparse Data
A polynomial of degree n is the function
Pn(x)=a0+a1x+a2x2+…+anxn. The ai’s are called
the coefficients of the polynomial
The polynomial can be represented by a linked
list, for example
a0+a2x2+a2x3+…+anxn

a0,0 a2,2 a3,3 an,n

start_ptr end_ptr
Easy to insert Easy to insert
Easy to delete
61
Linked Lists
Some Linked List operations:
 Head/Tail --- Start/End
 Insert a new item

 At the head of the list, or


 At the tail of the list, or
 Inside the list, after some designated node
 Search for an item in the list

 The item can be specified by position, or by some value

 Delete an item from the list

 Search for and locate the item, then remove the item, and
finally adjust the surrounding pointers
 int size( );

 int isEmpty( )

Special cases:
 Stack: Only Insert/Delete at start of the list

 Queue: Only Insert at end and Delete start of the list

 Dequeue: Insert/Delete from start [O(1)] , insert after end


[O(1)] and delete end [O(n)]
62
Insert– At the start
Insert a new data A. Call new: newPtr A
List before insertion:

data data data data

start_ptr end_ptr
After insertion to start:
A data data data data

start_ptr end_ptr
•The link value in the new item = old head_ptr
•The new value of head_ptr = newPtr

63
Insert – at the end of list
Insert a new data A. Call new: newPtr A
List before insertion

data data data data

start_ptr end_tail

After insertion to tail:


data data data data A

end_ptr
start_ptr
•The link value in the new item = NULL
•The link value of the old last item = newPtr

64
Delete – the Start Item
List before deletion:

data data data data data

start_ptr end_ptr

List after deletion of the head item:


data data data data data

start_ptr end_ptr

•The new value of start_ptr = link-value of the old start item


•The old start item is deleted and its memory returned

65
Delete – the End Item
List before deletion:

data data data data data

start_ptr end_ptr
How to get the before last? List after deletion of the
tail item:
data data data data data

end_ptr
start_ptr

•New value of tail_ptr = link-value of the node before last


•New link-value of new last item = NULL.

66
size() and isEmpty()
We need to scan the items in the list from the head_ptr to
the last item marked by its link-value being NULL
Count the number of items in the scan, and return the
count. This is the size().
Alternatively, keep a counter of the number of item, which
gets updated after each insert/delete. The function size( )
returns that counter
If head_ptr is NULL, isEmpty() returns true; else, it returns
false.

Searching for an Item


You have to search sequentially starting from the head item
rightward until the first item whose data member is equal to
A is found. At each item searched, a comparison between
the data member and A is performed.
67
Linked List: Insert Start

Insert Start/Head:
•Allocate a new node
•Insert new element
•Make new node point to old head
•Update head to point to new node
HEAD
FRONT
data data data data End/Tail
TAIL
REAR
Start/Head
val
void insert_start(LinkedList *list,TYPE val){
1 1 Node *p=newNode(val);
p->next=list->start;
list->start=p;
Easy to insert if (!list->end) list->end=p;
}
68
Linked List: Insert Start
#define TYPE int typedef struct {
typedef struct Node Node;
Node *start, *end;
typedef struct Node {
TYPE data; } LinkedList;
Node *next; LinkedList *newLinked(){
} Node; LinkedList *l=malloc
Node * newNode(TYPE value) { (sizeof(LinkedList));
Node *n=malloc(sizeof(Node)); l->start=NULL;l->end=NULL;
n->data=value; return l;
n->next=NULL; } HEAD
return n;} FRONT
data data data data End
TAIL
REAR
Start
val void insert_start(LinkedList *list,TYPE val){
1 Node *p=newNode(val);
1
p->next=list->start;
list->start=p;
Easy to insert if (!list->end) list->end=p;
}
69
Linked List: Insert Start
#define TYPE int typedef struct {
typedef struct Node Node;
Node *start, *end;
typedef struct Node {
TYPE data; } LinkedList;
Node *next; LinkedList *newLinked(){
} Node; LinkedList *l=malloc
Node * newNode(TYPE value) { (sizeof(LinkedList));
Node *n=malloc(sizeof(Node)); l->start=NULL;l->end=NULL;
n->data=value; return l;
n->next=NULL; } HEAD
return n;} FRONT
data data data data End
TAIL
REAR 2
Start
val void insert_start(LinkedList *list,TYPE val){
Node *p=newNode(val);
X 2 p->next=list->start;
list->start=p;
Easy to insert if (!list->end) list->end=p;
}
70
Linked List: Insert Start
#define TYPE int typedef struct {
typedef struct Node Node;
Node *start, *end;
typedef struct Node {
TYPE data; } LinkedList;
Node *next; LinkedList *newLinked(){
} Node; LinkedList *l=malloc
Node * newNode(TYPE value) { (sizeof(LinkedList));
Node *n=malloc(sizeof(Node)); l->start=NULL;l->end=NULL;
n->data=value; return l;
n->next=NULL; } HEAD
return n;} FRONT
data data data data End
TAIL
REAR
Start
3 val void insert_start(LinkedList *list,TYPE val){
X Node *p=newNode(val);
p->next=list->start;
3 list->start=p;
Easy to insert if (!list->end) list->end=p;
}
71
Linked Lists
void insert_start(LinkedList *list,TYPE val){
Node *p=newNode(val);
p->next=list->start;
list->start=p;
if (!list->end) list->end=p; Start
} End
2
TYPE del_start(LinkedList *list) {
1 Node* p=list->start;
data data data data
if (p) {
int val=p->data;
2 list->start=p->next; p
Free p
if (!list->start) list->end=NULL; 1
3
free(p);
return val;
}
return ERROR;
}

72
Linked Lists
void insert_end(LinkedList *list,TYPE val){
1 Node *p=newNode(val);
2 if (list->end) list->end->next=p;
3 list->end=p;
if (!list->start) list->start=p;
}
Start 3
End

data data data data val

p
2
1

73
Linked Lists
TYPE del_end(LinkedList *list) {
Node* p=list->start;
if(!p) return ERROR;
if (!p->next) return del_start(list);
// get previous of last
Node *prev=NULL;
1 while (p->next) {prev=p;p=p->next;}
2 int v=p->data;free(p);
3 list->end=prev;
4 prev->next=NULL;
return v; Start
} End
2 Free p
3
data data data data

4 prev 1 p

74
Recursive versus Iterative (Single Ended)
Start/Head
(list) data data data data

Node *n

void printLinkedList(Node *n){


printf("[");
while (n) {printf("%d ",n->data);n=n->next;}
printf("]\n");
}
void printLinkedListRecursive(Node *n){
if (!n) printf("\n");
else {printf("%d ",n->data);
printLinkedListRecursive(n->next);
}
}
Node * search(Node *n,TYPE value) {
if (!n) return NULL;
if (n->data==value) return n;
else return search(n->next,value);
}
75
Back To Stacks
typedef struct Node Node;

struct Node {
int item;
Node * next;
};
typedef struct Stack Stack;
struct Stack{
Node * Top;
};

Node* constructNode(int val) {


Node * p=(Node *)malloc(sizeof(Node));
p->item=val;
p->next=NULL; val
return p; Return value
}
Stack *initialize() {
Stack*s=malloc(sizeof(Stack)); Stack
s->Top=NULL;return s; Top
76 }
typedef struct Node Node;

Back To Stacks struct Node {


int item;
Node * next;
};
typedef struct Stack Stack;
struct Stack{
Node * Top;
};

Stack
Top

void push(Stack *s,TYPE value) {


Node *p=constructNode(value); p value
p->next=s->Top;
s->Top=p;
}
77
typedef struct Node Node;

Back To Stacks struct Node {


int item;
Node * next;
};
typedef struct Stack Stack;
struct Stack{
Node * Top;
};

Stack
Top

void push(Stack *s,TYPE value) {


Node *p=constructNode(value); p value
p->next=s->Top;
s->Top=p;
}
78
typedef struct Node Node;

Back To Stacks struct Node {


int item;
Node * next;
};
typedef struct Stack Stack;
struct Stack{
Node * Top;
};

Stack
Top

void push(Stack *s,TYPE val1) {


Node *p=constructNode(value); val1
p->next=s->Top;
s->Top=p;
}
79
typedef struct Node Node;

Back To Stacks struct Node {


int item;
Node * next;
};
typedef struct Stack Stack;
struct Stack{
Node * Top;
};

Stack
Top

void push(Stack *s,TYPE val2) {


Node *p=constructNode(value); val2 val1
p->next=s->Top;
s->Top=p;
}

80
typedef struct Node Node;

Back To Stacks struct Node {


int item;
Node * next;
};
typedef struct Stack Stack;
struct Stack{
Node * Top;
};

Stack
Top

void push(Stack *s,TYPE val2) {


Node *p=constructNode(value); val2 val1
p->next=s->Top;
s->Top=p;
}

81
typedef struct Node Node;

Back To Stacks struct Node {


int item;
Node * next;
};
typedef struct Stack Stack;
struct Stack{
Node * Top;
};

Stack
Top

void push(Stack *s,TYPE val2) {


Node *p=constructNode(value); val2 val1
p->next=s->Top;
s->Top=p;
}

82
typedef struct Node Node;

Back To Stacks struct Node {


int item;
Node * next;
};
typedef struct Stack Stack;
struct Stack{
Node * Top;
};

Stack
Top

TYPE pop(Stack *s) {


p
Node *p=s->Top;
TYPE ret=p->item; val2 val1
ret=val2
s->Top=p->next;
free(p);
return ret;
}
83
typedef struct Node Node;

Back To Stacks struct Node {


int item;
Node * next;
};
typedef struct Stack Stack;
struct Stack{
Node * Top;
};

Stack
Top

TYPE pop(Stack *s) {


p
Node *p=s->Top;
TYPE ret=p->item; val2 val1
ret=val2
s->Top=p->next;
free(p);
return ret;
}
84
typedef struct Node Node;

Back To Stacks struct Node {


int item;
Node * next;
};
typedef struct Stack Stack;
struct Stack{
Node * Top;
};

Stack
Top
TYPE pop(Stack *s) {
p
Node *p=s->Top;
TYPE ret=p->item; val2 val1
s->Top=p->next;
free(p);
return ret; ret=val2
}
85
Back To Queues, Linked list
Implementation
typedef struct Node Node;
struct Node {
int val;
Node *next;
};
Node *newNode(int val){
Node * n=malloc(sizeof(Node));
n->val=val;n->next=NULL;
return n;
}
typedef struct {
Node *front, *rear;
} Queue;
Queue * initQueue() {Queue *q=malloc(sizeof(Queue));
q->front=q->rear=NULL;
return q;
}
void main (void) [0][1][2][3][4]...[98][99]
{
Queue *q=initQueue();
int i;for (i=0;i<100;i++) enqueue(q,i);//No isfull()
while (!isEmpty(q)) printf("[%d]",dequeue(q));
return 0;
}
86
Back To Queues, Linked list
Implementation
int isEmpty(Queue *q){
return q->front==NULL;
}

void enqueue(Queue *q,int val){


Node*n=newNode(val);
if (q->rear) q->rear->next=n;
q->rear=n;
if (!q->front) q->front=n;
}

int dequeue(Queue *q) {


Node *n=q->front;
int retval=n->val;
q->front=n->next;
if (!q->front) q->rear=NULL;
free(n);return retval;
}
87
Arrays: pros and cons
+ Fast element access, O(1) indexing
-- Hard to resize, insert/delete element O(n)

•Many applications require resizing!


•Required size not always immediately
available.

88
OO Node Class
public class Node {
// Instance variables:
private Object element;
private Node next;
/** Creates a node with null references to its element and next
node. */
public Node() {
this(null, null);
}
/** Creates a node with the given element and next node. */
public Node(Object e, Node n) {
element = e;
// Modifier methods:
next = n;
public void setElement(Object
} newElem) {
// Accessor methods: element = newElem;
public Object getElement() { }
return element; public void setNext(Node newNext) {
} next = newNext;
public Node getNext() { }
return next; }
}

89
Singly linked list
First Last

Insert to Empty List: last==NULL: O(1)


struct Node *addToEmpty(struct Node *last, int data)
{
struct Node *last =
(struct Node*)malloc(sizeof(struct Node));
last -> data = data;
last -> next = last; return last;
}
Insert at Start O(1)
Create a node, say T.
Make T -> next = last -> next.
last -> next = T.
Insert at End O(1)
Create a node, say T.
Make T -> next = last -> next;
last -> next = T.
last = T
Insert anywhere [O(1) after search O(N)]
Create a node, say T.
Search the node after which T need to be insert, say that node be P.
Make T -> next = P -> next;
P -> next = T.
90
Doubly Linked List
A doubly linked list is often more prev next
convenient!
Nodes store:
 element
 link to the previous node
elem node
 link to the next node
Special trailer and header nodes

header nodes/positions trailer

elements
Linked Lists
91
Insertion
We visualize operation insertAfter(p, X), which returns position q
p

A B C
p

A q C

p q

A B X C
Linked Lists
92
Insertion
We visualize operation insertAfter(p, X), which returns position q
p

A B C
p

A B q C

X 1-q=new Node(x)
p q

A B X C
Linked Lists
93
Insertion
We visualize operation insertAfter(p, X), which returns position q
p

A B C
2-q->next=p->next
p

A B q C

X
p q

A B X C
Linked Lists
94
Insertion
We visualize operation insertAfter(p, X), which returns position q
p

A B C
4-q->prev=p->next->prev
p

A B q C

X
p q

A B X C
Linked Lists
95
Insertion
We visualize operation insertAfter(p, X), which returns position q
p

A B C
5-p->next=q->next->prev=q
p

A B q C

X
p q

A B X C
Linked Lists
96
Insertion Algorithm
Algorithm insertAfter(p,e):

Create a new node v


v.setElement(e)
v.setPrev(p) {link v to its predecessor}
v.setNext(p.getNext()) {link v to its successor}
(p.getNext()).setPrev(v) {link p’s old successor to v}
p.setNext(v) {link p to its new successor, v}

return v {the position for the element e}

97
Deletion
We visualize remove(p), where p == last()
p

A B C D

A B C p

A B C
98
Deletion Algorithm

Algorithm remove(p):

t = p.element {a temporary variable to hold the return value}


(p.getPrev()).setNext(p.getNext()) {linking out p}
(p.getNext()).setPrev(p.getPrev())
p.setPrev(null) {invalidating the position p}
p.setNext(null)

return t

99
Possible tricks:
Grounded Singly Linked
Remove element
pointed by
current,
pointing to 10.
However this
approach will
not work if
curr->15, the
last element.

100
Possible tricks:
Grounded Singly Linked
Adding header
and trailer.!
Add 15 before
curr.
 New=Clone curr
 Set curr->next to
new
 Set data of curr
 If (tail==curr)
tail=curr->next
101
Possible tricks:
Grounded Doubly
linked Lists

Header/trailer
Delete Node curr
 Get data (8)
 curr->prev->next=curr->next
 Decrement list size (if you want)
and return value (8)
102
Doubly Circular Linked List

// Structure of the node


struct node
{
int data;
struct node *next; // Pointer to next node
struct node *prev; // Pointer to previous node
};

103
Doubly Circular Linked List
// Function to insert Node at the beginning of the List,
void insertBegin(struct Node** start, int value)
{
// Pointer points to last Node
struct Node *last = (*start)->prev;
struct Node* new_node = constructNode(value);
// setting up previous and next of new node
new_node->next = *start;
new_node->prev = last;
// Update next and previous pointers of start and last.
last->next = (*start)->prev = new_node;
// Update start pointer
*start = new_node;
}

104
Worst-case running time
In a singly linked list
+ insertion at head or tail is O(1)
+ deletion at Tail (start list, rear) is O(1), deletion
from Head (end list, front queue is O(n)
-- element access by value is still in O(n)
In a doubly linked (grounded/circular) list
+ insertion at head or tail is in O(1)
+ deletion at either end is on O(1)
-- element access by value is still in O(n)

105
Thanks

106

You might also like