0% found this document useful (0 votes)
12 views

CS DataStructure-Lecture 1-Stack Based Array

Data structure lectures

Uploaded by

AsmaaGhoniem
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
12 views

CS DataStructure-Lecture 1-Stack Based Array

Data structure lectures

Uploaded by

AsmaaGhoniem
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 27

Data Structure

Dr. Ahmed Hesham Mostafa


Lecture 1 –Stack(ADT) bases Arrays
TextBooks
• s k chang, “data structures and algorithms”
• Kruse and Leung, “Data Structures & Program Design in C”
Online Martials
• CS214: Data Structures by Prof. Dr Waleed A. Yousef
• https://www.youtube.com/playlist?list=PLoK2Lr1miEm-
5zCzKE8siQezj9rvQlnca
• Data Structures Learning Course by Dr Mohammed El-Said
• https://www.youtube.com/playlist?list=PLfay0LLBd0wiNeOR_SGoYfC
3w-NxFwd0D
• Lectures Source code (updated frequently)
• https://github.com/ahmedheshamostafa/DataStructure
Motivation: What and Why Stacks?

Push box Q onto empty stack: Q


|empty stack |

Push box A onto stack: A


Q

Pop a box from stack: A


Q

Pop a box from stack: Q


|empty stack |

© Waleed A. Yousef 2008 4


Push box R onto stack: R
|empty stack |

Push box D onto stack: D


R

Push box M onto stack: M


D
Q

Pop a box from stack: M


D
Q

S
Push box Q onto stack: Q Push box S onto stack: Q
D Q
Q Q

© Waleed A. Yousef 2008 5


Abstract Data Type (ADT)
• Definition: Abstract Data Type (ADT) is a data type that is accessed only through an
interface (or Accessing mechanism).
• We refer to a program that uses an ADT as a client (or user) and a program that
specifies the data type as an implementation
Stack(ADT)
• Definition: Stack of elements of type T is a finite sequence of elements of T
together with the following operations:
1. Create the stack, leaving it empty.
2. Determine whether the stack is empty or not.
3. Determine whether the stack is full or not.
4. Find the size of the stack.
5. Push a new entry onto the top of the stack, provided the stack is not full.
6. Pop the entry off the top of the stack, provided the stack is not empty.
7. Retrieve the Top entry off the stack, provided the stack is not empty.
8. Traverse the stack, visiting each entry.
9. Clear the stack to make it empty.
Type Definition

typedef struct stack{


int top;
StackEntry entry[MAXSTACK];
}Stack;
MAXSTACK-1
StackEntry and MAXSTACK
should be defined in the User
Level.

For the moment forget about


them. We will mention later how
top 0 they should be defined.
entry
struct stack Stack

© Waleed A. Yousef 2008 8


Implementation level User Level
(what really happens) (interface)
void CreateStack(Stack s){ void main(){
s.top=0;
} CreateStack Stack s;

MAXSTACK-1 CreateStack(s);

top -2580 0
entry }
s
When we return:

MAXSTACK-1

top -2580 0
entry
© Waleed A. Yousef 2008 s 9
Implementation level But this way User Level
(what really happens) (interface)
void CreateStack(Stack *ps){ void main(){
ps->top=0;
} Stack s;

CreateStack(&s);
CreateStack
&s }
ps
When we return:
The execution time does not
depend on n; therefore the
MAXSTACK-1 complexity is: O(1)

top -2580 0 top is the index of the first


entry available place.
© Waleed A. Yousef 2008
s 10
Implementation level User Level
(what really happens) (interface)
void Push(StackEntry e, Stack *ps){
ps->entry[ps->top]=e;
ps->entry[ps->top++]=e;
ps->top++;
}
void main(){
Push StackEntry e;
Stack s;
e &s 
ps CreateStack(&s);

Push(e, &s);
MAXSTACK-1
}
top 0
1 0 e
entry

© Waleed A. Yousef 2008


