Data Structures (Second Part)Lecture 3 :
Array, Linked List, Stack & Queue
Bong-Soo Sohn
Assistant ProfessorSchool of Computer Science and Engineering
Chung-Ang University
ADT (Abstract Data Type) ADT
specification of a set of data and the set of operations that can be performed on the data
ADT is abstract : independent of concrete implementations
can be thought as an interface (hidden from implementation)
In OOP, ADT is a class. Instance of ADT is an object.
C style ADTlong stack_create(); /* create new instance of a stack */ void stack_push(long stack, void *item); /* push an item on the stack */ void *stack_pop(long stack); /* get item from top of stack */ void stack_delete(long stack); /* delete the stack */
long stack; struct foo *f; stack = stack_create(); /* create a stack */ stack_push(stack, f); /* add foo structure to stack */ f = stack_pop(stack); /* get top structure from stack */
Array ADT Array is a consecutive set of memory locations.
Array ADT is a more general structure
Structure Array is
objects : A set of pairs < index; value > where
for each value from the set item.
Index is a finite ordered set of one or more dimensions
functions :for all A ∈ Array; i ∈ index; x ∈ item;j; size 2 integerArray Create(j, list) ::=Array Retrieve(A, i) ::=Array Store(A, i, x) ::=
end Array
Arrays in Cint list[5], *plist[5]
Implementationvariable Memory Address
list[0] (= base address)list[1] + sizeof(int)list[2] + 2 • sizeof(int)list[3] + 3 • sizeof(int)list[4] + 4 • sizeof(int)
5 pointers to integersfrom plist[0] to plist[4]
5 integers from list[0] to list[4]
Structure
collections of data of the different types
typedef struct PERSON {char name[10];int age;float salary;
}PERSON person;
Using Pointers
Set all pointers to NULL when they are not actually pointing to an objectp = NULL
*p
NULL?A value in location zero?
Explicit type castingpi = malloc(sizeof (int));pf = (float *) pi;
Heap malloc free
Garbage int *pi; pi = (int *)mlloc (sizeof (int));*pi = 1; pi = (int *) malloc ( sizeof (int));*pi = 2;
1
2
pi
garbage
Garbage Automatic garbage collection
Memory Leak
Dangling Pointer
Singly Linked Lists
a1
ptr
a2 an •
typedef struct list_node *list_pointer;typedef struct list_node {
char data[data];list_pointer link;
};
list_pointer ptr = NULL; /* create a null list */
Necessary capabilities for linked representations.
A mechanism for defining a node’s
structure :
self-referential structure A way to create new nodes : malloc A way to remove nodes : free
Create a new nodeptr
ptr = (list_pointer)malloc(sizeof(struct list_node));
Assign a value to a field in the node.
strcpy (ptr data, “bat”) ;ptr link = NULL;
(ptr link) (*ptr).linkIn general,e (*e)
ptr
Insertion (after node q)q
p
x(1)
(1) p = (list_pointer) malloc ( sizeof (struct list_node));p data = x;
(2)
(2) p link = q link;
(3)
(3) q link = p;
Deletion (after node q)
(2)
(2) q link = (q link) link;
q
(1) p = q link;
p
(1)
(3)
(3) free (p);
Stack
An ordered list in which insertions and deletions are made at one end called top.
LIFO (Last-In-First-Out) Operations
Create IsEmpty IsFull Push Pop
Implementation of Stack using Array
Stack CreateS ( max stack size ) ::=
#define MAX STACK SIZE 100
typedef struct {
int key ;
/* other fields */
} element ;
element stack[MAX STACK SIZE] ;
int top = –1;
Boolean IsEmpty ( stack ) ::= top 0
Boolean IsFull ( stack ) ::= top MAX_STACK_SIZE – 1
Stack Add ( stack, item ) ::= void add ( int *top, element item ) /* push */ { if ( *top MAX_STACK_SIZE – 1 ) { stack_full() ; return ; } stack[++*top] := item ; }
Element Delete ( stack ) ::= element delete ( int *top ) /* pop */ { if ( *top < 0 ) return stack_empty() ; return stack[(*top) – – ]; }
Queue
An ordered list in which all insertions take place at one end and all deletions take place at the opposite end.
Q = (a0, • • • , an-1)front
element
FIFO ( First-In-First-Out )
rear element
Implementation using Array. Queue CreateQ ( max_queue_size ) ::=
#define MAX_QUEUE_SIZE 100
typedef struct {
int key ;
/* other fields */
} element ;
element queue[MAX_QUEUE_SIZE] ;
int rear = – 1 ;
int front = – 1 ;
Boolean IsEmptyQ ( queue ) ::= front == rear
Boolean IsFullQ ( queue ) ::= rear == MAX_QUEUE_SIZE – 1
Queue AddQ ( queue, item ) ::= void addq ( int *rear, element item ) { if ( *rear = = MAX_QUEUE_SIZE – 1 ) { queue_full() ; return ; } queue[++*rear] = item ; }
Element DeleteQ (queue ) ::= element deleteq ( int *front, int rear ) { if ( *front = = rear ) return queue_empty() ; return queue[++*front] ; }
*A problem in the above implementation
front Q[0] Q[1] Q[2] Q[4] comments
–1–1–1–10112
J1 J1 J2
J1 J2 J3
J2 J3
J3
J3 J4
J4
empty queue
addq J1
addq J2
addq J3
delq J1
delq J2
delq J4
delq J3
rear
–10122233
The queue gradually shifts to the right
Circular queue implementation Regard the array as circular.
Initially front = rear = 0 A circular queue is empty if front == rear
before deletion A circular queue is full if front == rear
after insertion A circular queue holds at most
MAX_QUEUE_SIZE - 1 elements
void addq ( int front, int *rear, element item ){
if ( *rear == MAX_QUEUE_SIZE ) *rear == 0;else (*rear)++ ;
if (front == *rear) { queue_full() ; return; } queue[*rear] = item ;}
element deleteq ( int *front, int rear){ if ( *front == rear )
return queue_empty () ;
*front = ( *front + 1) % MAX_QUEUE_SIZE ;
return queue[*front] ;}
*rear = (*rear+1) % MAX_QUEUE_SIZE