This document provides an overview of Abstract Data Types (ADTs) focusing on stack and queue implementations. It outlines the operations associated with these data structures, including push, pop, size, and top. The analysis covers the complexity of operations, emphasizing the efficiency of stack operations in both array-based and linked list implementations. Additionally, it highlights practical applications, such as evaluating expressions in postfix notation. The document is intended for programmers seeking to understand data structure design and efficiency.
01 / 109Abstract Data Types Stack, Queue Amortized analysis
1 / 17
Télécharger la présentation
Abstract Data Types Stack, Queue Amortized analysis
Une image / un lien ci-dessous est fourni (tel quel) pour télécharger la présentation
Politique de téléchargement : le contenu du site vous est fourni TEL QUEL pour votre information et votre usage personnel ; il ne peut être vendu, concédé sous licence ni partagé sur d’autres sites sans l’accord de son auteur.Le contenu vous est fourni TEL QUEL, pour votre information et votre usage personnel uniquement.Téléchargez la présentation en cliquant sur ce lien.Lors du téléchargement, si vous ne parvenez pas à télécharger une présentation, l’éditeur a peut-être supprimé le fichier de son serveur.Pendant le téléchargement, si vous ne parvenez pas à obtenir une présentation, le fichier a peut-être été supprimé par l’éditeur.
ADT is an interface • It defines • the type of the data stored • operations, what each operation does (not how) • parameters of each operation
ADT Application חוזה בין מתכנת האפליקציה ומיישם מבנה הנתונים ממשק Implementation of the Data structure
Example: Stacks • Push(x,S) : Insert element x into S • Pop(S) : Delete the last element inserted into S • Empty?(S): Return yes if S is empty • Top(S): Return the last element inserted into S • Size(S) • Make-stack()
Pseudo-code S ← make-stack() while ( not eof ) do B ← read the next data; if B is an operand thenpush(B,S) else X ← pop(S) Y ← pop(S) Z ← Apply the operation B on X and Y push(Z,S) return(top(S))
Implementation • We will be interested in algorithms to implement the ADT.. • And their efficiency..
Using an array t 12 1 3 A A[2] A[1] A[N-1] A[0] The stack is represented by the array A and variable t 3 1 12
Using an array t 12 1 3 A A[2] A[1] A[N-1] A[0] The stack is represented by the array A and variable t make-stack(): Allocates the array A, which is of some fixed size N, sets t ← -1
Operations t 12 1 3 A A[2] A[1] A[N-1] A[0] size(S): return (t+1) empty?(S): return (t < 0) top(S): ifempty?(S) then error else return A[t]
Pop t 12 1 3 A A[2] A[1] A[N-1] A[0] pop(S): ifempty?(S) then error else e ←A[t] t ← t – 1 return (e) pop(S)
Pop t 12 1 3 A A[2] A[1] A[N-1] A[0] pop(S): ifempty?(S) then error else e ←A[t] t ← t – 1 return (e) pop(S)
Push t 12 1 3 A A[2] A[1] A[N-1] A[0] push(x,S): ifsize(S) = N then error else t ←t+1 A[t] ← x push(5,S)
Push t 12 1 5 A A[2] A[1] A[N-1] A[0] push(x,S): ifsize(S) = N then error else t ←t+1 A[t] ← x push(5,S)
x x.next x.element Implementation with lists top size=3 5 1 12
Pop top size=3 5 1 12 pop(S): ifempty?(S) then error else e ←top.element top ← top.next size ← size-1 return (e) pop(S)
Pop top size=2 5 1 12 pop(S): ifempty?(S) then error else e ←top.element top ← top.next size ← size-1 return (e) pop(S)
Garbage collection top size=2 5 1 pop(S): ifempty?(S) then error else e ←top.element top ← top.next size ← size-1 return (e) pop(S)
Push top size=2 5 1 push(x,S): n = new node n.element ←x n.next ← top top ← n size ← size + 1 push(5,S)
Push top size=2 5 1 5 push(x,S): n = new node n.element ←x n.next ← top top ← n size ← size + 1 push(5,S)
Push top size=2 5 1 5 push(x,S): n = new node n.element ←x n.next ← top top ← n size ← size + 1 push(5,S)
Push top size=3 5 1 5 push(x,S): n = new node n.element ←x n.next ← top top ← n size ← size + 1 push(5,S)
Analysis • Bound the running time of an operation on the worst-case • As a function of the “size”, n, of the data structure • T(n) < 4n+7 • Too detailed, we are just interested in the order of growth
Stacks via extendable arrays • We do not want our implementation using arrays to be limited to only N elements • When the array is full we will double its size
Push t 12 1 A A[1] A[N-1] A[0] push(x,S): ifsize(S) = N then allocate a new array of size 2N copy the old array to the new one t ←t+1 A[t] ← x
Push t 12 1 3 3 4 5 7 3 2 8 1 A A[1] A[N-1] A[0] push(x,S): ifsize(S) = N then allocate a new array of size 2N copy the old array to the new one t ←t+1 A[t] ← x push(5,S)
Push t 12 1 3 3 4 5 7 3 2 8 1 A A[1] A[0] push(x,S): ifsize(S) = N then allocate a new array of size 2N copy the old array to the new one t ←t+1 A[t] ← x push(5,S)
Push 12 1 3 3 4 5 7 3 2 8 1 t 12 1 3 3 4 5 7 3 2 8 1 A A[1] A[0] push(x,S): ifsize(S) = N then allocate a new array of size 2N copy the old array to the new one t ←t+1 A[t] ← x push(5,S)
Push t 12 1 3 3 4 5 7 3 2 8 1 A A[1] A[2N-1] A[0] push(x,S): ifsize(S) = N then allocate a new array of size 2N copy the old array to the new one t ←t+1 A[t] ← x push(5,S)
Push t 12 1 3 3 4 5 7 3 2 8 1 5 A A[1] A[2N-1] A[0] push(x,S): ifsize(S) = N then allocate a new array of size 2N copy the old array to the new one t ←t+1 A[t] ← x push(5,S)
Analysis • An operation may take O(n) worst case time ! • But that cannot happen often..
Amortized Analysis • How long it takes to do m operations ? • Well, O(nm) • Yes, but can it really take that long ?