s 11
/*Pre: The stack is initialized and not full
Post: The element e has been stored at the top of the stack; and e
does not change*/
void Push(StackEntry e, Stack *ps){
ps->entry[ps->top++]=e;
}
The user has to check before calling Push
Other ways (no precondition) are: void main(){
if (ps->top==MAXSTACK) StackEntry e;
printf(“Stack is full”); Stack s;
else ps->entry[ps->top++]=e; 
//but this is not professional CreateStack(&s);

int Push(…){ if (!StackFull(s))
if (ps->top==MAXSTACK) Push(e, &s);
return 0; }
else {
ps->entry[ps->top++]=e; if (!Push(e, &s))
return 1; …
© Waleed A. Yousef 2008
}//This is fine 12
Implementation level User Level
(what really happens) (interface)
int StackFull(Stack *ps){
if (ps->top==MAXSTACK)
return 1;
else return ps->top >= MAXSTACK;
return 0; void main(){
} StackEntry e;
StackFull Stack s;

&s
CreateStack(&s);
ps

if (!StackFull(&s))
Push(e, &s);
MAXSTACK-1 }

top MAXSTACK 0 e
It could be: StackFull(s) but this
entry wastes memory and time of copying.
© Waleed A. Yousef 2008 s 13
Implementation level User Level
(what really happens) (interface)
void Pop(StackEntry *pe, Stack *ps){
ps->top--;
*pe=ps->entry[--ps->top];
*pe=ps->entry[ps->top];
}
void main(){
Pop StackEntry e;
Stack s;
&e &s 
pe ps CreateStack(&s);

Pop(&e, &s);
MAXSTACK-1
}
### top 1
0 0 ###
e entry

© Waleed A. Yousef 2008


s 14
/*Pre: The stack is initialized and not empty
Post: The last element entered is returned*/
void Pop(StackEntry *pe, Stack *ps){
*pe=ps->entry[--ps->top];
}
The user has to check before calling Pop
Other ways (no precondition) are: void main(){
if (ps->top==0) StackEntry e;
printf(“Stack is Empty”); Stack s;
else *pe=ps->entry[--ps->top]; 
//but this is not professional CreateStack(&s);

int Pop(…){ if (!StackEmpty(s))
if (ps->top==0) Pop(&e, &s);
return 0; }
else {
*pe=ps->entry[--ps->top]; if (!Pop(&e, &s))
return 1; …
© Waleed A. Yousef 2008
}//This is fine 15
Implementation level User Level
(what really happens) (interface)
int StackEmpty(Stack *ps){
if (ps->top==0)
return 1;
else return !ps->top;
return 0; void main(){
} StackEntry e;
StackEmpty Stack s;

&s
CreateStack(&s);
ps

if (!StackEmpty(&s))
Pop(&e, &s);
MAXSTACK-1 }

top 0 0 e
It could be: StackEmpty(s) but
entry this wastes memory and time of
copying.
© Waleed A. Yousef 2008 s 16
Implementation level User Level
(what really happens) (interface)
//Same preconditions of Pop.
void StackTop(StackEntry *pe, Stack *ps){
*pe=ps->entry[ps->top-1];
} void main(){
StackEntry e;
StackTop Stack s;

&e &s CreateStack(&s);
pe ps 
StackTop(&e, &s);
}
MAXSTACK-1
It could be: StackTop(&e,
### top 1 0 ### s)
e entry but this wastes memory and
© Waleed A. Yousef 2008
s time of copying 17
Implementation level User Level
(what really happens) (interface)
/*Pre: Stack is initialized.
Post: returns how many elements exist.
int StackSize(Stack *ps){
return ps->top; void main(){
} StackEntry e;
StackSize Stack s;
int x;
&s 
ps CreateStack(&s);

x=StackSize(&s);
MAXSTACK-1 }
It could be: StackSize(s)
top 1 0 ### but this wastes memory and
entry time of copying
© Waleed A. Yousef 2008
s 18
Implementation level User Level
(what really happens) (interface)
/*Pre: Stack is initialized.
Post: destroy all elements; stack looks initialized.
void ClearStack(Stack *ps){
ps->top=0; void main(){
} StackEntry e;
ClearStack Stack s;

&s CreateStack(&s);
ps 
ClearStack(&s);
}
MAXSTACK-1 Same code as CreateStack;
why new function then?
top 1
0 0 ### 1- conceptually
entry 2- will see later
© Waleed A. Yousef 2008
s 19
Implementation level
//Precondition: The stack is Initialized
void TraverseStack(Stack *ps, void(*pf)(StackEntry)){
for(int i=ps->top; i>0; i--)
(*pf)(ps->entry[i-1]); User Level:
} how to process each element with a user-
pf
defined function
=
&Display
void Display(StackEntry e){
printf(“e is: %d\n", e);
}
The code of
Display ps=&s void main(){

Stack s;
MAXSTACK-1
CreateStack(&s);
.
.
top 0 TraverseStack(&s, &Display);
entry }
s //&s only for efficiency as said before.
© Waleed A. Yousef 2008 20
Exercise: How to write the function StackTop in the user level? (e.g., if you do not
have the source code of the implementation)
User Level:
void StackTop(StackEntry *pe, Stack *ps){
Pop(pe, ps); /* Why interface, Pre, Post are crucial:
Push(*pe, ps); Pop takes a pointer to the element and a pointer to
} the stack.

Pre: The stack is initialized and not empty


void main(){
StackEntry e; Post: The last element entered is returned
Stack s;

CreateStack(&s);
Push takes the element itself and a pointer to the
 stack
StackTop(&e, &s);
} Pre: The stack is initialized and not full

Post: The element e has been stored at the top of the


stack; and e does not change*/
© Waleed A. Yousef 2008 21
void StackTop(StackEntry *pe, Stack *ps){
Pop(pe, ps); StackTop
Push(*pe, ps); &e &s
} pe ps
Push
Pop
###
&e &s
e pe ps

###
e

MAXSTACK-1

top 1
0 0 ###
entry

© Waleed A. Yousef 2008


s 22
Exercise: Assume that we need to read a line of text and write it back in a
reverse order. In general, store some data and retrieve it in a reverse order.

void ReverseRead(void){
StackEntry item;//StackEntry should be defined as char
Stack stack;
CreateStack(&stack);//Initialize the stack to be empty

while (!StackFull(&stack) && (item = getchar()) != '\n')


Push(item, &stack);//Push each item onto the stack

while (!StackEmpty(&stack)){
Pop(&item, &stack); //Pop an item from the stack.
putchar(item);
}
putchar('\n');
}

© Waleed A. Yousef 2008 23


StackEntry and MAXSTACK should be defined in the User
Level, because they concern the uer.

Also, they have to be defined in the implementation level, because


they are referenced in Stack.cpp

Therefore, they have to be defined in Stack.h which is included


in both Stack.cpp and the user main file.

So, the main file will compile even if stack.cpp is not compiled
yet. (check the homework; this is detailed in the sheet)

© Waleed A. Yousef 2008 24


/****Stack.h*******/
#define MAXSTACK 100

typedef struct stack{


int top;
StackEntry entry[MAXSTACK];
} Stack;

void Push (StackEntry, Stack *);


void Pop (StackEntry *, Stack *);
int StackEmpty (Stack *);
int StackFull (Stack *);
void CreateStack(Stack *);
void StackTop (StackEntry *, Stack *);
int StackSize (Stack *);
void ClearStack(Stack *);
void TraverseStack(Stack *, void (*)(StackEntry));

© Waleed A. Yousef 2008 25


References

Thanks

You might also like