parent
c0fe503a87
commit
fa1b27113f
@ -1,88 +0,0 @@
|
||||
---
|
||||
layout: simple
|
||||
---
|
||||
|
||||
# CMPT 225 - Introduction
|
||||
|
||||
## CMPT: 225, D100 --- Data Structures & Programming
|
||||
|
||||
## Graded Work
|
||||
|
||||
* 4 Assignments, 32%
|
||||
* Programming & Written Components
|
||||
* Programs:
|
||||
* In C++
|
||||
* running on ESIL Linux machines
|
||||
* using command line tools
|
||||
* 3 Tests, 33%
|
||||
* In class
|
||||
* 1 Final Exam, 35%
|
||||
|
||||
## Lectures
|
||||
|
||||
* Slides + audio recording will be posted <em>after</em> lectures.
|
||||
|
||||
## Labs
|
||||
|
||||
* There are <em>help times</em> (first labs are <em>next week</em>)
|
||||
|
||||
## Instructor Office Hours
|
||||
|
||||
* Will be primarily online --- times TBA.
|
||||
|
||||
## Instructor Contact
|
||||
|
||||
* Via Canvas or email (for email: write from your SFU account, use subject "225: ...")
|
||||
|
||||
## Some Basic Rules
|
||||
|
||||
* In class, do not distract others.
|
||||
* In class, no taking photos/videos/recording
|
||||
* Help each other, but submit your own work.
|
||||
* Masks are mandatory in class:
|
||||
* may be removed while asking a question
|
||||
* if you cannot wear a mask, please email me
|
||||
* Please stay on "your" side of the table
|
||||
* and stay 6' away if you don't have a mask on
|
||||
|
||||
## Course Content
|
||||
|
||||
* Algorithms: processes that operate on data
|
||||
* Programs: implementations of algorithms
|
||||
* Data in programs: stored in data structures
|
||||
* simple D.S.: variables
|
||||
* most algorithms required compound D.S.s: e.g. arrays, lists, ...
|
||||
* most non-trivial applications require non-trivial D.S.s
|
||||
* Data Type: collection of values + operations on these values
|
||||
* Multiple data types:
|
||||
* Cleaner/simpler slg. design
|
||||
* better code
|
||||
* Abstract Data Type: defined by values + operations without reference to how things are implemented
|
||||
* ADTs provide an abstract view of data:
|
||||
* let us reason about algorithms at a high level, ignoring implementation details
|
||||
* Good ADT choices reduce program complexity & increase likelihood of success ( which is good).
|
||||
* a[i] vs. a(i)
|
||||
|
||||
## We will look at:
|
||||
* fundamental ADTs
|
||||
* fundamental data structures (to implement them)
|
||||
* sorting algorithms
|
||||
* with attention to:
|
||||
* correctness
|
||||
* efficiency/speed
|
||||
* how to implement
|
||||
* how to choose (for an application)
|
||||
|
||||
## Pre-regs:
|
||||
|
||||
* Basic Programming (e.g. CMPT 125)
|
||||
* Discrete Math (e.g. MACM 101)
|
||||
|
||||
(students get these in many different ways)
|
||||
|
||||
## To Do
|
||||
|
||||
* Read chapters 1 + 3 of text
|
||||
* Lear about CSIL
|
||||
|
||||
## End
|
@ -1,357 +0,0 @@
|
||||
---
|
||||
layout: simple
|
||||
---
|
||||
|
||||
# Stacks & Queues - 1
|
||||
|
||||
CMPT 225, Fall 2021, Lecture 2
|
||||
|
||||
## Stack
|
||||
|
||||
* ADT that stores a collection of objects/values
|
||||
* Insertions and removals follow last-in-first-out pattern
|
||||
* Fundamental Operations:
|
||||
* push: inserts an element on the "top"
|
||||
* pop: removes + returns the top element
|
||||
|
||||
e.g.
|
||||
|
||||
Stack index|Value
|
||||
|
||||
push a
|
||||
|
||||
Stack index|Value
|
||||
0|a
|
||||
|
||||
push b
|
||||
|
||||
Stack index|Value
|
||||
0|b
|
||||
1|a
|
||||
|
||||
push c
|
||||
|
||||
Stack index|Value
|
||||
0|c
|
||||
1|b
|
||||
2|a
|
||||
|
||||
pop
|
||||
|
||||
Stack index|Value
|
||||
0|b
|
||||
1|a
|
||||
|
||||
* conventient optional operations
|
||||
* size: return # of elements on stack // encapsulation
|
||||
* empty: check for emptiness // better than "size=0?"
|
||||
* top: return top element, but don't remove it // better than x = pop(); push(x) then use x
|
||||
|
||||
## Algorithm Applications
|
||||
|
||||
* parasing/evaluation/transformation of expressions
|
||||
* speech recognition coding/decoding
|
||||
* shared network access control
|
||||
* programming languages & execution
|
||||
* Postscript, Forth, the call stack
|
||||
* things we do daily with computers
|
||||
|
||||
## Parenthasies Checking
|
||||
|
||||
Parenthasies: `(()(((()())()()(()))`
|
||||
|
||||
A diagram showing:
|
||||
For every left parenthasies, add one to a counter.
|
||||
For every right parthenthasies, remove one from the counter.
|
||||
If the counter is not zero by the end of the sequence, there are too many on one side of the parenthasies.
|
||||
|
||||
Can be done by counting unmached left parenthasies:
|
||||
|
||||
Successful example:
|
||||
|
||||
Character|Counter
|
||||
|0
|
||||
(|1
|
||||
(|2
|
||||
)|1
|
||||
(|2
|
||||
(|3
|
||||
)|2
|
||||
)|1
|
||||
)|0
|
||||
Yay!|0
|
||||
|
||||
Failed example:
|
||||
|
||||
Character|Country
|
||||
|0
|
||||
(|1
|
||||
(|2
|
||||
)|1
|
||||
(|2
|
||||
)|1
|
||||
|Oh no it's not zero!
|
||||
|
||||
Another fail:
|
||||
|
||||
Character|Counter
|
||||
|0
|
||||
(|1
|
||||
)|0
|
||||
(|1
|
||||
)|0
|
||||
)|-1
|
||||
|Negative 1 this time!
|
||||
|
||||
Do this one yourself:
|
||||
|
||||
Character|Counter
|
||||
(|
|
||||
)|
|
||||
)|
|
||||
(|
|
||||
|
||||
But consider multiple grouping symbols: `(\{\{)`, `(\{)\{`, `(\{[( ... ]`.
|
||||
Counting is not enough.
|
||||
|
||||
## Parenthasies Checking
|
||||
|
||||
Diagram showing failure on the last character of this sequence: `(()((()()))()(())))`
|
||||
|
||||
Can be done by counting unmatched left parenthasies:
|
||||
|
||||
Character|Counter
|
||||
(|1
|
||||
(|2
|
||||
)|1
|
||||
(|2
|
||||
(|3
|
||||
)|2
|
||||
)|1
|
||||
)|0
|
||||
|
||||
Example 2:
|
||||
|
||||
Character|Counter
|
||||
(|1
|
||||
(|2
|
||||
)|1
|
||||
(|2
|
||||
)|1
|
||||
|
||||
Example 3:
|
||||
|
||||
Character|Counter
|
||||
(|1
|
||||
)|0
|
||||
(|1
|
||||
)|0
|
||||
)|-1
|
||||
|
||||
Example 4:
|
||||
|
||||
Character|Counter
|
||||
(|1
|
||||
)|0
|
||||
)|-1
|
||||
(|0
|
||||
|
||||
But consider multiple grouping symbols:
|
||||
|
||||
* sequence `(\{\})` will and should work
|
||||
* sequence `(\{)\}` will work and should not
|
||||
* sequence `(\{[( ...` ???
|
||||
|
||||
Counting is not enough.
|
||||
|
||||
## Stack-based Algorithm for Checking Grouping Symbols
|
||||
|
||||
Pseudo-code:
|
||||
|
||||
```
|
||||
I is an input stream of symbols.
|
||||
S is a new empty stack.
|
||||
|
||||
while there are signals to read from I {
|
||||
c is next symbol from I
|
||||
if c is a left grouping signal {
|
||||
push c on S
|
||||
} else if c is a right grouping signal{
|
||||
if s in empty { report error and stop }
|
||||
d is pop S
|
||||
if c and d do not match { report error and stop }
|
||||
endif // if c is not a grouping symbol, ignore it
|
||||
end while
|
||||
|
||||
if S is not empty { report error and exit }
|
||||
report ok
|
||||
```
|
||||
|
||||
Diagram showing how each set of parenthasies are matched, innermost first torwards the outermost.
|
||||
|
||||
## Stack: Partially-Filled Array Implementation
|
||||
|
||||
Variables:
|
||||
|
||||
* A - an array of stack elements
|
||||
* capacity - size of array
|
||||
* top - index in array of top stack element
|
||||
* -1 if stack is empty
|
||||
|
||||
|
||||
A starts out as:
|
||||
|
||||
Index|0|1|2|...|capacity-1
|
||||
Value|a|b|c|...|
|
||||
|
||||
* Capacity = <size of A>
|
||||
* top = 2
|
||||
|
||||
push e
|
||||
|
||||
A now equals
|
||||
|
||||
Index|0|1|2|3|4|...|capacity-1
|
||||
Value|a|b|c|d|e|...|
|
||||
|
||||
* capacity = <size of A>
|
||||
* top = 3
|
||||
|
||||
## The Queue ADT
|
||||
|
||||
A container that stores a collection of items with insertion and removal in "first-in-first-out" order.
|
||||
|
||||
Stack: a digram showing circled being placed on top of eachother, pushing circles into the tube, then popping them out from the same size (the top). Like a pringles can of elements.
|
||||
|
||||
Queue: a diagram showing circles being unqueued in on the left and dequeued on the right. Like waiting in line for food.
|
||||
|
||||
Basic operations:
|
||||
* enqueue: add an item to the back of a list
|
||||
* dequeue: remove & return the item at the front of the list
|
||||
|
||||
## Example: Palindrome Checking
|
||||
|
||||
Sequence `aba` should succeed.
|
||||
Sequence `aab` should not.
|
||||
|
||||
In an array: a diagram showing the following pattern with the variable `i` set to the leftmost element and `j` set to the rightmost element.
|
||||
|
||||
Values|a|b|c|...|s|b|a
|
||||
|
||||
With a stack and queue:
|
||||
1. read symbols, starting each in a stack and a queue
|
||||
2. while the stack, queue are not empty:
|
||||
* pop and element from the stack + delete an element from the queue
|
||||
* if different -> not a palindrome
|
||||
3. palindrome
|
||||
|
||||
## Queue: Array Implementations
|
||||
|
||||
Enqueue: a,b,c,d.
|
||||
Front is now a, last is now d.
|
||||
|
||||
Values|a|b|c|d|...
|
||||
|
||||
Dequeue returns and deletes first element.
|
||||
Front is now b, last is now d.
|
||||
|
||||
Values|?|b|c|d|...
|
||||
|
||||
Many enquques/dequeues later:
|
||||
|
||||
Values|s|...|m|n|o
|
||||
|
||||
Front element is now `m`, last element is now s.
|
||||
|
||||
Values|?|t|u|v|w|...
|
||||
|
||||
A similar slide is here, but I can't see the differnece.
|
||||
|
||||
Variables:
|
||||
* array A is array of size capacity
|
||||
* front is 0
|
||||
* back is 0
|
||||
* size is 0
|
||||
* capacity = <size of array>
|
||||
|
||||
Pseudo-code:
|
||||
|
||||
```
|
||||
array A = array of size capacity // holds queue contents
|
||||
front = 0 // index in A of front element, if queue not empty
|
||||
back = 0 // index where next unqueued element will go
|
||||
size = 0 // number of elements in queue
|
||||
capacity = <size of array> // ???(can't read) queue size supported
|
||||
|
||||
enqueue(x) { // adds x to the back of the queue
|
||||
// requires size<capacity>
|
||||
A[back] = x
|
||||
size = size + 1
|
||||
back = (back + 1) % capacity
|
||||
}
|
||||
|
||||
dequeue() { // removes front element of queue and returns it
|
||||
// required size > 0
|
||||
temp = A[front]
|
||||
front = (front + 1) % capacity
|
||||
size = size - 1
|
||||
return temp
|
||||
}
|
||||
```
|
||||
|
||||
Is `size == front - back`?
|
||||
|
||||
Diagram showing only true if front and back haven't been switched around due to wrapping around back to the beginning o the array.
|
||||
|
||||
## "Circular Array" Queue Example
|
||||
|
||||
* size = 0
|
||||
* front = 0
|
||||
* back = 0
|
||||
|
||||
Values|empty|empty|empty|empty|empty|empty
|
||||
|
||||
enqueue: a,b,c,d
|
||||
|
||||
* front = 0
|
||||
* back = 4
|
||||
|
||||
Values|a|b|c|d|empty|empty
|
||||
|
||||
dequque 3 times
|
||||
|
||||
* front = 3
|
||||
* back = 4
|
||||
|
||||
Values|empty|empty|empty|d|empty|empty
|
||||
|
||||
enqueue e,f,g,h
|
||||
|
||||
* front = 3
|
||||
* back = 2
|
||||
|
||||
Values|g|h|empty|d|e|f
|
||||
|
||||
unqueue j
|
||||
|
||||
* size = 6
|
||||
* font = 3
|
||||
* back = 3
|
||||
|
||||
Values|g|h|j|d|e|f
|
||||
|
||||
dequeue 3 times
|
||||
|
||||
* back = 3
|
||||
* front = 0
|
||||
|
||||
Values|g|h|j|empty|empty|empty
|
||||
|
||||
dequeue 3 times
|
||||
|
||||
* back = 3
|
||||
* front = 3
|
||||
|
||||
Values|empty|empty|empty|empty|empty|empty
|
||||
|
||||
## End
|
@ -1,88 +0,0 @@
|
||||
---
|
||||
layout: simple
|
||||
---
|
||||
|
||||
# CMPT 225 - Introduction
|
||||
|
||||
## CMPT: 225, D100 --- Data Structures & Programming
|
||||
|
||||
## Graded Work
|
||||
|
||||
* 4 Assignments, 32%
|
||||
* Programming & Written Components
|
||||
* Programs:
|
||||
* In C++
|
||||
* running on ESIL Linux machines
|
||||
* using command line tools
|
||||
* 3 Tests, 33%
|
||||
* In class
|
||||
* 1 Final Exam, 35%
|
||||
|
||||
## Lectures
|
||||
|
||||
* Slides + audio recording will be posted <em>after</em> lectures.
|
||||
|
||||
## Labs
|
||||
|
||||
* There are <em>help times</em> (first labs are <em>next week</em>)
|
||||
|
||||
## Instructor Office Hours
|
||||
|
||||
* Will be primarily online --- times TBA.
|
||||
|
||||
## Instructor Contact
|
||||
|
||||
* Via Canvas or email (for email: write from your SFU account, use subject "225: ...")
|
||||
|
||||
## Some Basic Rules
|
||||
|
||||
* In class, do not distract others.
|
||||
* In class, no taking photos/videos/recording
|
||||
* Help each other, but submit your own work.
|
||||
* Masks are mandatory in class:
|
||||
* may be removed while asking a question
|
||||
* if you cannot wear a mask, please email me
|
||||
* Please stay on "your" side of the table
|
||||
* and stay 6' away if you don't have a mask on
|
||||
|
||||
## Course Content
|
||||
|
||||
* Algorithms: processes that operate on data
|
||||
* Programs: implementations of algorithms
|
||||
* Data in programs: stored in data structures
|
||||
* simple D.S.: variables
|
||||
* most algorithms required compound D.S.s: e.g. arrays, lists, ...
|
||||
* most non-trivial applications require non-trivial D.S.s
|
||||
* Data Type: collection of values + operations on these values
|
||||
* Multiple data types:
|
||||
* Cleaner/simpler slg. design
|
||||
* better code
|
||||
* Abstract Data Type: defined by values + operations without reference to how things are implemented
|
||||
* ADTs provide an abstract view of data:
|
||||
* let us reason about algorithms at a high level, ignoring implementation details
|
||||
* Good ADT choices reduce program complexity & increase likelihood of success ( which is good).
|
||||
* a[i] vs. a(i)
|
||||
|
||||
## We will look at:
|
||||
* fundamental ADTs
|
||||
* fundamental data structures (to implement them)
|
||||
* sorting algorithms
|
||||
* with attention to:
|
||||
* correctness
|
||||
* efficiency/speed
|
||||
* how to implement
|
||||
* how to choose (for an application)
|
||||
|
||||
## Pre-regs:
|
||||
|
||||
* Basic Programming (e.g. CMPT 125)
|
||||
* Discrete Math (e.g. MACM 101)
|
||||
|
||||
(students get these in many different ways)
|
||||
|
||||
## To Do
|
||||
|
||||
* Read chapters 1 + 3 of text
|
||||
* Lear about CSIL
|
||||
|
||||
## End
|
@ -1,357 +0,0 @@
|
||||
---
|
||||
layout: simple
|
||||
---
|
||||
|
||||
# Stacks & Queues - 1
|
||||
|
||||
CMPT 225, Fall 2021, Lecture 2
|
||||
|
||||
## Stack
|
||||
|
||||
* ADT that stores a collection of objects/values
|
||||
* Insertions and removals follow last-in-first-out pattern
|
||||
* Fundamental Operations:
|
||||
* push: inserts an element on the "top"
|
||||
* pop: removes + returns the top element
|
||||
|
||||
e.g.
|
||||
|
||||
Stack index|Value
|
||||
|
||||
push a
|
||||
|
||||
Stack index|Value
|
||||
0|a
|
||||
|
||||
push b
|
||||
|
||||
Stack index|Value
|
||||
0|b
|
||||
1|a
|
||||
|
||||
push c
|
||||
|
||||
Stack index|Value
|
||||
0|c
|
||||
1|b
|
||||
2|a
|
||||
|
||||
pop
|
||||
|
||||
Stack index|Value
|
||||
0|b
|
||||
1|a
|
||||
|
||||
* conventient optional operations
|
||||
* size: return # of elements on stack // encapsulation
|
||||
* empty: check for emptiness // better than "size=0?"
|
||||
* top: return top element, but don't remove it // better than x = pop(); push(x) then use x
|
||||
|
||||
## Algorithm Applications
|
||||
|
||||
* parasing/evaluation/transformation of expressions
|
||||
* speech recognition coding/decoding
|
||||
* shared network access control
|
||||
* programming languages & execution
|
||||
* Postscript, Forth, the call stack
|
||||
* things we do daily with computers
|
||||
|
||||
## Parenthasies Checking
|
||||
|
||||
Parenthasies: `(()(((()())()()(()))`
|
||||
|
||||
A diagram showing:
|
||||
For every left parenthasies, add one to a counter.
|
||||
For every right parthenthasies, remove one from the counter.
|
||||
If the counter is not zero by the end of the sequence, there are too many on one side of the parenthasies.
|
||||
|
||||
Can be done by counting unmached left parenthasies:
|
||||
|
||||
Successful example:
|
||||
|
||||
Character|Counter
|
||||
|0
|
||||
(|1
|
||||
(|2
|
||||
)|1
|
||||
(|2
|
||||
(|3
|
||||
)|2
|
||||
)|1
|
||||
)|0
|
||||
Yay!|0
|
||||
|
||||
Failed example:
|
||||
|
||||
Character|Country
|
||||
|0
|
||||
(|1
|
||||
(|2
|
||||
)|1
|
||||
(|2
|
||||
)|1
|
||||
|Oh no it's not zero!
|
||||
|
||||
Another fail:
|
||||
|
||||
Character|Counter
|
||||
|0
|
||||
(|1
|
||||
)|0
|
||||
(|1
|
||||
)|0
|
||||
)|-1
|
||||
|Negative 1 this time!
|
||||
|
||||
Do this one yourself:
|
||||
|
||||
Character|Counter
|
||||
(|
|
||||
)|
|
||||
)|
|
||||
(|
|
||||
|
||||
But consider multiple grouping symbols: `(\{\{)`, `(\{)\{`, `(\{[( ... ]`.
|
||||
Counting is not enough.
|
||||
|
||||
## Parenthasies Checking
|
||||
|
||||
Diagram showing failure on the last character of this sequence: `(()((()()))()(())))`
|
||||
|
||||
Can be done by counting unmatched left parenthasies:
|
||||
|
||||
Character|Counter
|
||||
(|1
|
||||
(|2
|
||||
)|1
|
||||
(|2
|
||||
(|3
|
||||
)|2
|
||||
)|1
|
||||
)|0
|
||||
|
||||
Example 2:
|
||||
|
||||
Character|Counter
|
||||
(|1
|
||||
(|2
|
||||
)|1
|
||||
(|2
|
||||
)|1
|
||||
|
||||
Example 3:
|
||||
|
||||
Character|Counter
|
||||
(|1
|
||||
)|0
|
||||
(|1
|
||||
)|0
|
||||
)|-1
|
||||
|
||||
Example 4:
|
||||
|
||||
Character|Counter
|
||||
(|1
|
||||
)|0
|
||||
)|-1
|
||||
(|0
|
||||
|
||||
But consider multiple grouping symbols:
|
||||
|
||||
* sequence `(\{\})` will and should work
|
||||
* sequence `(\{)\}` will work and should not
|
||||
* sequence `(\{[( ...` ???
|
||||
|
||||
Counting is not enough.
|
||||
|
||||
## Stack-based Algorithm for Checking Grouping Symbols
|
||||
|
||||
Pseudo-code:
|
||||
|
||||
```
|
||||
I is an input stream of symbols.
|
||||
S is a new empty stack.
|
||||
|
||||
while there are signals to read from I {
|
||||
c is next symbol from I
|
||||
if c is a left grouping signal {
|
||||
push c on S
|
||||
} else if c is a right grouping signal{
|
||||
if s in empty { report error and stop }
|
||||
d is pop S
|
||||
if c and d do not match { report error and stop }
|
||||
endif // if c is not a grouping symbol, ignore it
|
||||
end while
|
||||
|
||||
if S is not empty { report error and exit }
|
||||
report ok
|
||||
```
|
||||
|
||||
Diagram showing how each set of parenthasies are matched, innermost first torwards the outermost.
|
||||
|
||||
## Stack: Partially-Filled Array Implementation
|
||||
|
||||
Variables:
|
||||
|
||||
* A - an array of stack elements
|
||||
* capacity - size of array
|
||||
* top - index in array of top stack element
|
||||
* -1 if stack is empty
|
||||
|
||||
|
||||
A starts out as:
|
||||
|
||||
Index|0|1|2|...|capacity-1
|
||||
Value|a|b|c|...|
|
||||
|
||||
* Capacity = <size of A>
|
||||
* top = 2
|
||||
|
||||
push e
|
||||
|
||||
A now equals
|
||||
|
||||
Index|0|1|2|3|4|...|capacity-1
|
||||
Value|a|b|c|d|e|...|
|
||||
|
||||
* capacity = <size of A>
|
||||
* top = 3
|
||||
|
||||
## The Queue ADT
|
||||
|
||||
A container that stores a collection of items with insertion and removal in "first-in-first-out" order.
|
||||
|
||||
Stack: a digram showing circled being placed on top of eachother, pushing circles into the tube, then popping them out from the same size (the top). Like a pringles can of elements.
|
||||
|
||||
Queue: a diagram showing circles being unqueued in on the left and dequeued on the right. Like waiting in line for food.
|
||||
|
||||
Basic operations:
|
||||
* enqueue: add an item to the back of a list
|
||||
* dequeue: remove & return the item at the front of the list
|
||||
|
||||
## Example: Palindrome Checking
|
||||
|
||||
Sequence `aba` should succeed.
|
||||
Sequence `aab` should not.
|
||||
|
||||
In an array: a diagram showing the following pattern with the variable `i` set to the leftmost element and `j` set to the rightmost element.
|
||||
|
||||
Values|a|b|c|...|s|b|a
|
||||
|
||||
With a stack and queue:
|
||||
1. read symbols, starting each in a stack and a queue
|
||||
2. while the stack, queue are not empty:
|
||||
* pop and element from the stack + delete an element from the queue
|
||||
* if different -> not a palindrome
|
||||
3. palindrome
|
||||
|
||||
## Queue: Array Implementations
|
||||
|
||||
Enqueue: a,b,c,d.
|
||||
Front is now a, last is now d.
|
||||
|
||||
Values|a|b|c|d|...
|
||||
|
||||
Dequeue returns and deletes first element.
|
||||
Front is now b, last is now d.
|
||||
|
||||
Values|?|b|c|d|...
|
||||
|
||||
Many enquques/dequeues later:
|
||||
|
||||
Values|s|...|m|n|o
|
||||
|
||||
Front element is now `m`, last element is now s.
|
||||
|
||||
Values|?|t|u|v|w|...
|
||||
|
||||
A similar slide is here, but I can't see the differnece.
|
||||
|
||||
Variables:
|
||||
* array A is array of size capacity
|
||||
* front is 0
|
||||
* back is 0
|
||||
* size is 0
|
||||
* capacity = <size of array>
|
||||
|
||||
Pseudo-code:
|
||||
|
||||
```
|
||||
array A = array of size capacity // holds queue contents
|
||||
front = 0 // index in A of front element, if queue not empty
|
||||
back = 0 // index where next unqueued element will go
|
||||
size = 0 // number of elements in queue
|
||||
capacity = <size of array> // ???(can't read) queue size supported
|
||||
|
||||
enqueue(x) { // adds x to the back of the queue
|
||||
// requires size<capacity>
|
||||
A[back] = x
|
||||
size = size + 1
|
||||
back = (back + 1) % capacity
|
||||
}
|
||||
|
||||
dequeue() { // removes front element of queue and returns it
|
||||
// required size > 0
|
||||
temp = A[front]
|
||||
front = (front + 1) % capacity
|
||||
size = size - 1
|
||||
return temp
|
||||
}
|
||||
```
|
||||
|
||||
Is `size == front - back`?
|
||||
|
||||
Diagram showing only true if front and back haven't been switched around due to wrapping around back to the beginning o the array.
|
||||
|
||||
## "Circular Array" Queue Example
|
||||
|
||||
* size = 0
|
||||
* front = 0
|
||||
* back = 0
|
||||
|
||||
Values|empty|empty|empty|empty|empty|empty
|
||||
|
||||
enqueue: a,b,c,d
|
||||
|
||||
* front = 0
|
||||
* back = 4
|
||||
|
||||
Values|a|b|c|d|empty|empty
|
||||
|
||||
dequque 3 times
|
||||
|
||||
* front = 3
|
||||
* back = 4
|
||||
|
||||
Values|empty|empty|empty|d|empty|empty
|
||||
|
||||
enqueue e,f,g,h
|
||||
|
||||
* front = 3
|
||||
* back = 2
|
||||
|
||||
Values|g|h|empty|d|e|f
|
||||
|
||||
unqueue j
|
||||
|
||||
* size = 6
|
||||
* font = 3
|
||||
* back = 3
|
||||
|
||||
Values|g|h|j|d|e|f
|
||||
|
||||
dequeue 3 times
|
||||
|
||||
* back = 3
|
||||
* front = 0
|
||||
|
||||
Values|g|h|j|empty|empty|empty
|
||||
|
||||
dequeue 3 times
|
||||
|
||||
* back = 3
|
||||
* front = 3
|
||||
|
||||
Values|empty|empty|empty|empty|empty|empty
|
||||
|
||||
## End
|
@ -1,78 +0,0 @@
|
||||
---
|
||||
layout: simple
|
||||
---
|
||||
|
||||
# Memory & Pointers 1
|
||||
|
||||
CMPT-225, Fall 2021
|
||||
|
||||
## Computer Memory
|
||||
|
||||
* A sequence of locations
|
||||
* Indexed by address: 0,1,2,...
|
||||
* Each location stores a data *byte*
|
||||
* Processor can *read* or *write* the byte at each address.
|
||||
* Regions of memory are allocated to processes *as needed*, according to some scheme.
|
||||
|
||||
Diagram displaying "Code + Data for running part of OS" at the start of memory, "Free memory" in the middle, and "Code + Data for running user processes" and the end.
|
||||
|
||||
## Variables & Memory
|
||||
|
||||
A variable is (roughly) and names & tagged collection of bytes:
|
||||
|
||||
Diagram showing:
|
||||
* "int x; x = 6" taking 4 bytes of memory,
|
||||
* "char c; c = 'x';" taking 1 byte of memory
|
||||
* "bool b; b = 'true';" taking 1 byte of memory
|
||||
|
||||
* So, *at run time*, each variable has an *address* in memory.
|
||||
* In C, C++ we can:
|
||||
* access the address of a variable
|
||||
* access a variable or memory location by its address
|
||||
* declare variables by storing addresses (pointers).
|
||||
|
||||
## Addresses & Pointers - By Example
|
||||
|
||||
* "int i = 5;"
|
||||
* allocate space for an *int*,
|
||||
* name the space "i",
|
||||
* store 5 there
|
||||
* "int \*p;"
|
||||
* allocate space for an address,
|
||||
* name it p,
|
||||
* record its type as "pointer to int"
|
||||
* "p = ∧i;"
|
||||
* "&i" is the address of "i"
|
||||
* store ∧i in p
|
||||
* so, p becomes a *pointer to i*
|
||||
* "cout << i;"
|
||||
* outputs the value stored in i, *5*
|
||||
* "cout << p;"
|
||||
* outputs the address of i: 0xbffffbbc
|
||||
* "cout << \*p;"
|
||||
* "\*" *dereferences* p. That is, \*p is the value *pointed to by p*. In this case *5*
|
||||
|
||||
Diagram of memory:
|
||||
|
||||
Address|Name|Value
|
||||
...|...|...
|
||||
<span id="point">254</span>|i|5
|
||||
...|...|...
|
||||
923|p|<a href="#point">254</a>
|
||||
|
||||
Second diagram of memory:
|
||||
|
||||
Address|Name|Value|Size
|
||||
0x6fffbe|i|5|4 bytes
|
||||
...|...|...|...
|
||||
???|p|0x6fffbe|4 bytesa
|
||||
|
||||
Slide showing program code: see pointers.c
|
||||
|
||||
Slide showing output: see output.txt
|
||||
|
||||
Slide showing same program with different highlights.
|
||||
|
||||
Slide showing same output with different highlights.
|
||||
|
||||
## End
|
@ -1,38 +0,0 @@
|
||||
main() begin
|
||||
XXXX = 111111111
|
||||
XXXX is stored at &XXXX = 0xfffff40750e0
|
||||
YYYY is a pointer to XXXX: YYYY = 0xfffff40750e0
|
||||
* dereferences the pointer: *YYYY = 111111111
|
||||
Array AAAA can be accessed with array notaions:
|
||||
AAAA[0] = 222222222
|
||||
AAAA[1] = 333333333
|
||||
AAAA[2] = 444444444
|
||||
|
||||
Array variable AAAA is a pointer to A[0]: AAAA = 0xfffff40750f8
|
||||
So, dereferencing AAAA should give us A[0]: *AAAA = 222222222
|
||||
|
||||
Adding 1 to an int pointer makes it point to the next int
|
||||
AAAA = 0xfffff40750f8
|
||||
AAAA+1 = 0xfffff40750fc
|
||||
*(AAAA+1) = 333333333
|
||||
|
||||
We can look at contents of a chunk of memory:
|
||||
Peeking at the memory in the neighbourhood of &XXXX, we see:
|
||||
|
||||
Address Contents in Hex Contents in Decimal
|
||||
0xfffff40750fc: 13de4355 = 333333333
|
||||
0xfffff40750f8: d3ed78e = 222222222
|
||||
0xfffff40750f4: ffff = 65535
|
||||
0xfffff40750f0: f40750e0 = -200847136
|
||||
0xfffff40750ec: ffff = 65535
|
||||
0xfffff40750e8: f40750e8 = -200847128
|
||||
0xfffff40750e4: 6 = 6
|
||||
0xfffff40750e0: 69f6bc7 = 111111111
|
||||
0xfffff40750dc: ffff = 65535
|
||||
0xfffff40750d8: a478f4e0 = -1535576864
|
||||
0xfffff40750d4: aaaa = 43690
|
||||
0xfffff40750d0: c46a13e0 = -999681056
|
||||
0xfffff40750cc: ffff = 65535
|
||||
0xfffff40750c8: a478f538 = -1535576776
|
||||
0xfffff40750c4: ffff = 65535
|
||||
main() ends
|
@ -1,43 +0,0 @@
|
||||
/* a small program to demonstrate C++ addresses, pointers and arrays */
|
||||
|
||||
#include <iostream> /* Tait: missing name for import */
|
||||
#include <iomanip> /* Tait: missing name from import */
|
||||
using namespace std;
|
||||
|
||||
int main(){
|
||||
cout << "main() begin\n";
|
||||
|
||||
int XXXX = 111111111;
|
||||
cout << "XXXX = " << XXXX << endl;
|
||||
cout << "XXXX is stored at &XXXX = " << &XXXX << endl;
|
||||
|
||||
int * YYYY = &XXXX;
|
||||
cout << "YYYY is a pointer to XXXX: YYYY = " << YYYY << endl;
|
||||
cout << "* dereferences the pointer: *YYYY = " << *YYYY << endl;
|
||||
|
||||
int AAAA[3] = { 222222222, 333333333, 444444444 };
|
||||
cout << "Array AAAA can be accessed with array notaions: " << endl;
|
||||
cout << " AAAA[0] = " << AAAA[0] << endl;
|
||||
cout << " AAAA[1] = " << AAAA[1] << endl;
|
||||
cout << " AAAA[2] = " << AAAA[2] << endl << endl;
|
||||
|
||||
cout << "Array variable AAAA is a pointer to A[0]: AAAA = " << AAAA << endl;
|
||||
cout << "So, dereferencing AAAA should give us A[0]: *AAAA = " << *AAAA << endl << endl;
|
||||
|
||||
cout << "Adding 1 to an int pointer makes it point to the next int" << endl;
|
||||
cout << "AAAA = " << AAAA << endl;
|
||||
cout << "AAAA+1 = " << (AAAA+1) << endl;
|
||||
cout << "*(AAAA+1) = " << *(AAAA+1) << endl << endl;
|
||||
|
||||
cout << "We can look at contents of a chunk of memory:" << endl;
|
||||
cout << "Peeking at the memory in the neighbourhood of &XXXX, we see: " << endl << endl;
|
||||
cout << "Address Contents in Hex Contents in Decimal " << endl;
|
||||
int * p = (&XXXX)+7;
|
||||
|
||||
for (int i = 0; i < 15; i++) {
|
||||
cout << p << ": " << setw(8) << hex << *p << " = " << setw(11) << dec << *p << endl;
|
||||
p -= 1;
|
||||
}
|
||||
|
||||
cout << "main() ends" << endl;
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
---
|
||||
layout: simple
|
||||
math: true
|
||||
---
|
||||
|
||||
# Vector Implementation Basics
|
||||
|
||||
* CMPT 225
|
||||
* Fall 2021
|
||||
* Lecture 4
|
||||
|
||||
|
||||
## Example Using a Simple "Vector" Class
|
||||
|
||||
Take a look at the [simple_vector.cpp](./simple_vector.cpp) file.
|
||||
|
||||
Name|Type|Value
|
||||
---|---|---
|
||||
<span id="y1">y</span>|float|(empty)
|
||||
<span id="x1">x</span>|int|5
|
||||
...|...|...
|
||||
p|int \*|[address](#x1)
|
||||
g|int \*|[p+1](#y1)
|
||||
|
||||
What is \*g?
|
||||
|
||||
## Implementation in *IVector.h*
|
||||
|
||||
See [IVector.h](./IVector.h)
|
||||
|
||||
## Templates
|
||||
|
||||
* Often, we have algorithms that will work on many data types, with few or no changes.
|
||||
* In *strongly typed* languages, we need a way to produce "generic" code--code that can work on different types in different places.
|
||||
* In C++, *templates* let us write generic code.
|
||||
* A template function or class defineition has a *placeholder* for one or more data types that is instanciated at compile time.
|
||||
* The instanciation may be different at different places in the same code.
|
||||
|
||||
## Test Program
|
||||
|
||||
See [test_program.cpp](./test_program.cpp)
|
||||
|
||||
See [simple_vector2.cpp](./simple_vector2.cpp)
|
||||
|
||||
## TVector is a templated version of IVector
|
||||
|
||||
See [TVector.h](./TVector.h)
|
||||
|
||||
See [Vector.h](./Vector.h)
|
||||
|
||||
See [TestVector.cpp](./TestVector.cpp)
|
Binary file not shown.
@ -1,84 +0,0 @@
|
||||
/*Transcriber's note: these first two lines of ifndef and define are added to make compilation work.*/
|
||||
#ifndef _H_IVECTOR
|
||||
#define _H_IVECTOR
|
||||
#include <iostream>
|
||||
|
||||
class IVector
|
||||
{
|
||||
public:
|
||||
// Constructor
|
||||
IVector(int initSize=0)
|
||||
: theSize{initSize}, theCapacity{initSize+10}
|
||||
{
|
||||
objects = new int(theCapacity);
|
||||
}
|
||||
|
||||
// Destructor
|
||||
~IVector()
|
||||
{delete [] objects;}
|
||||
|
||||
// Check for emptyness
|
||||
bool empty() const {return size() == 0;}
|
||||
|
||||
// Return size of list
|
||||
int size() const {return theSize;}
|
||||
|
||||
// Access the element at a given index
|
||||
// This is the non-const version, so you can change the element.
|
||||
int& operator[](int index)
|
||||
{
|
||||
return objects[index];
|
||||
}
|
||||
|
||||
// Access the element at a given index
|
||||
// This is the const version, for accessing the value only
|
||||
const int& operator[](int index) const
|
||||
{
|
||||
return objects[index];
|
||||
}
|
||||
|
||||
// Increase the capacity (i.e., array size)
|
||||
void reserve(int newCapacity)
|
||||
{
|
||||
if(newCapacity>theSize){
|
||||
int *newArray = new int[newCapacity];
|
||||
for (int k=0;k<theSize;++k){
|
||||
newArray[k] = std::move(objects[k]);
|
||||
}
|
||||
theCapacity = newCapacity;
|
||||
std::swap(objects, newArray);
|
||||
delete [] newArray;
|
||||
}
|
||||
}
|
||||
|
||||
// add a new element to end of the list
|
||||
void push_back(const int& x)
|
||||
{
|
||||
if(theSize==theCapacity) reserve(2*theCapacity+1);
|
||||
objects[theSize++]=x;
|
||||
}
|
||||
|
||||
// remove the last element from the list
|
||||
void pop_back()
|
||||
{
|
||||
--theSize;
|
||||
}
|
||||
|
||||
// Print out the size and contents of the list
|
||||
void display() const
|
||||
{
|
||||
std::cout << "size=" << theSize << std::endl;
|
||||
|
||||
for(int i=0;i<theSize;++i){
|
||||
std::cout<<"["<<i<<"]"<<"="<<objects[i]<<std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
int theSize;
|
||||
int theCapacity;
|
||||
int* objects; // The array is of type int.
|
||||
// In C, C++ a variable of type int array is just a pointer to an int.
|
||||
};
|
||||
|
||||
#endif
|
@ -1,87 +0,0 @@
|
||||
/*
|
||||
Transcriber's note: these first two lines of ifndef and define are added to make compilation work.
|
||||
Note 2: all changed lines are labled with "//CHANGE" (without the quotes)
|
||||
*/
|
||||
#ifndef _H_TVECTOR
|
||||
#define _H_TVECTOR
|
||||
#include <iostream>
|
||||
|
||||
template <typename Object>//CHANGE
|
||||
class TVector
|
||||
{
|
||||
public:
|
||||
// Constructor
|
||||
TVector(int initSize=0)
|
||||
: theSize{initSize}, theCapacity{initSize+10}
|
||||
{
|
||||
objects = new Object(theCapacity);//CHANGE: annotation: in IVector object(...) was int(...)
|
||||
}
|
||||
|
||||
// Destructor
|
||||
~TVector()
|
||||
{delete[] objects;}
|
||||
|
||||
// Check for emptyness
|
||||
bool empty() const {return size() == 0;}
|
||||
|
||||
// Return size of list
|
||||
int size() const {return theSize;}
|
||||
|
||||
// Access the element at a given index
|
||||
// This is the non-const version, so you can change the element.
|
||||
Object& operator[](int index)//CHANGE
|
||||
{
|
||||
return objects[index];
|
||||
}
|
||||
|
||||
// Access the element at a given index
|
||||
// This is the const version, for accessing the value only
|
||||
const Object& operator[](int index) const //CHANGE
|
||||
{
|
||||
return objects[index];
|
||||
}
|
||||
|
||||
// Increase the capacity (i.e., array size)
|
||||
void reserve(int newCapacity)
|
||||
{
|
||||
if(newCapacity>theSize){
|
||||
Object *newArray = new int[newCapacity]; //CHANGE
|
||||
for (int k=0;k<theSize;++k){
|
||||
newArray[k] = std::move(objects[k]);
|
||||
}
|
||||
theCapacity = newCapacity;
|
||||
std::swap(objects, newArray);
|
||||
delete [] newArray;
|
||||
}
|
||||
}
|
||||
|
||||
// add a new element to end of the list
|
||||
void push_back(const Object& x)//CHANGE
|
||||
{
|
||||
if(theSize==theCapacity) reserve(2*theCapacity+1);
|
||||
objects[theSize++]=x;
|
||||
}
|
||||
|
||||
// remove the last element from the list
|
||||
void pop_back()
|
||||
{
|
||||
--theSize;
|
||||
}
|
||||
|
||||
// Print out the size and contents of the list
|
||||
void display() const
|
||||
{
|
||||
std::cout << "size=" << theSize << std::endl;
|
||||
|
||||
for(int i=0;i<theSize;++i){
|
||||
std::cout<<"["<<i<<"]"<<"="<<objects[i]<<std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
int theSize;
|
||||
int theCapacity;
|
||||
Object* objects;//CHANGE
|
||||
};
|
||||
|
||||
#endif
|
@ -1,48 +0,0 @@
|
||||
#include "Vector.h"
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
using namespace std;
|
||||
|
||||
void print(const Vector<Vector<int>> arr)
|
||||
{
|
||||
int N=arr.size();
|
||||
for(int i=0;i<N;++i)
|
||||
{
|
||||
cout<<"arr["<<i<<"]:";
|
||||
for(int j=0;j<arr[i].size();++j)
|
||||
cout<<" "<<arr[i][j];
|
||||
|
||||
cout<<endl;
|
||||
}
|
||||
}
|
||||
|
||||
class CompareVector
|
||||
{
|
||||
public:
|
||||
bool operator()(const Vector<int>& lhs, const Vector<int>& rhs)const
|
||||
{return lhs.size()<rhs.size();}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
const int N=20;
|
||||
Vector<Vector<int>> arr(N);
|
||||
Vector<int> v;
|
||||
|
||||
for(int i=N-1;i>0;--i)
|
||||
{
|
||||
v.push_back(i);
|
||||
arr[i]=v;
|
||||
}
|
||||
|
||||
print(arr);
|
||||
|
||||
clock_t start=clock();
|
||||
std::sort(begin(arr),end(arr),CompareVector{});
|
||||
clock_t end=clock();
|
||||
cout<<"Sorting time: "<<(end-start)<<endl;
|
||||
|
||||
print(arr);
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,119 +0,0 @@
|
||||
// transcriber's note: include is added from slide because otherwise it will not compile
|
||||
#include <utility>
|
||||
#include <stdexcept>
|
||||
|
||||
template <typename Object>
|
||||
class Vector
|
||||
{
|
||||
public:
|
||||
explicit Vector(int initSize=0)
|
||||
: theSize{initSize}, theCapacity{initSize + SPARE_CAPACITY}
|
||||
{objects = new Object[theCapacity];}
|
||||
|
||||
Vector(const Vector& rhs)
|
||||
: theSize{rhs.theSize}, theCapacity{rhs.theCapacity}, objects{nullptr}
|
||||
{
|
||||
objects = new Object[theCapacity];
|
||||
for(int k=0;k<theSize;++k){
|
||||
objects[k] = rhs.objects[k];
|
||||
}
|
||||
}
|
||||
|
||||
Vector& operator=(const Vector& rhs)
|
||||
{
|
||||
Vector copy = rhs;
|
||||
std::swap(*this,copy);
|
||||
return *this;
|
||||
}
|
||||
|
||||
~Vector()
|
||||
{delete[] objects;}
|
||||
|
||||
Vector(Vector&& rhs)
|
||||
: theSize{rhs.theSize}, theCapacity{rhs.theCapacity}, objects{rhs.objects}
|
||||
{
|
||||
rhs.objects=nullptr;
|
||||
rhs.theSize=0;
|
||||
rhs.theCapacity=0;
|
||||
}
|
||||
|
||||
Vector& operator=(Vector&& rhs)
|
||||
{
|
||||
std::swap(theSize,rhs.theSize);
|
||||
std::swap(theCapacity,rhs.theCapacity);
|
||||
std::swap(objects,rhs.objects);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//stacky stuff
|
||||
void push_back(Object x)
|
||||
{
|
||||
if(theSize==theCapacity)
|
||||
reserve(2*theCapacity+1);
|
||||
objects[theSize++]=std::move(x);
|
||||
}
|
||||
|
||||
void pop_back()
|
||||
{
|
||||
if(empty())
|
||||
// transcriber's note: the original line here was the following, however, it was changed to compile
|
||||
// throw UnderflowException();
|
||||
throw std::underflow_error::underflow_error;
|
||||
--theSize;
|
||||
}
|
||||
|
||||
const Object& back() const
|
||||
{
|
||||
if(empty())
|
||||
// See note on line 58
|
||||
throw std::underflow_error::underflow_error;
|
||||
return objects[theSize-1];
|
||||
}
|
||||
|
||||
// transcriber's note: these three functions added to make compilation work
|
||||
const int size() const
|
||||
{
|
||||
return theSize;
|
||||
}
|
||||
Object& operator[](int index)
|
||||
{
|
||||
return objects[index];
|
||||
}
|
||||
const Object& operator[](int index) const
|
||||
{
|
||||
return objects[index];
|
||||
}
|
||||
bool empty() const {return size() == 0;}
|
||||
void reserve(int newCapacity)
|
||||
{
|
||||
if(newCapacity>theSize){
|
||||
Object *newArray = new int[newCapacity]; //CHANGE
|
||||
for (int k=0;k<theSize;++k){
|
||||
newArray[k] = std::move(objects[k]);
|
||||
}
|
||||
theCapacity = newCapacity;
|
||||
std::swap(objects, newArray);
|
||||
delete [] newArray;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
typedef Object* iterator;
|
||||
typedef const Object* const_iterator;
|
||||
|
||||
iterator begin()
|
||||
{return &objects[0];}
|
||||
const_iterator begin() const
|
||||
{return &objects[0];}
|
||||
iterator end()
|
||||
{return &objects[size()];}
|
||||
const_iterator end() const
|
||||
{return &objects[size()];}
|
||||
|
||||
static const int SPARE_CAPACITY=2;
|
||||
|
||||
private:
|
||||
int theSize;
|
||||
int theCapacity;
|
||||
Object* objects;
|
||||
};
|
@ -1,22 +0,0 @@
|
||||
#include "IVector.h"
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
const int N = 20;
|
||||
|
||||
IVector v; // make an int vector
|
||||
v.display(); // prints its contents
|
||||
|
||||
// Stores N ints in the Vector
|
||||
for (int i=0; i<N; ++i)
|
||||
{
|
||||
v.push_back(i);
|
||||
}
|
||||
|
||||
// print the contents
|
||||
v.display();
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
#include "TVector.h"
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
const int N = 20;
|
||||
|
||||
TVector<int> v; // make an int vector
|
||||
v.display(); // prints its contents
|
||||
|
||||
// Stores N ints in the Vector
|
||||
for (int i=0; i<N; ++i)
|
||||
{
|
||||
v.push_back(i);
|
||||
}
|
||||
|
||||
// print the contents
|
||||
v.display();
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,46 +0,0 @@
|
||||
//
|
||||
// Test Program for Basic Stack Class
|
||||
//
|
||||
#include <iostream> // for I/O facilities
|
||||
using namespace std;
|
||||
#include "MinimalStack.h" // basic_stackj declaration
|
||||
|
||||
int main(int argc, char* const argv[]){
|
||||
cout << "\n\nMinimalStack Template Class Test Proceedure - START\n\n";
|
||||
|
||||
// Make some stacks, and verify that empty() says they are empty.
|
||||
MinimalStack<int> s1;
|
||||
MinimalStack<float> s2;
|
||||
|
||||
cout<<"s1.isEmpty() = "<<s1.isEmpty()<<"\n";
|
||||
cout<<"s2.isEmpty() = "<<s2.isEmpty()<<"\n";
|
||||
|
||||
// Put some things on them
|
||||
cout<<"s1.push("<<1<<")\n";
|
||||
s1.push(1);
|
||||
cout<<"s1.push("<<2<<")\n";
|
||||
s1.push(2);
|
||||
cout<<"s2.push("<<1.5<<")\n";
|
||||
s2.push(1.5);
|
||||
cout<<"s2.push("<<2.5<<")\n";
|
||||
s2.push(2.5);
|
||||
|
||||
// Verify that isEmpty() reports that they are empty
|
||||
// and that the right things are on top
|
||||
cout<<"s1.isEmpty()="<<s1.isEmpty()<<"\n";
|
||||
cout<<"s1.top()="<<s1.top()<<"\n";
|
||||
cout<<"s2.isEmpty()="<<s2.isEmpty()<<"\n";
|
||||
cout<<"s2.top()="<<s2.top()<<"\n";
|
||||
|
||||
// Empty them and verify that isEmpty() again reports that they are empty.
|
||||
while(!s1.isEmpty()){
|
||||
cout<<"s1.pop()="<<s1.pop()<<"\n";
|
||||
}
|
||||
cout<<"s1.isEmpty()="<<s1.isEmpty()<<"\n";
|
||||
while(!s2.isEmpty()){
|
||||
cout<<"s2.pop()="<<s2.pop()<<"\n";
|
||||
}
|
||||
// transcriber's note: the following lines are not contained on the slide, but I am assuming they are supposed to be there.
|
||||
cout<<"s2.isEmpty()="<<s2.isEmpty()<<"\n";
|
||||
return 0;
|
||||
}
|
@ -1,160 +0,0 @@
|
||||
---
|
||||
layout: simple
|
||||
math: true
|
||||
---
|
||||
|
||||
# Dynamic Data Structures - Linked Lists
|
||||
|
||||
Transcriber's note:
|
||||
Each row in the Value\|Pointer/Link tables represents a node.
|
||||
Despite the fact that the link/pointer takes you to the "value" column, in reality it is taking you to the node "row", it's not just a pointer to the value.
|
||||
|
||||
## Dynamic Data Structures
|
||||
|
||||
* Basic types (e.g. int, char, bool, ...), and arrays of these store a *fixed* amount of data.
|
||||
* We want implementations of ADTs like stacks + queues to *grow & shrink* (their memory use) *as needed*.
|
||||
* e.g. like Vector, Array-something? (can't read), String classes
|
||||
|
||||
Basic Idea:
|
||||
|
||||
Store data in a collection of (simple) objects.
|
||||
add/delete these as needed; link them all together to make the main object.
|
||||
|
||||
## Linked Lists
|
||||
|
||||
- A sequence of simple objects (nodes): each storing one datum (plus a link...) linked together in a chain
|
||||
- E.g., to store the list <3, 5, 7>:
|
||||
|
||||
Datum|Link
|
||||
---|---
|
||||
<span id="z1">3</span>|[link](#z2)
|
||||
<span id="z2">5</span>|[link](#z3)
|
||||
<span id="z3">7</span>|link to nowhere
|
||||
|
||||
- These objects have no names, (in contrast to declared values)
|
||||
- we access them by following links
|
||||
- in Java, references (implemented as pointers)
|
||||
- in C++, pointers
|
||||
|
||||
Need one named place to start like so:
|
||||
|
||||
A normal variable of type "pointer to a node": [First](#y1)
|
||||
|
||||
Data|Link
|
||||
---|---
|
||||
<span id="y1">3</span>|[pointer](#y2)
|
||||
<span id="y2">5</span>|[pointer](#y3)
|
||||
<span id="y3">7</span>|null pointer
|
||||
|
||||
## Implementing a Stack with a Linked List (By example)
|
||||
|
||||
Code to run, followed by the current stack.
|
||||
|
||||
### <code>stack s;</code>
|
||||
|
||||
<label for="tof">top or front</label>
|
||||
<span id="tof">node</span>
|
||||
|
||||
### <code>s.push(3)</code>
|
||||
|
||||
<a href="#x1">front</a>
|
||||
|
||||
Data|Pointer
|
||||
---|---
|
||||
<span id="x1">3</span>|null pointer
|
||||
|
||||
### etc...
|
||||
|
||||
...
|
||||
|
||||
### <code>s.push(5)</code>
|
||||
|
||||
[front](#w1)
|
||||
|
||||
Data|Pointer
|
||||
---|---
|
||||
<span id="w1">5</span>|[pointer](#w2)
|
||||
<span id="w2">8</span>|[pointer](#w3)
|
||||
<span id="w3">...</span>|... ([pointer](#w4))
|
||||
<span id="w4">3</span>|null pointer
|
||||
|
||||
### <code>s.push(7)</code>
|
||||
|
||||
[front](#v1)
|
||||
|
||||
Value|Pointer
|
||||
<span id="v1">7</span>|[pointer](#v2)
|
||||
<span id="v2">5</span>|[pointer](#v3)
|
||||
<span id="v3">8</span>|[pointer](#v4)
|
||||
<span id="v4">...</span>|...
|
||||
|
||||
To perform the push(7):
|
||||
|
||||
1. Make a new node to store the 7
|
||||
2. modify links to insert it correctly
|
||||
|
||||
Original:
|
||||
|
||||
[front](#u1)
|
||||
|
||||
Data|Pointer
|
||||
---|---
|
||||
<span id="u1">5</span>|[pointer](#u2)
|
||||
<span id="u2">8</span>|...
|
||||
|
||||
After operation:
|
||||
|
||||
[front](#t1) now points at node with value 7; node with value 7's pointer now points to the [old front](#u1)
|
||||
|
||||
Value|Pointer
|
||||
---|---
|
||||
<span id="t1">7</span>|[pointer](#t2)
|
||||
<span id="t2">5</span>|[pointer](#t3)
|
||||
<span id="t3">8</span>|...
|
||||
|
||||
### <code>s.pop()</code>
|
||||
|
||||
[front](#s1)
|
||||
|
||||
Value|Pointer
|
||||
---|---
|
||||
<span id="s1">5</span>|[pointer](#s2)
|
||||
<span id="s2">8</span>|...
|
||||
|
||||
How to perform the pop():
|
||||
1. Change the "top" link
|
||||
2. Return the old top node
|
||||
|
||||
Linked list after running operation (note that two links go to the same node):
|
||||
|
||||
[top](#r0) now points to second row
|
||||
|
||||
Value|Pointer
|
||||
---|---
|
||||
<span id="r1">7</span> (return this value)|[pointer](#r0)
|
||||
<span id="r0">5</span>|[pointer](#r2)
|
||||
<span id="r2">8</span>|...
|
||||
|
||||
* Caveat 1: don't lose the old top value
|
||||
* Caveat 2: don't ignore the old top node (it still consumes space)
|
||||
|
||||
### "Improved" pop():
|
||||
|
||||
1. Store the old top value in "temp"
|
||||
2. make *top* link to the new top node
|
||||
3. *free* the space for the old top node
|
||||
3. return temp
|
||||
|
||||
## The List Class (A doubly-linked list implementation of a list)
|
||||
|
||||
See <a href="./list.cpp">list.cpp</a>
|
||||
|
||||
<...5,6,7,...> in a double linked list:
|
||||
|
||||
Prev|Value|Next
|
||||
---|---|---
|
||||
...|<span id="d0">5</span>|[next](#d1)
|
||||
[prev](#d0)|<span id="d1">6</span>|[next](#d2)
|
||||
[prev](#d1)|<span id="d2">7</span>|...
|
||||
|
||||
## End
|
Binary file not shown.
@ -1,22 +0,0 @@
|
||||
#include <utility> // not in original, needed for compilation
|
||||
|
||||
template <typename Object>
|
||||
class List
|
||||
{
|
||||
private:
|
||||
// the basic doubly linked list node
|
||||
// Nested inside a list, can be public
|
||||
// because the node itself is private
|
||||
struct Node
|
||||
{
|
||||
Object data; // (annotation: list element)
|
||||
Node *prev; // (annotation: pointer to next node)
|
||||
Node *next; // (annotation: pointer to previous node)
|
||||
|
||||
Node(const Object& d = Object{}, Node* p = nullptr, Node* n = nullptr)
|
||||
: data{d}, prev{p}, next{n} {}
|
||||
|
||||
Node(Object&& d, Node* p = nullptr, Node* n = nullptr)
|
||||
: data{std::move(d)}, prev{p}, next{n} {}
|
||||
};
|
||||
}; // not in original, needed for compilation
|
@ -1,393 +0,0 @@
|
||||
---
|
||||
layout: simple
|
||||
math: true
|
||||
---
|
||||
|
||||
# CMPT 225--Call Stack & Heap Memory
|
||||
|
||||
## The call stack
|
||||
|
||||
* Suppose a function `A` calls a function `B`, which calls `C`.
|
||||
* During execution control passes from (the code for) `A`, to `B`, then to `C`.
|
||||
* The execution of `C` ends, control must return to `B` and then to `A`.
|
||||
|
||||
{% katex display %}
|
||||
... \leftrightarrow A \leftrightarrow B \leftrightarrow C \leftrightarrow ...
|
||||
{% endkatex %}
|
||||
|
||||
* At each function call, the system records where control should return to be *pushing an activation record on the call stack*
|
||||
* The call stack also records all local variables, including the arguments to the function call.
|
||||
|
||||
## Call Stack Illustration
|
||||
|
||||
Code is in [call_stack.cpp](./call_stack.cpp)
|
||||
|
||||
Call stack for this process:
|
||||
|
||||
Name|Data
|
||||
---|---
|
||||
...|...
|
||||
main|a=1, b=0
|
||||
f(2)|c=2, d=3, e=8
|
||||
g(4)|i=4
|
||||
...|...
|
||||
g|<code for g>
|
||||
f|<code for f>
|
||||
main|<code for main>
|
||||
|
||||
## Stack Code
|
||||
|
||||
Picture of code, which can be found in [stack_pointers.cpp](./stack_pointers.cpp)
|
||||
|
||||
Picture of code output, which can be found in [stack_pointers_output.txt](stack_pointers_output.txt)
|
||||
|
||||
## Dynamic Memory *or* Heap
|
||||
|
||||
* Vairables declared in functions are stored on the *call stack*
|
||||
* These variables:
|
||||
* are of fixed size
|
||||
* are destoryed when the function they are defined in terminates
|
||||
* We often want a function `f` to create data that can be used after it returns.
|
||||
* In particular, dynamic data structures require this!
|
||||
* This data is stored in "the heap", a region of memory that is allocated dynamically as needed!
|
||||
|
||||
## In C++:
|
||||
|
||||
* Basic (or primitive) types can be stored on the call stack *or* on the heap.
|
||||
* Objects (e.g. instances of classes) can be stored on the call stack *or* on the heap.
|
||||
* Variables declared in functions are on the stack
|
||||
* Allocation on the heap is denoted by "new".
|
||||
|
||||
## Ex: Basic Types on Call Stack & Heap
|
||||
|
||||
Code snippet below:
|
||||
|
||||
```
|
||||
f(){
|
||||
int n; //n is on stack
|
||||
n=6;
|
||||
int * np;//np is on stack
|
||||
np = new int;// new int is stored in heap
|
||||
*np = 7; // np points to the location.
|
||||
}
|
||||
```
|
||||
|
||||
## Ex: Basic Types on Call Stack & Heap
|
||||
|
||||
See code above.
|
||||
|
||||
Call stack:
|
||||
|
||||
Name|Value|Note
|
||||
---|---|---
|
||||
n|6|
|
||||
np|[pointer](#h1)|`np` is a pointer to the location on the heap.
|
||||
|
||||
Heap:
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Value</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>...</td>
|
||||
</tr>
|
||||
<td><span id="h1">7</span></td>
|
||||
<tr>
|
||||
<td>...</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
Note: When `f` ends, `np` is gone (the stack is popped), but the space it pointed to *is not*.
|
||||
|
||||
## Class Instances on Heap & Stack (combines notes on two slides)
|
||||
|
||||
Code snippet:
|
||||
|
||||
```c++
|
||||
List * f(){
|
||||
List L;
|
||||
List * Lp;
|
||||
Lp = new List();
|
||||
return Lp; // returns pointer
|
||||
}
|
||||
|
||||
main(){
|
||||
...
|
||||
List * lst = f(); // lst becomes a pointer to the list object
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
Call Stack:
|
||||
|
||||
Name|Values|Notes
|
||||
---|---|---
|
||||
lst|[pointer to heap](#o2)|in main
|
||||
L|<List Object>|entire List object; in function `f` (destroyed when f ends)
|
||||
Lp|[pointer to <List Object>](#o2)|in function `f` (this *pointer* is also destroyed when f exits); annotation: this instanciates the list class
|
||||
|
||||
Heap:
|
||||
|
||||
Value|Notes
|
||||
...|...
|
||||
<span id="o2"><List Object></span>|entire list object
|
||||
...|...
|
||||
|
||||
## Accessing Instance Members in C++ (combination of notes in two slides)
|
||||
|
||||
Suppose a class *Store* with:
|
||||
|
||||
* a data member `x`. (an int)
|
||||
* a function `put(v)` that stores `v` in `x`.
|
||||
* a function `get()` that returns the value of `x`.
|
||||
|
||||
Consider this code fragment:
|
||||
|
||||
```c++
|
||||
f(){
|
||||
...
|
||||
Store s1;
|
||||
s1.put(5);
|
||||
y=s1.get();//y=5
|
||||
...
|
||||
Store *s2;
|
||||
s2=new Store();// (annotation: XX)
|
||||
s2.put(5);// (annotation: X)
|
||||
y=s2.get()// (annotation: X)
|
||||
...
|
||||
*s2.put(5);// (annotation: X)
|
||||
y=*s2.get();// (annotation: X)
|
||||
...
|
||||
(*s2).put(5);// (annotation: check mark)
|
||||
y=(*s2).get();// (annotation: check mark)
|
||||
...
|
||||
s2->put(5); // equiv. to (*s).put(5)// (annotation: check mark)
|
||||
y=s2->get(); // equiv. to y=(*s).get()// (annotation: check mark)
|
||||
}
|
||||
```
|
||||
|
||||
Call Stack:
|
||||
|
||||
Name|Value|Notes
|
||||
---|---|---
|
||||
s2|[pointer to <Store Object>](#pts)|
|
||||
s1|<Store Object [x=5]>|
|
||||
|
||||
Heap:
|
||||
|
||||
Value|Notes
|
||||
---|---
|
||||
<span id="pts"><Store Object [x=5]></span>|
|
||||
|
||||
## Using the Textbook List Class
|
||||
|
||||
See [textbook_list.cpp](./textbook_list.cpp)
|
||||
and [List.h](./List.h).
|
||||
|
||||
Call stack during the run of the program:
|
||||
|
||||
Name|Value|Notes
|
||||
---|---
|
||||
N|5|within main
|
||||
lst|<List Object [size=5, head=0, tail=4]>|within main
|
||||
|
||||
The heap is empty.
|
||||
|
||||
See "doubly linked list" example in lecture 05.
|
||||
|
||||
## The List Class
|
||||
|
||||
Two images of the doubly linked list slides from lecture 05 with a big red X written overtop each image.
|
||||
|
||||
## The List Class - Constructor
|
||||
|
||||
Code snippet:
|
||||
|
||||
```C++
|
||||
private:
|
||||
int theSize;
|
||||
Node *head;
|
||||
Node *tail;
|
||||
void init()
|
||||
{
|
||||
theSize = 0;
|
||||
head = new Node;
|
||||
tail = new Node;
|
||||
head->next = tail;
|
||||
tail->prev = head;
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
After constructor:
|
||||
|
||||
Name|Next|Value|Prev
|
||||
---|---|---|---
|
||||
<span id="t0">head</span>|[pointer](#t1)|nullptr|nullptr
|
||||
<span id="t1">tail</span>|nullptr|nullptr|[pointer](#t0)
|
||||
|
||||
Code snippet form [List.h](./List.h):
|
||||
|
||||
```C++
|
||||
Node(const Object& d = Object{}, Node* p = nullptr, Node* n = nullptr)
|
||||
: data{d}, prev{p}, next{n} {}
|
||||
```
|
||||
|
||||
## The List Class - The iterators
|
||||
|
||||
* Data member (Node\* current)
|
||||
* a pointer to a Node. (the list iterators are implemented with pointers.)
|
||||
* Constructors:
|
||||
* turn a pointer into an iterator:
|
||||
* `iterator(Node\* p): const_iterator{p}{}`
|
||||
* `const_iterator(Node\* p): current{p}`
|
||||
* function:
|
||||
* `iterator end(){ return iterator(tail}`
|
||||
* turns the tail pointer into the iter to "end". (???can't read completely)
|
||||
* it corresponds to "just past the end" of the list
|
||||
|
||||
## The List Class - the push_back function
|
||||
|
||||
```C++
|
||||
// add an element to the tail end of the list
|
||||
// end() is the end iterator
|
||||
// x is the element to add
|
||||
void push_back(const Object& x){insert(end(), x);}
|
||||
|
||||
iterator insert(iterator itr, const Object& x){
|
||||
Node *p = itr.current; // turns the iterator into a pointer
|
||||
++theSize; //increments size variable
|
||||
return iterator(p->prev=p->prev->next=new Node(x, p->prev, p)) // turns the pointer into an iterator
|
||||
// p->prev=p->prev->next=new Node(x, p->prev, p)) does two things:
|
||||
// 1. Makes a new node `N`
|
||||
// 2. stores a pointer to `N` in p->prev and it p->prev->next
|
||||
}
|
||||
```
|
||||
|
||||
## The List Class - Inserting the first element (combination of notes from two slides)
|
||||
|
||||
Code snippet:
|
||||
|
||||
```C++
|
||||
// itr is the end
|
||||
iterator insert(iterator itr, const Object& x){
|
||||
Node *p = itr.current;// itr.current is the tail
|
||||
++theSize;
|
||||
return iterator(p->prev=p->prev->next=new Node(x, p->prev, p)); // turns pointer into iterator
|
||||
// x is new list element
|
||||
// p->prev is initial value of prev
|
||||
// p is initial value of next
|
||||
}
|
||||
```
|
||||
|
||||
List pointed to by [pointer p](#d1) (original)
|
||||
|
||||
Name|Next|Value|Prev
|
||||
---|---|---|---
|
||||
<span id="d0">head</span>|[pointer](#d1)|nullptr|nullptr
|
||||
<span id="d1">tail</span>|nullptr|nullptr|[pointer](#d0)
|
||||
|
||||
The "new Node(...)" object:
|
||||
|
||||
Next|Value|Prev
|
||||
---|---|---
|
||||
[pointer](#d1)|nullptr|[pointer](#d0)
|
||||
|
||||
## Transcriber's addition (implied in diagram): What does `p->prev=p->prev->next=New Node(...)` do to this list?
|
||||
|
||||
Transciber's note: It inserts the `new Node(...)` into the list like so:
|
||||
|
||||
Name|Next|Value|Prev
|
||||
---|---|---|---
|
||||
<span id="l0">head</span>|[pointer](#l2)|nullptr|nullptr
|
||||
<span id="l2">`new Node(...)`</span>|[pointer](#l1)|nullptr|[pointer](#l0)
|
||||
<span id="l1">tail</span>|nullptr|nullptr|[pointer](#l2)
|
||||
|
||||
Transciber's note: This cancels the previous connection between `head` and `tail` directly.
|
||||
|
||||
## Using the Textbook List Class
|
||||
|
||||
Code snippet:
|
||||
|
||||
```C++
|
||||
#include "dsexceptions.h"
|
||||
#include "List.h"
|
||||
int main(){
|
||||
const int N = 5;
|
||||
List<int> = lst;
|
||||
for(int i=N-1; i<0; --i){
|
||||
lst.push_front(i);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
When lst contains the two values [1, 2]:
|
||||
|
||||
Call Stack:
|
||||
|
||||
Name|Value|Notes
|
||||
---|---|---
|
||||
N|5|
|
||||
lst|<List Object [theSize=2, head=[pointer](#g3v), tail=[pointer](#g1v)>|
|
||||
|
||||
Heap (transcriber's note: the link takes you to the value, but the pointer is to the group of values [next, value, prev), A.K.A. a Node):
|
||||
|
||||
Value|Notes
|
||||
[Node.next](#g2v)|Node index 0
|
||||
<span id="g0v">Node Value: 1</span>|Node index 0
|
||||
[Node.prev](#g3v)|Node index 0
|
||||
...|...
|
||||
Node.next (nullptr)|Ending Node
|
||||
<span id="g1v">Node Value: ?</span>|Ending Node
|
||||
[Node.prev](#g2v)|Ending Node
|
||||
...|...
|
||||
[Node.next](#g1v)|Node index 1
|
||||
<span id="g2v">Node Value: 2</span>|Node index 1
|
||||
[Node.prev](#g0v)|Node index 1
|
||||
...|...
|
||||
[Node.next](#g0v)|Beginning Node
|
||||
<span id="g3v">Node Value: ?</span>|Beginning Node
|
||||
Node.prev (nullptr)|Beginning Node
|
||||
|
||||
## Linked List Ends
|
||||
|
||||
Transcriber's note: tell me if you like this way of transcribing simplified linked lists where the individual values don't matter, but only a linear relationship between the nodes:
|
||||
|
||||
For [4, 5, 6]:
|
||||
|
||||
{% katex display %}
|
||||
\text{head} \leftrightarrow \text{beginning node} \leftrightarrow 4 \leftrightarrow 5 \leftrightarrow 6 \leftrightarrow \text{ending node} \leftrightarrow \text{tail}
|
||||
{% endkatex %}
|
||||
|
||||
versus
|
||||
|
||||
{% katex display %}
|
||||
\text{head} \leftrightarrow 4 \leftrightarrow 5 \leftrightarrow 6 \leftrightarrow \text{tail}
|
||||
{% endkatex %}
|
||||
|
||||
For [5]:
|
||||
|
||||
{% katex display %}
|
||||
\text{head} \leftrightarrow \text{beginning node} \leftrightarrow 5 \leftrightarrow \text{ending node} \leftrightarrow \text{tail}
|
||||
{% endkatex %}
|
||||
|
||||
versus
|
||||
|
||||
$$\text{head} \leftrightarrow 5 \leftrightarrow \text{tail}$$
|
||||
|
||||
For []:
|
||||
|
||||
$$\text{head} \leftrightarrow \text{beginning node} \leftrightarrow \text{ending node} \leftrightarrow \text{tail}$$
|
||||
|
||||
versus (transcriber's note: the lack of connection is intentional)
|
||||
|
||||
$$\text{head} , \text{tail}$$
|
||||
|
||||
## End
|
||||
|
||||
After the "End" slide, some previous slides are repeated for no apparent reason.
|
Binary file not shown.
@ -1,22 +0,0 @@
|
||||
#include <utility> // not in original, needed for compilation
|
||||
|
||||
template <typename Object>
|
||||
class List
|
||||
{
|
||||
private:
|
||||
// the basic doubly linked list node
|
||||
// Nested inside a list, can be public
|
||||
// because the node itself is private
|
||||
struct Node
|
||||
{
|
||||
Object data; // (annotation: list element)
|
||||
Node *prev; // (annotation: pointer to next node)
|
||||
Node *next; // (annotation: pointer to previous node)
|
||||
|
||||
Node(const Object& d = Object{}, Node* p = nullptr, Node* n = nullptr)
|
||||
: data{d}, prev{p}, next{n} {}
|
||||
|
||||
Node(Object&& d, Node* p = nullptr, Node* n = nullptr)
|
||||
: data{std::move(d)}, prev{p}, next{n} {}
|
||||
};
|
||||
}; // not in original, needed for compilation
|
@ -1,19 +0,0 @@
|
||||
/*
|
||||
Transcriber's note: In the slide, the order of the functions is: main, f, g
|
||||
But I have reordered them g, f, main to allow compilation.
|
||||
*/
|
||||
int g(int i){
|
||||
return 2*i;
|
||||
} // return control to f
|
||||
|
||||
int f(int c){
|
||||
int d=3;
|
||||
int e=g(4); // go to g
|
||||
return e;
|
||||
} // return control to main
|
||||
|
||||
int main(){
|
||||
int a=1;
|
||||
int b=f(2); // go to function f
|
||||
return 0;
|
||||
} // return from program
|
@ -1,38 +0,0 @@
|
||||
/* A program to demonstrate printing out partial contents of the call stack */
|
||||
|
||||
#include <iostream> /* Note: only "#include" shown in image */
|
||||
#include <iomanip> /* Note: only "#include" shwon in image */
|
||||
|
||||
using namespace std;
|
||||
|
||||
int print_stack(int k, int j){
|
||||
cout << "print_stack() begins" << endl;
|
||||
cout << "argument k is at &k=" << &k << " and k=" << k << endl;
|
||||
cout << "argument j is at &j=" << &j << " and j=" << j << endl;
|
||||
|
||||
int CCC[2] = {77777777, 88888888};
|
||||
cout << "Peeking from &j up, for the space of k ints" << endl;
|
||||
int *p = (&j)+k;
|
||||
for (int l=k; l>0; l--){
|
||||
cout << p << ": " << setw(8) << hex << *p << " = " << setw(11) << dec << *p << endl;
|
||||
p-=j;// subtracts j from an int pointer sets it to the j-th previous int
|
||||
}
|
||||
cout << "End of: print_stack()" << endl;
|
||||
}
|
||||
|
||||
int ffff(int fun_arg){
|
||||
cout << "fun() begins" << endl;
|
||||
cout << "fun_arg is at &fun_arg=" << &fun_arg << endl;
|
||||
int BBB[2] = {44444444,55555555};
|
||||
cout << "BBB is at BBB=" << BBB << endl;
|
||||
print_stack(40, +1);
|
||||
cout << "fun ends" << endl;
|
||||
}
|
||||
|
||||
int main(){
|
||||
cout << "main() begins" << endl;
|
||||
int XXXX = 99999999;
|
||||
int AAAA[2] = {11111111,22222222};
|
||||
ffff(33333333);
|
||||
cout << "main() ends" << endl;
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
main() begins
|
||||
fun() begins
|
||||
fun_arg is at &fun_arg=0xffffe9fe9e5c
|
||||
BBB is at BBB=0xffffe9fe9e60
|
||||
print_stack() begins
|
||||
argument k is at &k=0xffffe9fe9e1c and k=40
|
||||
argument j is at &j=0xffffe9fe9e18 and j=1
|
||||
Peeking from &j up, for the space of k ints
|
||||
0xffffe9fe9eb8: 0 = 0
|
||||
0xffffe9fe9eb4: 0 = 0
|
||||
0xffffe9fe9eb0: 0 = 0
|
||||
0xffffe9fe9eac: aaaa = 43690
|
||||
0xffffe9fe9ea8: b3e70b38 = -1276703944
|
||||
0xffffe9fe9ea4: 0 = 0
|
||||
0xffffe9fe9ea0: 0 = 0
|
||||
0xffffe9fe9e9c: 195a3d0f = 425344271
|
||||
0xffffe9fe9e98: 2b7fe700 = 729802496
|
||||
0xffffe9fe9e94: 153158e = 22222222
|
||||
0xffffe9fe9e90: a98ac7 = 11111111
|
||||
0xffffe9fe9e8c: 5f5e0ff = 99999999
|
||||
0xffffe9fe9e88: aba454fc = -1415293700
|
||||
0xffffe9fe9e84: ffff = 65535
|
||||
0xffffe9fe9e80: e9fe9ea0 = -369189216
|
||||
0xffffe9fe9e7c: ffff = 65535
|
||||
0xffffe9fe9e78: aba45538 = -1415293640
|
||||
0xffffe9fe9e74: ffff = 65535
|
||||
0xffffe9fe9e70: e9fe9ea0 = -369189216
|
||||
0xffffe9fe9e6c: 195a3d0f = 425344271
|
||||
0xffffe9fe9e68: 2b7fe700 = 729802496
|
||||
0xffffe9fe9e64: 34fb5e3 = 55555555
|
||||
0xffffe9fe9e60: 2a62b1c = 44444444
|
||||
0xffffe9fe9e5c: 1fca055 = 33333333
|
||||
0xffffe9fe9e58: b3e71074 = -1276702604
|
||||
0xffffe9fe9e54: ffff = 65535
|
||||
0xffffe9fe9e50: e9fe9e70 = -369189264
|
||||
0xffffe9fe9e4c: aaaa = 43690
|
||||
0xffffe9fe9e48: b3e710a4 = -1276702556
|
||||
0xffffe9fe9e44: ffff = 65535
|
||||
0xffffe9fe9e40: e9fe9e70 = -369189264
|
||||
0xffffe9fe9e3c: 195a3d0f = 425344271
|
||||
0xffffe9fe9e38: 2b7fe700 = 729802496
|
||||
0xffffe9fe9e34: 54c5638 = 88888888
|
||||
0xffffe9fe9e30: 4a2cb71 = 77777777
|
||||
0xffffe9fe9e2c: ffff = 65535
|
||||
0xffffe9fe9e28: e9fe9e28 = -369189336
|
||||
0xffffe9fe9e24: 3 = 3
|
||||
0xffffe9fe9e20: e9fe9e40 = -369189312
|
||||
0xffffe9fe9e1c: 28 = 40
|
||||
End of: print_stack()
|
||||
fun ends
|
||||
main() ends
|
@ -1,15 +0,0 @@
|
||||
#include "dsexception.h" // transcriber's note: I have no idea where this file is or what it does???
|
||||
#include "List.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
const int N = 5;
|
||||
List<int> lst;
|
||||
for (int i=N-1; i>0; --i)
|
||||
{
|
||||
lst.push_forward(i);
|
||||
}
|
||||
return 0;
|
||||
}
|
@ -1,267 +0,0 @@
|
||||
---
|
||||
layout: simple
|
||||
math: true
|
||||
---
|
||||
|
||||
# L.L. Queues & L.L. Traversal
|
||||
|
||||
## Basic L.L. Queue
|
||||
|
||||
* [front](#frontele1)
|
||||
* [back](#backele1)
|
||||
|
||||
Value|Next
|
||||
---|---
|
||||
<span id="frontele1">a</span>|[pointer](#ele11)
|
||||
<span id="ele11">b</span>|[pointer](#ele12)
|
||||
<span id="ele12">...</span>|...
|
||||
<span id="ele13">g</span>|[pointer](#backele1)
|
||||
<span id="backele1">h</span>|nullptr
|
||||
|
||||
as a stack, this L.L. would be:
|
||||
|
||||
$$a \rightarrow b \rightarrow \dots \rightarrow h$$
|
||||
|
||||
Pseudo-code:
|
||||
|
||||
```
|
||||
class Node{
|
||||
Type data
|
||||
Node * next
|
||||
}
|
||||
```
|
||||
|
||||
## Enqueue + Dequeue -- First Versions
|
||||
|
||||
Variables:
|
||||
|
||||
* float (pointer to stack)
|
||||
* back (pointer to stack)
|
||||
* size (# elements in queue)
|
||||
|
||||
### Dequeue:
|
||||
|
||||
Pseudo-code:
|
||||
|
||||
```
|
||||
dequeue(){
|
||||
temp = front
|
||||
val = front->data
|
||||
front = front->next
|
||||
delete temp
|
||||
size = size-1
|
||||
return val
|
||||
}
|
||||
```
|
||||
|
||||
Diagram:
|
||||
|
||||
* <del>[front](#frontele2)</del>
|
||||
<ins>[front](#ele21)</ins>
|
||||
* [back](#backele2)
|
||||
* [temp](#frontele2)
|
||||
|
||||
Value|Next
|
||||
---|---
|
||||
<del><span id="frontele2">a</span></del>|<del>[pointer](#ele21)</del>
|
||||
<span id="ele21">b</span>|[pointer](#ele22)
|
||||
<span id="ele22">...</span>|...
|
||||
<span id="ele13">g</span>|[pointer](#backele2)
|
||||
<span id="backele2">h</span>|nullptr
|
||||
|
||||
|
||||
### Unqueue
|
||||
|
||||
Pseudo-code:
|
||||
|
||||
```
|
||||
enqueue(x){
|
||||
n = new node containing x
|
||||
back->next = n
|
||||
back = back->next
|
||||
size = size+1
|
||||
}
|
||||
```
|
||||
|
||||
Diagram:
|
||||
|
||||
* [front](#frontele3)
|
||||
* <del>[back](#backele3)</del>
|
||||
<ins>[back](#backele32)</ins>
|
||||
|
||||
Value|Next
|
||||
---|---
|
||||
<span id="frontele3">a</span>|[pointer](#ele31)
|
||||
<span id="ele31">b</span>|[pointer](#ele32)
|
||||
<span id="ele32">...</span>|...
|
||||
<span id="ele33">g</span>|[pointer](#backele3)
|
||||
<span id="backele3">h</span>|<del>nullptr</del> <ins>[pointer](#backele32)</ins>
|
||||
<ins><span id="backele32">x</span></ins>|<ins>nullptr</ins>
|
||||
|
||||
## Empty Queue
|
||||
|
||||
A stack with a
|
||||
|
||||
$$\text{front} \rightarrow a \leftarrow \text{back}$$
|
||||
|
||||
After dequeue
|
||||
|
||||
$$\text{front}, \text{back}$$
|
||||
|
||||
After enqueue(b)
|
||||
|
||||
$$\text{front} \rightarrow b \leftarrow \text{back}$$
|
||||
|
||||
Enqueue & Dequeue are different from empty/non-empty queues.
|
||||
|
||||
## Enqueue
|
||||
|
||||
Example 1: Empty queue
|
||||
|
||||
$$\text{front}, \text{back}$$
|
||||
|
||||
Enqueue b
|
||||
|
||||
$$\text{front} \rightarrow b \leftarrow \text{back}$$
|
||||
|
||||
Example 2: Starter queue
|
||||
|
||||
$$\text{front} \rightarrow \dots \rightarrow x \leftarrow \text{back}$$
|
||||
|
||||
enqueue b
|
||||
|
||||
$$\text{front} \rightarrow \dots \rightarrow x \rightarrow b \leftarrow \text{back}$$
|
||||
|
||||
Pseudo code:
|
||||
|
||||
```
|
||||
enqueue(x){
|
||||
if size > 0{
|
||||
back->next = new Node(x)
|
||||
back = back->next
|
||||
} else {
|
||||
back = new Node(x)
|
||||
front = back
|
||||
}
|
||||
size = size+1
|
||||
}
|
||||
```
|
||||
|
||||
## Dequeue
|
||||
|
||||
|
||||
Pseudo code:
|
||||
|
||||
```
|
||||
front = front->next
|
||||
return value
|
||||
```
|
||||
|
||||
That code has the following effect upon a queue.
|
||||
|
||||
$$\text{front} \rightarrow a \rightarrow b \rightarrow c \rightarrow d \leftarrow \text{back}$$
|
||||
|
||||
becomes
|
||||
|
||||
$$\text{front} \rightarrow b \rightarrow c \rightarrow d \leftarrow \text{back}$$
|
||||
|
||||
while returning a.
|
||||
|
||||
### Example 1:
|
||||
|
||||
$$\text{front} \rightarrow b \leftarrow \text{back}$$
|
||||
|
||||
dequeue (b)
|
||||
|
||||
$$\text{front}, \text{back}$$
|
||||
|
||||
### Example 2:
|
||||
|
||||
$$\text{front} \rightarrow b \rightarrow c \rightarrow d \leftarrow \text{back}$$
|
||||
|
||||
dequeue
|
||||
|
||||
$$\text{front} \rightarrow c \rightarrow d \leftarrow \text{back}$$
|
||||
|
||||
Return b
|
||||
|
||||
### Pseudo code
|
||||
|
||||
```
|
||||
dequeue(){
|
||||
temp = front
|
||||
val = front->data
|
||||
front = front->next
|
||||
delete temp
|
||||
size = size-1
|
||||
return val
|
||||
}
|
||||
```
|
||||
|
||||
## Traversing the List
|
||||
|
||||
Pseudo code:
|
||||
|
||||
```
|
||||
displayList(){
|
||||
Node * cur = front;
|
||||
while(cur!=nullptr){
|
||||
output cur->data
|
||||
cur = cur->next
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
A diagram which shows the cursor going from c, to d to be (in order from front to back).
|
||||
|
||||
## Linked List Ends
|
||||
|
||||
Transcriber's note: this is the same as in 06. The left/right arrows denote a double linked list, even though the current set of slides is talking about only singly linked lists.
|
||||
|
||||
For [4, 5, 6]:
|
||||
|
||||
{% katex display %}
|
||||
\text{head} \leftrightarrow \text{beginning node} \leftrightarrow 4 \leftrightarrow 5 \leftrightarrow 6 \leftrightarrow \text{ending node} \leftrightarrow \text{tail}
|
||||
{% endkatex %}
|
||||
|
||||
versus
|
||||
|
||||
{% katex display %}
|
||||
\text{head} \leftrightarrow 4 \leftrightarrow 5 \leftrightarrow 6 \leftrightarrow \text{tail}
|
||||
{% endkatex %}
|
||||
|
||||
For [5]:
|
||||
|
||||
{% katex display %}
|
||||
\text{head} \leftrightarrow \text{beginning node} \leftrightarrow 5 \leftrightarrow \text{ending node} \leftrightarrow \text{tail}
|
||||
{% endkatex %}
|
||||
|
||||
versus
|
||||
|
||||
$$\text{head} \leftrightarrow 5 \leftrightarrow \text{tail}$$
|
||||
|
||||
For []:
|
||||
|
||||
$$\text{head} \leftrightarrow \text{beginning node} \leftrightarrow \text{ending node} \leftrightarrow \text{tail}$$
|
||||
|
||||
versus
|
||||
|
||||
$$\text{head} , \text{tail}$$
|
||||
|
||||
## List Class: Traversing the List
|
||||
|
||||
Pseudo code:
|
||||
|
||||
```
|
||||
displayList(){
|
||||
Node * cur = head->next
|
||||
while(cur!=tail){
|
||||
output cur->data
|
||||
cur = cur->next
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Graphic of `cur` moving through each (empty) element of the queue.
|
||||
|
||||
## End
|
Binary file not shown.
File diff suppressed because one or more lines are too long
@ -1,823 +0,0 @@
|
||||
---
|
||||
layout: simple
|
||||
math: true
|
||||
---
|
||||
|
||||
# Rooted Trees -- CMPT 225
|
||||
|
||||
## Graphs
|
||||
|
||||
Graph is a pair G=<V,E>, with:
|
||||
|
||||
* V, a set called "vertacies" or "nodes"
|
||||
* E, a set of pairs from V, i.e. {% katex %}E \subseteq V\times V{% endkatex %} called edges
|
||||
* Example: {% katex %}G=\langle\{1,2,3\},\{(1,2),(1,3)\}\rangle{% endkatex %}
|
||||
|
||||
Example in table format:
|
||||
|
||||
node|connections
|
||||
---|---
|
||||
<span id="g1-1">1</span>|<a href="#g1-2">2</a>,<a href="#g1-3">3</a>
|
||||
<span id="g1-2">2</span>|<a href="#g1-1">1</a>
|
||||
<span id="g1-3">3</span>|<a href="#g1-1">1</a>
|
||||
|
||||
"G is directed": edges are ordered pairs (often called arcs)
|
||||
|
||||
{% katex display %}
|
||||
\langle\{\{1,2,3\},\{(1,2),(1,3)\}\}\rangle
|
||||
\neq
|
||||
\langle\{\{1,2,3\},\{(2,1),(1,3)\}\}\rangle
|
||||
{% endkatex %}
|
||||
|
||||
i.e. graph one:
|
||||
|
||||
node|connections
|
||||
---|---
|
||||
<span id="g2-1">1</span>|<a href="#g2-2">2</a>,<a href="#g2-3">3</a>
|
||||
<span id="g2-2">2</span>|
|
||||
<span id="g2-3">3</span>|
|
||||
|
||||
does not equal graph two:
|
||||
|
||||
node|connections
|
||||
---|---
|
||||
<span id="g3-1">1</span>|<a href="#g3-3">3</a>
|
||||
<span id="g3-2">2</span>|<a href="#g3-1">1</a>
|
||||
<span id="g3-3">3</span>|
|
||||
|
||||
"G is undirected" edges are sets
|
||||
|
||||
{% katex display %}
|
||||
\langle\{\{1,2,3\},\{(2,1),(1,3)\}\}\rangle
|
||||
=
|
||||
\langle\{\{1,2,3\},\{(1,2),(3,1)\}\}\rangle
|
||||
{% endkatex %}
|
||||
|
||||
i.e. graph one:
|
||||
|
||||
node|connections
|
||||
---|---
|
||||
<span id="g4-1">1</span>|<a href="#g4-3">3</a>,<a href="#g4-2">2</a>
|
||||
<span id="g4-2">2</span>|<a href="#g4-1">1</a>
|
||||
<span id="g4-3">3</span>|<a href="#g4-1">1</a>
|
||||
|
||||
is equal to graph two:
|
||||
|
||||
node|connections
|
||||
---|---
|
||||
<span id="g5-1">1</span>|<a href="#g5-2">2</a>,<a href="#g5-3">3</a>
|
||||
<span id="g5-2">2</span>|<a href="#g5-1">1</a>
|
||||
<span id="g5-3">3</span>|<a href="#g5-1">1</a>
|
||||
|
||||
By default, by "graph" we will mean "undirected graph".
|
||||
|
||||
## Path
|
||||
|
||||
Path of G of length n is a sequence $$\langle V_{0},V_{1},V_{2},\dots V_{n}\rangle$$ of vertacies s-t. $$(V_{0},V_{1}),(V_{1},V_{2}),(V_{2},V_{3})\dots$$ are edges of G.
|
||||
|
||||
s-t Path in G: path $$\langle s,\dots,t\rangle$$ in G.
|
||||
|
||||
Example of a s-t path of length 6 for G: $$\langle s,d,c,e,f,h,t\rangle$$
|
||||
|
||||
node|connections
|
||||
---|---
|
||||
<span id="g6-a">a</span>|<a href="#g6-b">b</a>,<a href="#g6-s">s</a>
|
||||
<span id="g6-b">b</span>|<a href="#g6-a">a</a>,<a href="#g6-c">c</a>
|
||||
<span id="g6-c">c</span>|<a href="#g6-b">b</a>,<a href="#g6-d">d</a>,<a href="#g6-e">e</a>,<a href="#g6-s">s</a>
|
||||
<span id="g6-d">d</span>|<a href="#g6-c">c</a>,<a href="#g6-s">s</a>
|
||||
<span id="g6-e">e</span>|<a href="#g6-c">c</a>,<a href="#g6-f">f</a>,<a href="#g6-g">g</a>
|
||||
<span id="g6-f">f</span>|<a href="#g6-e">e</a>,<a href="#g6-h">h</a>
|
||||
<span id="g6-g">g</span>|<a href="#g6-e">e</a>,<a href="#g6-h">h</a>,<a href="#g6-t">t</a>
|
||||
<span id="g6-h">h</span>|<a href="#g6-f">f</a>,<a href="#g6-g">g</a>,<a href="#g6-t">t</a>
|
||||
<span id="g6-s">s</span>|<a href="#g6-a">a</a>,<a href="#g6-c">c</a>,<a href="#g6-d">d</a>
|
||||
<span id="g6-t">t</span>|<a href="#g6-g">g</a>,<a href="#g6-h">h</a>
|
||||
|
||||
Vertex t is *reachable* from s in G if ther is an s-t path in G.
|
||||
G is *connected* if for every pair $$u,v\in V$$, u is reachable from v.
|
||||
|
||||
Transcriber's note: this is much easier to show with graphics and in fact very hard to show easily without graphics. I did my best, but it should be noted that this is *very* obvious with a visual graph.
|
||||
It becomes two seperate graphs, in essense.
|
||||
So for convenience, I will be splitting this up into two tables, even though technically it's one "graph" with two sets of connected nodes.
|
||||
|
||||
<p id="connected1">Connected:</p>
|
||||
|
||||
node|connections
|
||||
---|---
|
||||
<span id="g7-a">a</span>|<a href="#g7-b">b</a>,<a href="#g7-s">s</a>
|
||||
<span id="g7-b">b</span>|<a href="#g7-a">a</a>,<a href="#g7-c">c</a>
|
||||
<span id="g7-c">c</span>|<a href="#g7-b">b</a>,<a href="#g7-d">d</a>,<a href="#g7-e">e</a>,<a href="#g7-s">s</a>
|
||||
<span id="g7-d">d</span>|<a href="#g7-c">c</a>,<a href="#g7-s">s</a>
|
||||
<span id="g7-e">e</span>|<a href="#g7-c">c</a>,<a href="#g7-f">f</a>,<a href="#g7-g">g</a>
|
||||
<span id="g7-f">f</span>|<a href="#g7-e">e</a>,<a href="#g7-h">h</a>
|
||||
<span id="g7-g">g</span>|<a href="#g7-e">e</a>,<a href="#g7-h">h</a>,<a href="#g7-t">t</a>
|
||||
<span id="g7-h">h</span>|<a href="#g7-f">f</a>,<a href="#g7-g">g</a>,<a href="#g7-t">t</a>
|
||||
<span id="g7-s">s</span>|<a href="#g7-a">a</a>,<a href="#g7-c">c</a>,<a href="#g7-d">d</a>
|
||||
<span id="g7-t">t</span>|<a href="#g7-g">g</a>,<a href="#g7-h">h</a>
|
||||
|
||||
Not connected:
|
||||
|
||||
node|connections
|
||||
---|---
|
||||
<span id="g9-a">a</span>|<a href="#g9-b">b</a>,<a href="#g9-s">s</a>
|
||||
<span id="g9-b">b</span>|<a href="#g9-a">a</a>,<a href="#g9-c">c</a>
|
||||
<span id="g9-c">c</span>|<a href="#g9-b">b</a>,<a href="#g9-d">d</a>,<a href="#g9-e">e</a>,<a href="#g9-s">s</a>
|
||||
<span id="g9-d">d</span>|<a href="#g9-c">c</a>,<a href="#g9-s">s</a>
|
||||
<span id="g9-e">e</span>|<a href="#g9-c">c</a>
|
||||
<span id="g9-s">s</span>|<a href="#g9-a">a</a>,<a href="#g9-c">c</a>,<a href="#g9-d">d</a>
|
||||
|
||||
node|connections
|
||||
---|---
|
||||
<span id="g10-f">f</span>|<a href="#g10-h">h</a>
|
||||
<span id="g10-g">g</span>|<a href="#g10-h">h</a>,<a href="#g10-t">t</a>
|
||||
<span id="g10-h">h</span>|<a href="#g10-f">f</a>,<a href="#g10-g">g</a>,<a href="#g10-t">t</a>
|
||||
<span id="g10-t">t</span>|<a href="#g10-g">g</a>,<a href="#g10-h">h</a>
|
||||
|
||||
## Cycles & Trees
|
||||
|
||||
Cycle in G: path $$\langle V_{0},\dots V_{n-1},V_{n}\rangle$$ in G where $$V_{0}=V_{n}$$
|
||||
|
||||
*Simple path*: all vertecies are distinct.
|
||||
*Simple Cycle*: cycle $$\langle V_{0},\dots V_{n-1},V_{n}\rangle$$ where $$\langle V_{0},\dots,V_{n-1}$$ is a simple path.
|
||||
|
||||
Simple cylcle of length 5: (see ["connected" graph](#connected1) for confirmation): $$\langle s,d,c,b,a,s\rangle$$
|
||||
|
||||
Cycle of length 7 + repeats: $$\langle s,d,c,b,f,e,c,s\rangle$$
|
||||
|
||||
node|connections
|
||||
---|---
|
||||
<span id="g11-a">a</span>|<a href="#g11-b">b</a>,<a href="#g11-s">s</a>
|
||||
<span id="g11-b">b</span>|<a href="#g11-a">a</a>,<a href="#g11-c">c</a>,<a href="#g11-f">f</a>
|
||||
<span id="g11-c">c</span>|<a href="#g11-b">b</a>,<a href="#g11-d">d</a>,<a href="#g11-e">e</a>,<a href="#g11-f">f</a>,<a href="#g11-s">s</a>
|
||||
<span id="g11-d">d</span>|<a href="#g11-c">c</a>,<a href="#g11-s">s</a>
|
||||
<span id="g11-e">e</span>|<a href="#g11-c">c</a>,<a href="#g11-f">f</a>,<a href="#g11-g">g</a>
|
||||
<span id="g11-f">f</span>|<a href="#g11-c">c</a>,<a href="#g11-e">e</a>,<a href="#g11-h">h</a>,<a href="#g11-b">b</a>
|
||||
<span id="g11-g">g</span>|<a href="#g11-e">e</a>,<a href="#g11-h">h</a>,<a href="#g11-t">t</a>
|
||||
<span id="g11-h">h</span>|<a href="#g11-f">f</a>,<a href="#g11-g">g</a>,<a href="#g11-t">t</a>
|
||||
<span id="g11-s">s</span>|<a href="#g11-a">a</a>,<a href="#g11-c">c</a>,<a href="#g11-d">d</a>
|
||||
<span id="g11-t">t</span>|<a href="#g11-g">g</a>,<a href="#g11-h">h</a>
|
||||
|
||||
## Tree
|
||||
|
||||
Tree: a connected, acyclic graph:
|
||||
|
||||
Example 1 (not a tree, due to cycle: $$\langle s,c,d,s\rangle$$):
|
||||
|
||||
node|connections
|
||||
---|---
|
||||
<span id="g12-a">a</span>|<a href="#g12-b">b</a>
|
||||
<span id="g12-b">b</span>|<a href="#g12-a">a</a>,<a href="#g12-c">c</a>
|
||||
<span id="g12-c">c</span>|<a href="#g12-b">b</a>,<a href="#g12-d">d</a>,<a href="#g12-e">e</a>,<a href="#g12-s">s</a>
|
||||
<span id="g12-d">d</span>|<a href="#g12-c">c</a>,<a href="#g12-s">s</a>
|
||||
<span id="g12-e">e</span>|<a href="#g12-c">c</a>,<a href="#g12-g">g</a>
|
||||
<span id="g12-f">f</span>|<a href="#g12-h">h</a>
|
||||
<span id="g12-g">g</span>|<a href="#g12-e">e</a>,<a href="#g12-h">h</a>,<a href="#g12-t">t</a>
|
||||
<span id="g12-h">h</span>|<a href="#g12-f">f</a>,<a href="#g12-g">g</a>,<a href="#g12-t">t</a>
|
||||
<span id="g12-s">s</span>|<a href="#g12-c">c</a>,<a href="#g12-d">d</a>
|
||||
<span id="g12-t">t</span>|<a href="#g12-g">g</a>,<a href="#g12-h">h</a>
|
||||
|
||||
Example 2 (a tree, no cycle, all connected):
|
||||
|
||||
Now using ARIA trees:
|
||||
|
||||
<!-- AUTO GENERATED FROM CUSTOM PYTHON CODE -->
|
||||
<ul role="tree">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
s
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
a
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
b
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
d
|
||||
</span>
|
||||
</li>
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
c
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
e
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
f
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
h
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
g
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
i
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<!-- END OF GENERATED CODE -->
|
||||
|
||||
Example 3 (not a tree) (transcriber's note: written as two trees for simplicity's sake)
|
||||
|
||||
|
||||
<!-- AUTO GENERATED FROM CUSTOM PYTHON CODE -->
|
||||
<ul role="tree">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
s
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
a
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
b
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
d
|
||||
</span>
|
||||
</li>
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
c
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
e
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<!-- END OF GENERATED CODE -->
|
||||
|
||||
<!-- AUTO GENERATED FROM CUSTOM PYTHON CODE -->
|
||||
<ul role="tree">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
f
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
h
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
g
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
i
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<!-- END OF GENERATED CODE -->
|
||||
|
||||
Fact: every tree with $$n$$ verticies has $$n-1$$ edges.
|
||||
|
||||
## Rooted-tree:
|
||||
|
||||
Rooted tree: tree with a distringuished vertex called the root.
|
||||
|
||||
Unrooted tree:
|
||||
|
||||
|
||||
<!-- AUTO GENERATED FROM CUSTOM PYTHON CODE -->
|
||||
<ul role="tree">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
a
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
b
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
c
|
||||
</span>
|
||||
</li>
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
d
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
e
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
f
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
g
|
||||
</span>
|
||||
</li>
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
h
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
i
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
j
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
k
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
l
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<!-- END OF GENERATED CODE -->
|
||||
|
||||
Tree T with root:
|
||||
|
||||
|
||||
<!-- AUTO GENERATED FROM CUSTOM PYTHON CODE -->
|
||||
<ul role="tree">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
a (root)
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
b
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
c
|
||||
</span>
|
||||
</li>
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
d
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
e
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
f
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
g
|
||||
</span>
|
||||
</li>
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
h
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
i
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
j
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
k
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
l
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<!-- END OF GENERATED CODE -->
|
||||
|
||||
An alternate drawing of T, with no semantic change.
|
||||
|
||||
Notice: in a tree there is a unique path between any two verticies.
|
||||
So: a unique path from any vertex to the root.
|
||||
Thus: the root indicates a *direction* on the edges e.g. towards the root.
|
||||
|
||||
A graph of the same tree, T, with arrows pointing towards the root.
|
||||
There is no reason for having any semantic markup for this.
|
||||
|
||||
(sometimes "away from the root").
|
||||
|
||||
## Rooted Tree Terminology
|
||||
|
||||
|
||||
<!-- AUTO GENERATED FROM CUSTOM PYTHON CODE -->
|
||||
<ul role="tree">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
z (root, anscestor of a)
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
y
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
x (leaf)
|
||||
</span>
|
||||
</li>
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
w (leaf)
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
v (anscestor of a)
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
u (leaf)
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
t (anscestor of a, parent of a)
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
s (sibling of a, leaf)
|
||||
</span>
|
||||
</li>
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
r (sibling of a, leaf)
|
||||
</span>
|
||||
</li>
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
a (descendant of a, anscestor of a)
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
q (child of a, desandant of a)
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
o (decendant of a, leaf)
|
||||
</span>
|
||||
</li>
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
n (decendant of a, leaf)
|
||||
</span>
|
||||
</li>
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
m (decendant of a, leaf)
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
p (child of a, desendant of a, leaf)
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<!-- END OF GENERATED CODE -->
|
||||
|
||||
* The *root* has no parent.
|
||||
* *Leaves* have no children.
|
||||
* Internal nodes are the non-leaves (sometimes root ??? [can't read] too)
|
||||
|
||||
## Depth & Height
|
||||
|
||||
|
||||
<!-- AUTO GENERATED FROM CUSTOM PYTHON CODE -->
|
||||
<ul role="tree">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
4 (depth 0)
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
1 (depth 1)
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
0 (depth 2)
|
||||
</span>
|
||||
</li>
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
0 (depth 2)
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
3 (depth 1)
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
2 (depth 2)
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
1 (depth 3)
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
0 (depth 4)
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
0 (depth 3)
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
0 (depth 2)
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<!-- END OF GENERATED CODE -->
|
||||
|
||||
* Depth of node v = length of path from v to the root.
|
||||
* Height of node v = length of longest path from to a decendant of v (e.g. to a leaf)
|
||||
* Height of Tree T = height of its root = max height of any node in T = max depth of any node in T.
|
||||
|
||||
A rooted tree is:
|
||||
|
||||
* k-ary if *no node has* >k children.
|
||||
* binary if *no node has* >2 children.
|
||||
* ordered if the children of every node are ordered.
|
||||
|
||||
E.g. A ordered trenary tree:
|
||||
|
||||
|
||||
<!-- AUTO GENERATED FROM CUSTOM PYTHON CODE -->
|
||||
<ul role="tree">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
no name
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
1
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
1
|
||||
</span>
|
||||
</li>
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
2
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
2
|
||||
</span>
|
||||
</li>
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
3
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
1
|
||||
</span>
|
||||
</li>
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
2
|
||||
</span>
|
||||
</li>
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
3
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<!-- END OF GENERATED CODE -->
|
||||
|
||||
Notice: when we draw a tree, or represent it in a data structure, we order it.
|
||||
|
||||
In an ordered binary tree, every child of a node v is either the "left child of v" or the "right child of v".
|
||||
|
||||
Transcriber's note: nodes' children are transcribes from left to right. So for a binary tree, the first child is the "left child" and the second child is the "right child".
|
||||
|
||||
## Subtree rooted at v
|
||||
|
||||
Subtree rooted at v: tree with root v and containing all decendants of v.
|
||||
|
||||
In a binary tree:
|
||||
* "left subtree of v" means the subtree rooted at the left child of v.
|
||||
* sim. for "right child of v".
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- AUTO GENERATED FROM CUSTOM PYTHON CODE -->
|
||||
<ul role="tree">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
z
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
v (subtree rooted at v)
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
y (subtree rooted at v, left subtree of v)
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
v (subtree rooted at v, left subtree of v
|
||||
</span>
|
||||
</li>
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
u (subtree rooted at v, left subtree of v
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
x (subtree rooted at v, right subtree of v)
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
w (subtree rooted at v, right subtree of v)
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
a
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
b
|
||||
</span>
|
||||
</li>
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
c
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<!-- END OF GENERATED CODE -->
|
||||
|
||||
## End
|
Binary file not shown.
File diff suppressed because one or more lines are too long
@ -1,398 +0,0 @@
|
||||
---
|
||||
layout: simple
|
||||
math: true
|
||||
---
|
||||
|
||||
# Recursion on Trees
|
||||
|
||||
CMPT 225
|
||||
|
||||
## Recursion
|
||||
|
||||
Recursion: A definition of a function is recursive if the body cointains an application of itself.
|
||||
|
||||
Consider: {% katex display %}
|
||||
S(n)=\sum_{i=0}^{n} i
|
||||
{% endkatex %}
|
||||
|
||||
or
|
||||
|
||||
{% katex display %}
|
||||
S(n) = \begin{cases}
|
||||
0 & \text{if } n=0\\
|
||||
n+S(n-1) & \text{if } n>0
|
||||
\end{cases}
|
||||
{% endkatex %}
|
||||
|
||||
These two descriptions of $$S(n)$$ suggest two implementations:
|
||||
|
||||
e.g.:
|
||||
|
||||
```
|
||||
S(n){
|
||||
s=0
|
||||
for i=1..n
|
||||
s=s+i
|
||||
return s
|
||||
}
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```
|
||||
S(n){
|
||||
if n=0
|
||||
return 0
|
||||
else
|
||||
return n+S(n-1)
|
||||
}
|
||||
```
|
||||
|
||||
## Recursive Version
|
||||
|
||||
* -> S(4)
|
||||
* -> S(3)
|
||||
* -> S(2)
|
||||
* -> S(1)
|
||||
* -> S(0)
|
||||
* <span id="inner0">returns 0</span>
|
||||
* returns <span id="inner1">1+[0](#inner0)</span>
|
||||
* returns <span id="inner2">2+[1](#inner1)=3</span>
|
||||
* returns <span id="inner3">3+[3](#inner2)=6</span>
|
||||
* returns 4+[6](#inner3)=10
|
||||
|
||||
Iterative version:
|
||||
|
||||
{% katex display %}
|
||||
S = 0 + \sum_{i=1}^{n} i = 1 + \sum_{i=2}^{n} i = 3 + \sum_{i=3}^{n} i = \dots\\
|
||||
= 0+1+2+3+4
|
||||
{% endkatex %}
|
||||
|
||||
The *same computation*, but a different control strategy.
|
||||
|
||||
## Recursion & The Call Stack
|
||||
|
||||
Code:
|
||||
|
||||
```
|
||||
S(n){
|
||||
if(n=0){
|
||||
r=0
|
||||
}else{
|
||||
r=n+S(n-1)
|
||||
}
|
||||
return r
|
||||
}
|
||||
```
|
||||
|
||||
Compute `p=S(2)`:
|
||||
|
||||
* Call S(2):
|
||||
* n = 2
|
||||
* r = ? ->
|
||||
* Call S(1):
|
||||
* n=1
|
||||
* r=? ->
|
||||
* Call S(0):
|
||||
* N=0
|
||||
* r=0
|
||||
* <span id="innerstack1">return 0</span>
|
||||
* <span id="innerstack2">return 1+[S(0)](#innerstack1)</span>
|
||||
* return 2+[S(1)](#innerstack2)
|
||||
|
||||
The call stack at the end:
|
||||
|
||||
Name|Value|Removed
|
||||
S|<code of S; n=0, r=0>|true
|
||||
S|<code of S; n=1, r=1>|true
|
||||
S|<code of S; n=2, r=3>|true
|
||||
p|3|false
|
||||
|
||||
After the call the `S(2)` is complete, the entire call stack of S to S to S is gone.
|
||||
|
||||
There are 2 more slides containing *slightly* different versions of the same diagrams.
|
||||
They do not provide any extra information.
|
||||
|
||||
## Recursion on Trees
|
||||
|
||||
* We will often use recursion & induction on trees.
|
||||
* e.g. the tree rooted a v has some property if its subtrees have some related property
|
||||
* e.g. the height of node v in a binary tree may be defined by:
|
||||
|
||||
{% katex display %}
|
||||
h(v) = \begin{cases}
|
||||
0 & \text{ if v is a leaf}\\
|
||||
1 + \text{max}\{h(\text{left}(v)), h(\text{right}(v))\} & \text{ otherwise}
|
||||
\end{cases}
|
||||
{% endkatex %}
|
||||
|
||||
(We can define h(left(v)) to be -1 if left(v) does not exist, and sim. for right(v)).
|
||||
|
||||
## Recurssion a Trees Examples
|
||||
|
||||
height of node v in T:
|
||||
|
||||
{% katex display %}
|
||||
h(v) = \begin{cases}
|
||||
0 & \text{ if v is a leaf}\\
|
||||
1+ max\{h(\text{left}(v)),h(\text{right}(v))\} & \text{ ow}
|
||||
\end{cases}
|
||||
{% endkatex %}
|
||||
|
||||
for the follwing tree: $$h(v)=?$$
|
||||
|
||||
|
||||
<!-- AUTO GENERATED FROM CUSTOM PYTHON CODE -->
|
||||
<ul role="tree">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
v
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
a
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
e
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
g
|
||||
</span>
|
||||
</li>
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
h
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
f
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
i
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
b
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
c
|
||||
</span>
|
||||
</li>
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
d
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<!-- END OF GENERATED CODE -->
|
||||
|
||||
## Recursion on Trees Example (pt 2)
|
||||
|
||||
(See math equation of previous slide)
|
||||
|
||||
h(v) = 3
|
||||
|
||||
|
||||
<!-- AUTO GENERATED FROM CUSTOM PYTHON CODE -->
|
||||
<ul role="tree">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
v (3)
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
a (2)
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
e (1)
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
g (0)
|
||||
</span>
|
||||
</li>
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
h (0)
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
f (1)
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
i (0)
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
b (1)
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
c (0)
|
||||
</span>
|
||||
</li>
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
d (0)
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<!-- END OF GENERATED CODE -->
|
||||
|
||||
## Pseudo-code version:
|
||||
|
||||
```
|
||||
height(v){
|
||||
if v is a leaf
|
||||
return 0
|
||||
if v has one child u
|
||||
return 1+height(u)
|
||||
else
|
||||
return 1+max(height(left(v)), height(right(v)))
|
||||
}
|
||||
```
|
||||
|
||||
## Traversals of Binary Tree
|
||||
|
||||
* A traversal of a graph is a process that "visits" each node in the graph once.
|
||||
* We consider 4 standard tree traversalt:
|
||||
1. level order
|
||||
2. pre-order
|
||||
3. in-order
|
||||
4. post-order
|
||||
* 2,3,4 begin at the root & recursively visit the nodes in each subtree & the root. They vary in the relative ???(can't read).
|
||||
|
||||
(Level order later)
|
||||
|
||||
Code:
|
||||
|
||||
```
|
||||
pre-order-T(v){
|
||||
visit v
|
||||
pre-order-T(left(v))
|
||||
pre-order-T(right(v))
|
||||
}
|
||||
```
|
||||
|
||||
pre-order-T(v) does nothing if v does not exist.
|
||||
|
||||
* v is visited before any of its decendants
|
||||
* every node in the left subtree is visited before any node in the right subtree.
|
||||
|
||||
Tree to come back to:
|
||||
|
||||
<!-- AUTO GENERATED FROM CUSTOM PYTHON CODE -->
|
||||
<ul role="tree">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
A
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
B
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
D
|
||||
</span>
|
||||
</li>
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
E
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
C
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span>
|
||||
F
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<!-- END OF GENERATED CODE -->
|
||||
|
||||
Pre-order-traversal: A,B,D,E,C,F
|
||||
|
||||
## in-order-T
|
||||
|
||||
code:
|
||||
|
||||
```
|
||||
in-order-T(v){
|
||||
in-order-T(left(v))
|
||||
visit v
|
||||
in-order-T(right(v))
|
||||
}
|
||||
```
|
||||
|
||||
In order traversal: D,B,E,A,C,F
|
||||
|
||||
|
||||
## post-order-T
|
||||
|
||||
code:
|
||||
|
||||
```
|
||||
post-order-T(v){
|
||||
post-order-T(left(v))
|
||||
post-order-T(right(v))
|
||||
visit v
|
||||
}
|
||||
```
|
||||
|
||||
Post order traversal: D,E,B,F,C,A
|
||||
|
||||
## End
|
||||
|
||||
...some repeated slides... unknown reason
|
Binary file not shown.
File diff suppressed because one or more lines are too long
@ -1,122 +0,0 @@
|
||||
---
|
||||
layout: simple
|
||||
math: true
|
||||
---
|
||||
|
||||
Transciber's notes:
|
||||
* $$\iff$$ is "if and only if"
|
||||
* $$\implies$$ is "implies"
|
||||
* $$\forall$$ is "for all"
|
||||
* $$\exists$$ is "exists"
|
||||
|
||||
# Big-Oh--Part I
|
||||
|
||||
CMPT 225
|
||||
|
||||
## Slide 1
|
||||
|
||||
* Recall: if `f,g` are functions `f:N->N`,`g:N->N`
|
||||
* f is `O(g)` means there are constants $$n_{0},c > 0$$
|
||||
s.t. for every $$n>n_{0},f(n) \leq \text{c.g}(n)$$
|
||||
* that is for all but finitely many "small" values of n: $$f(n) \leq cg(n)$$
|
||||
* or f grows no faster than g (asymtotically)
|
||||
* we typically write $$f(n) = O(g(n))$$
|
||||
|
||||
## Consider `f(n)`,`g(n)`:
|
||||
|
||||
Claim: $$f(n) = O(g(n))$$
|
||||
|
||||
Why:
|
||||
|
||||
* When $$f(n) > g(n)$$ for all n?
|
||||
* But $$f(n) < 2g(n)$$ for almost all values of `n`.
|
||||
* choose $$n_{0}$$ to "exclude" the real values of `n`.
|
||||
* Now: $$f(n) < 2g(n)$$ for all $$n>n_{0}$$
|
||||
* So: $$f(n) = O(g(n))$$
|
||||
|
||||
## Also:
|
||||
|
||||
(A graph a cannot transcribe because the notation doesn't make any sense. All future graphs have complexity on the y axis and the value of n [input to the function] as the x asxis.)
|
||||
|
||||
Claim: f(n) is **not** O(g(n))
|
||||
|
||||
However large we choose $$c,n_{0}$$, there will be some k (larger than $$n_0$$) s.d.: $$n > k \implies f(n) > c g(n)$$
|
||||
|
||||
## Consider `O(1)` (i.e. $$g(n)=1$$)
|
||||
|
||||
$$f(n) = O(1)$$ if $$\exists n_{0},c > 0$$ s.t. $$\forall n>n_{0} \space \space f(n) \leq c\times 1$$
|
||||
|
||||
(Another graph that makes no Goddamn sense whatsoever.)
|
||||
|
||||
* for every $$n>n_{0}, f(n)<c$$ <-- >-->
|
||||
* so, f(n) grwos no faster than a constant
|
||||
* so f(n) is asymptotically bounded by a constant
|
||||
|
||||
## The constant does not matter
|
||||
|
||||
|
||||
Fact: $$f(n) = O(1) \iff f(n)=O(\text{10}^{27}) \iff f(n) = O(\frac{1}{\text{10}^{27}})$$
|
||||
|
||||
Suppose: $$f(n) = O(\text{10}^{27})$$ \*
|
||||
|
||||
Claim: $$f(n)$$ is also $$O(\frac{1}{\text{10}^{27}})$$
|
||||
|
||||
\* means $$\exists n_{0},c > 0$$ s.t. $$n > n_{0} \implies f(n) \leq c\times\text{10}^{27}$$
|
||||
|
||||
Want to show: $$\exists n_{0},c^{1}>0$$ s.t. $$n>n_{0} \implies f(n) \leq c^{1}\times \frac{1}{\text{10}^{27}}$$
|
||||
|
||||
Choose $$c^1$$ big enough that $$c^{1} \frac{1}{\text{10}^{27}} \leq c \times \text{10}^{27}$$
|
||||
|
||||
e.g: $$c^{1} = c \times \text{10}^{54}$$
|
||||
|
||||
Then:
|
||||
|
||||
{% katex display %}
|
||||
\forall n>n_{0}, f(n) \leq c \times \text{10}^{27} \\
|
||||
\leq c \times \text{10}^{-27} - \text{10}^{54}\\
|
||||
\leq c^1 - \text{10}^{-27}
|
||||
{% endkatex %}
|
||||
|
||||
(54-27=27)
|
||||
|
||||
So: $$f(n)=O(\text{10}^{-27})$$
|
||||
|
||||
## Asymtotic Notation (e.g. Big-Oh)
|
||||
|
||||
* Is *not* "about" algorithm
|
||||
* *Is* a tool for describing (growth of) functions
|
||||
* It is useful for describing functions related to algorithms + data structures, e.g.:
|
||||
* minimum or maximum time taken
|
||||
* minimum or maximum space needed
|
||||
* etc.
|
||||
* We use it so often for worst-case time for an algorithm that we often leave implciit a statement like "let T(n) be the max time taken by algorithm A as an input of size as most n." This statement is essential.
|
||||
|
||||
## Ex. *Complexity of Palindrome Checking*
|
||||
|
||||
* using a stack & queue
|
||||
* Algorithm:
|
||||
1. Insert all tokens into a stack & a queue
|
||||
2. Repeat pop one token; dequeue one token. if different report 'no'.
|
||||
* size of input = number of symbols or token
|
||||
* each token is (all together O(1)):
|
||||
* pushed on the stack, O(1)
|
||||
* enqueued on the queue, O(1)
|
||||
* popped off the stack, O(1)
|
||||
* dequeued from the queue, O(1)
|
||||
* compared to one other token, O(1)
|
||||
* $$\text{n tokens} \implies n \times O(1)$$ time in total
|
||||
* So: $$T(n) = n \times O(1) = O(n)$$
|
||||
|
||||
## What does $$n\times O(1) = O(n)$$ mean?
|
||||
|
||||
It means: $$f(n) = O(1) \iff n\times f(n) = O(n)$$
|
||||
|
||||
To see if it is true:
|
||||
|
||||
{% katex display %}
|
||||
f(n) = O(1) \iff \exists c>0 \space \text{s.t.} \space f(n) < c, \text{for any} \space n \in \Z\\
|
||||
\iff \exists c>0 \text{ s.t. } n\times f(n) < c\times n, \text{for any } n \in \N\\
|
||||
\iff n\times f(n) = O(n)
|
||||
{% endkatex %}
|
||||
|
||||
## End
|
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because one or more lines are too long
@ -1,77 +0,0 @@
|
||||
---
|
||||
layout: simple
|
||||
math: true
|
||||
---
|
||||
|
||||
# Big-Omega & Big-Theta
|
||||
|
||||
## Big-Oh Gives Upper Bounds
|
||||
|
||||
For f,g functions $$\N \rightarrow \R^+$$,<br>
|
||||
$$f(n) = \Omega(g(n))$$ means there are $$c,n_0 > 0$$ s.t.
|
||||
$$\forall n>n_0\quad f(n) \geq c \times g(n)$$
|
||||
|
||||
i.e. f is asymptotically bounded from below by g
|
||||
|
||||
(A graph with two lines.
|
||||
f is a blue line with a wobbly, but mostly linear movement upwards.
|
||||
c times g is a red line which has a similar trajectory, but end up just slightly below the blue line.)
|
||||
|
||||
Note: We may have $$C << 1$$
|
||||
|
||||
or f grows asymptotically at least as fast as g.
|
||||
|
||||
## Big-Oh & Big-Omega are Duals
|
||||
|
||||
Fact: $$f(n) = \Omega(g(n)) \leftrightarrow g(n) = O(f(n))$$
|
||||
|
||||
Pf: $$f(n) = \Omega(g(n))$$:
|
||||
|
||||
* $$\iff \exists n_0, c' > 0 \text{ s.t. } n>n_0 \implies f(n) \geq c' \cdot g(n)$$
|
||||
* $$\iff \exists n_0,c' > 0 \text{ s.t. } n>n_0 \implies c'\cdot g(n) \leq f(n)$$
|
||||
* $$\iff\exists n_0,c > 0 \text{ s.t. } n>n_0 \implies g(n) \leq c\cdot f(n)$$ // letting $$c = \frac{1}{c'}$$
|
||||
* $$\iff g(n) O(f(n))$$
|
||||
|
||||
So: f grows at least as fast as g $$\iff$$ g grows at most as fast as f.
|
||||
|
||||
## Examples: Worse-case times
|
||||
|
||||
Operation|$$O(1)$$|$$\Omega(1)$$|$$O(\log n)$$ (highlighted)|$$\Omega(\log n)$$ (highlighted)|$$O(n)$$|$$\Omega(n)$$|$$O(n \log n)$$|$$\Omega(n \log n)$$
|
||||
---|---|---|---|---|---|---|---|---
|
||||
stack push/pop (highlighted)|✓ (green)|✓ (green)|✓|❌ (blue)|✓|❌ (blue)|✓|❌ (blue)
|
||||
unqueue/dequeue|✓ (green)|✓ (green)|✓|❌ (blue)|✓|❌ (blue)|✓|❌ (blue)
|
||||
heap insert or extract min|❌ (pink)|✓|✓ (green)|✓ (green)|✓|❌ (blue)|✓|❌ (blue)
|
||||
AVL-tree find, insert, remove|❌ (pink)|✓|✓ (green)|✓ (green)|✓|❌ (blue)|✓|❌ (blue)
|
||||
make_heap|❌ (pink)|✓|❌ (pink)|✓|✓ (green)|✓ (green)|✓|❌ (blue)
|
||||
BST find, insert, remove|❌ (pink)|✓|❌ (pink)|✓|✓ (green)|✓ (green)|✓|❌ (blue)
|
||||
Sorting|❌ (pink)|✓|❌ (pink)|✓|❌ (pink)|✓ (green)|✓ (green)|? (red)
|
||||
|
||||
## Big-Theta Expresses "Tight Bounds"
|
||||
|
||||
For f,g functions $$\N \rightarrow \R^+$$,
|
||||
$$f(n) = \Theta(g(n))$$ means there are $$c_1, c_2,n_0 > 0 \text{ s.t. } n>n_0 \implies c_1\cdot g(n) \leq f(n) \leq c_2\cdot g(n)$$
|
||||
|
||||
i.e. f asymptotically bounded from above and below by g
|
||||
|
||||
(Diagram with three lines, wobbly but roughly linear, with them stacked in the following order from top to bottom:
|
||||
|
||||
* $$c_2 \cdot g$$
|
||||
* f
|
||||
* $$c_1 \cdot g$$)
|
||||
|
||||
or f grows asymptotically the same as g.
|
||||
|
||||
## "Grows the same as" is systemetic
|
||||
|
||||
Fact: $$f(n) = \Theta(g(n)) \iff g(n) = \Theta(f(n))$$
|
||||
|
||||
i.e. f grows the same as g $$\iff$$ g grows the same as f.
|
||||
|
||||
P.f.: $$f(n) = \Theta(g(n))
|
||||
|
||||
* $$\iff \exists \text{c1},\text{c2},n_0 > 0 \text{ s.t. } \forall n>n_0 \quad c1\cdot g(n) \leq f(n) \leq c2\cdot g(n)$$
|
||||
* $$\iff \exists c_1,c2,n_0 > 0 \text{ s.t. } \forall n>n_0 \quad \frac{1}{c2} f(n) \leq g(n) \leq \frac{1}{c1} f(n)$$
|
||||
* $$\iff \exists c_3,c_4,n_0 > 0 \text{ s.t. } \forall n>n_0 c_3 f(n) \leq g(n) \leq c_4 f(n)$$
|
||||
* $$\iff g(n) = \Theta(f(n))$$
|
||||
|
||||
## End
|
Binary file not shown.
File diff suppressed because one or more lines are too long
@ -1,537 +0,0 @@
|
||||
---
|
||||
layout: simple
|
||||
math: true
|
||||
---
|
||||
|
||||
# Sorting
|
||||
|
||||
## Sorting
|
||||
|
||||
* re-arranging elements of a sequence $$S \text{ s.t. } S_0 \leq S_1 \leq S_2 \leq \cdots \leq S_{n-1}$$
|
||||
* We will look at 5 sorting algorithms:
|
||||
* 3 iterative
|
||||
* 2 recursive
|
||||
|
||||
## The iterative algorithms
|
||||
|
||||
* maintain a partition: "unsorted part" & "srtoed part"
|
||||
* sort a sequence of n elements in n-1 stages
|
||||
* at each stage, move 1 element from the unsorted part to the sorted part:
|
||||
* (Diagram of a generic array with unseen "sorted" items on the left and "unsorted" elements on the right. Caption: "1 stage moves 1 element")
|
||||
|
||||
```
|
||||
sort(A){
|
||||
* initialize
|
||||
* repeat n-1 times
|
||||
* move 1 element from unsorted and sorted part
|
||||
}
|
||||
```
|
||||
|
||||
* The algorithms differ in how they:
|
||||
* select an element to remove from the unsorted part
|
||||
* insert it into the sorted part
|
||||
|
||||
## Insertion Sort
|
||||
|
||||
* Initially sorted part is just A[0]
|
||||
* Repeat n-1 times
|
||||
* remove the first element from the unsorted part
|
||||
* insert it into the sorted part (shifting elements to the right as needed)
|
||||
|
||||
Diagram of array as it gets sorted in three stages:
|
||||
|
||||
* Stage 1: sorted is leftmost (0th) element; n-1 elements are unsorted on the right.
|
||||
* Stage 2: approximately half of the array is sorted; an arrow points from the leftmost value inside the unsorted side to an arbitrary position inside the sorted side.
|
||||
* Stage 3: just over half of the array is sorted now.
|
||||
|
||||
Code:
|
||||
|
||||
```
|
||||
insertion sort(A){
|
||||
for(i=1 to n-1){
|
||||
pivot = A[i] // first element in unsorted part
|
||||
j=i-1
|
||||
// The following loop shifts all elements in sorted parts that are larger than pivot 1 "to the right"
|
||||
while(j>=0 AND A[i] > pivot){
|
||||
A[j+i] = A[j] // shift jth
|
||||
j = j-1
|
||||
}
|
||||
A[j+i] = pivot // move pivot into position.
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Insertion Sort Example
|
||||
|
||||
Stages:
|
||||
|
||||
* Stage 0: Original
|
||||
* 5|4|2|6|1|3
|
||||
* Stage 1: (label: 4)
|
||||
* 4|5|2|6|1|3
|
||||
* Stage 2: (label: 2)
|
||||
* 2|4|5|6|1|3
|
||||
* Stage 3: (label: 6)
|
||||
* 2|4|5|6|1|3
|
||||
* Stage 4: (label: 1)
|
||||
* 1|2|4|5|6|3
|
||||
* Stage 5: (label: 3)
|
||||
* 1|2|3|4|5|6
|
||||
|
||||
## Selection Sort
|
||||
|
||||
* initially sorted part is empty
|
||||
* repeat n-1 times
|
||||
* find the smallest element in the unsorted part
|
||||
* make it the first position which becomes the now last position of sorted part.
|
||||
|
||||
Diagram of parts:
|
||||
|
||||
* Initially, the entire array is all unsorted.
|
||||
* Over time the sorted elements stack up on the left.
|
||||
* Every time an element is moved, it is moved from the unsorted part (lowest element) and swapped with the element just after the end of the sorted part, making the sorted part one element bigger.
|
||||
* Eventually all elements are sorted in descending order.
|
||||
|
||||
Code:
|
||||
|
||||
```
|
||||
selection_sort(A){
|
||||
for(i=1 to n-1){
|
||||
// find min element of unsorted
|
||||
j=i-1 // j is index of min found so far.
|
||||
k=i
|
||||
while(k<n){
|
||||
if(A[k]<A[j]) j=k;
|
||||
k=k+1
|
||||
}
|
||||
swap A[i-1] and A[j]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Process of Selection Sort:
|
||||
|
||||
* Original: all unsorted
|
||||
* 5|4|2|6|1|3
|
||||
* Stage 1: [0] is sorted; 1 and 5 swap
|
||||
* 1|4|2|6|5|3
|
||||
* Stage 2: [0..1] is sorted; 2 and 4 swap
|
||||
* 1|2|4|6|5|3
|
||||
* Stage 3: [0..2] is sorted; 3 and 4 swap
|
||||
* 1|2|3|6|5|4
|
||||
* Stage 4: [0..3] is sorted; 4 and 6 swap
|
||||
* 1|2|3|4|5|6
|
||||
* Stage 5: [0..4] is sorted; annotation: s.t. s (final stage)
|
||||
* 1|2|3|4|5|6
|
||||
|
||||
## Heapsort (Selection Sort is crossed out)
|
||||
|
||||
* Initially sorted part empty
|
||||
* (highlighted) make unsorted part into a heap
|
||||
* repeat n-1 times
|
||||
* find the smallest element in the unsorted part (Note: heap extract takes log(n) time vs. Θ(n) for the scan in selection sort)
|
||||
* move it to the first position which becomes the new last position of the started part.
|
||||
|
||||
Consider the organization of array contents:
|
||||
|
||||
1. (Diagram of array with sorted half on the right and the unsorted half on the left.) A purple arrow points to the leftmost element in the unsorted portion. The note reads: "if this is the root of the heap, then it is also the smallest element in the unsorted part, so is in its correct final position.
|
||||
To use this arrangement, the root of the heap keeps moving, so we have lots of shifting to do."
|
||||
2. (A diagram showing the same array with sorted and unsorted halves.) A purple arrow points to the last element in the array; it points to a purple circle. A purple square is at the leftmost element of the unsorted half (the one discussed in the last item). The note reads: "If this is the root of the, then everything works:
|
||||
* We extract the final element (purple circle); move the last leaf (purple square) to the root + do a percolate-down;
|
||||
store the final element (purple circle) where the last element of the unsorted list (purple square) *was*,
|
||||
which is now free, and is the correct final location for the previously final element (purple circle); after which we have:
|
||||
* (Diagram of array with the "sorted" half extended one cell over to encompass the purple circle)
|
||||
* **But**: we must re-code our heap implementation s.t. the root is at A[n-1], with the result that the indexing is now less intuitive.
|
||||
3. Instead, we use a max-heap, and this arrangement:
|
||||
* (Diagram showcasing, as previously, a sorted half to the right and an unsorted half on the left. An orange circle labeled "root of heap" is the very first element of the list and the unsorted half; an orange square labeled "last leaf" sits at the end (rightmost side) of the unsorted half.)
|
||||
* The heap root is at A[0]
|
||||
* Heap Extraction remove the root of the heap (orange circle), moves the last leaf (orange square) to A[0],
|
||||
freeing up the spot where the root of the heap (orange circle) belongs.
|
||||
* This leaves us with: (Diagram of the orange circle near the middle of the array, at the leftmost portion of the sorted half. The orange square is in the center of the unsorted half.)
|
||||
* Re-coding a min heap into a max heap is just replacing < with > and vice versa.
|
||||
|
||||
## Heapsort (Selectioon Sort is crossed out)
|
||||
|
||||
* initially sorted part empty
|
||||
* (highlighted) make unsorted part into a max heap
|
||||
* repeat n-1 times:
|
||||
* find the largest (smallest is crossed out) element in the unsorted part
|
||||
* move it to the last (first is crossed out) position which becomes the new first (last is crossed out) position of the sorted part.
|
||||
|
||||
Code:
|
||||
|
||||
```
|
||||
heapsort(A){
|
||||
buildMaxHeap(A)
|
||||
for(i=1 to n-1){
|
||||
A[n-1] extractMax()
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Stages of sorting:
|
||||
|
||||
* (Diagram of unsorted array with first element labeled as "heap with max here".)
|
||||
* (Diagram of a half-sorted array showing the swap between the first and last elements of the unsorted portion of the array. Labeled as "take max element from root..." and "take last leaf from end of heap" with arrows pointing to one another.)
|
||||
* (Diagram of a half+1 sorted array, displaying the new sorted element that has been swapped from the root element of the heap. Labeled as "newest element of sorted part" and "this is the *final* location" (the new element just swapped), and "y new root of heap (which then gets percolated down)" (what is now the first element of the array, which was also just swapped).)
|
||||
|
||||
Unsorted heap of size 1 has smallest element.
|
||||
|
||||
## Heapsort with in-line percolate-down
|
||||
|
||||
Code:
|
||||
|
||||
```
|
||||
heapsort(A){
|
||||
makeMaxHeap(A)
|
||||
for(i=1 to n-1){
|
||||
swap A[0] and A[n-1] // move last leaf to root and old root to where last leaf was
|
||||
size <- n-i+1 // size of heap = size of unsorted part
|
||||
// start of percolate down
|
||||
j <- 0
|
||||
while(2j+1 < size){
|
||||
child <- 2j+1
|
||||
if(2j+2 < size AND A[2j+2] < A[2j+1]){
|
||||
child <- 2j+2
|
||||
}
|
||||
if(A[child]<A[j]){
|
||||
swap A[child] and A[j]
|
||||
j <- child
|
||||
} else {
|
||||
j <- size // termite the while
|
||||
}
|
||||
} // end of percolate down
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Heapsort Example
|
||||
|
||||
* Original:
|
||||
* 5|4|2|6|1|3
|
||||
* Turn into heap:
|
||||
* 6|5|3|4|1|2
|
||||
* Swap root (6) and last unsorted element (2):
|
||||
* 2|5|3|4|1|6
|
||||
* Re-heap the unsorted portion: [0..4]
|
||||
* 5|4|3|2|1|6
|
||||
* Swap root (5) and the last unsorted element (2):
|
||||
* 1|4|3|2|5|6
|
||||
* Re-heap the unsorted portion: [0..3]
|
||||
* 4|2|3|1|5|6
|
||||
* Swap root (4) and the last unsorted element (1):
|
||||
* 1|2|3|4|5|6
|
||||
* Re-heap unsorted portion: [0..2]
|
||||
* 3|2|1|4|5|6
|
||||
* Swap root (3) and last unsorted element (1):
|
||||
* 1|2|3|4|5|6
|
||||
* Re-heap unsorted portion: [0..1]
|
||||
* 2|1|3|4|5|6
|
||||
* Swap root (2) and last unsorted element (1):
|
||||
* 1|2|3|4|5|6
|
||||
* Array is sorted because unsorted portion is only 1 element.
|
||||
|
||||
Tree version of above (heap):
|
||||
|
||||
Original:
|
||||
|
||||
<!-- AUTO GENERATED FROM CUSTOM PYTHON CODE -->
|
||||
<ul role="tree">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span id="t11_5">
|
||||
5
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span id="t11_4">
|
||||
4
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span id="t11_6">
|
||||
6
|
||||
</span>
|
||||
</li>
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span id="t11_1">
|
||||
1
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span id="t11_2">
|
||||
2
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span id="t11_3">
|
||||
3 (left)
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<!-- END OF GENERATED CODE -->
|
||||
|
||||
After re-heap and one removal:
|
||||
|
||||
<!-- AUTO GENERATED FROM CUSTOM PYTHON CODE -->
|
||||
<ul role="tree">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span id="t0_2">
|
||||
2
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span id="t0_5">
|
||||
5
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span id="t0_2">
|
||||
2
|
||||
</span>
|
||||
</li>
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span id="t0_1">
|
||||
1
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span id="t0_3">
|
||||
3
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<!-- END OF GENERATED CODE -->
|
||||
|
||||
After a second re-heap and removal:
|
||||
|
||||
<!-- AUTO GENERATED FROM CUSTOM PYTHON CODE -->
|
||||
<ul role="tree">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span id="t0_1">
|
||||
1
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span id="t0_4">
|
||||
4
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span id="t0_2">
|
||||
2 (left)
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span id="t0_3">
|
||||
3
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<!-- END OF GENERATED CODE -->
|
||||
|
||||
After a third:
|
||||
|
||||
<!-- AUTO GENERATED FROM CUSTOM PYTHON CODE -->
|
||||
<ul role="tree">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span id="t0_1">
|
||||
1
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span id="t0_2">
|
||||
2
|
||||
</span>
|
||||
</li>
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span id="t0_3">
|
||||
3
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<!-- END OF GENERATED CODE -->
|
||||
|
||||
Examples stop here.
|
||||
|
||||
## Heapsort Example (2)
|
||||
|
||||
(Repeat same as above, except with different trees.)
|
||||
|
||||
Trees (Transcriber's note: these trees don't seem relavant to me.... but maybe I'm wrong):
|
||||
|
||||
<!-- AUTO GENERATED FROM CUSTOM PYTHON CODE -->
|
||||
<ul role="tree">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span id="t0_2">
|
||||
2 (crossed out with orange 5)
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span id="t0_5">
|
||||
5 (crossed out next to orange 2 which is also crossed out; an orange 4 is not crossed out)
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span id="t0_4">
|
||||
4 (crossed out with orange 2)
|
||||
</span>
|
||||
</li>
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span id="t0_1">
|
||||
1
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span id="t0_3">
|
||||
3
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<!-- END OF GENERATED CODE -->
|
||||
<!-- AUTO GENERATED FROM CUSTOM PYTHON CODE -->
|
||||
<ul role="tree">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span id="t0_1">
|
||||
1 (crossed out with an orange 4)
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span id="t0_4">
|
||||
4 (crossed out with orange 1, which is also crossed out; an orange 2, not crossed out is next to it)
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span id="t0_2">
|
||||
2 (left; crossed out with orange 1)
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span id="t0_3">
|
||||
3
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<!-- END OF GENERATED CODE -->
|
||||
<!-- AUTO GENERATED FROM CUSTOM PYTHON CODE -->
|
||||
<ul role="tree">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span id="t0_1">
|
||||
1 (orange 2)
|
||||
</span>
|
||||
<ul role="group">
|
||||
<li role="treeitem" tabindex="-1">
|
||||
<span id="t0_2">
|
||||
2 (left; orange 1)
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<!-- END OF GENERATED CODE -->
|
||||
|
||||
## Time Complexity of Iterative Sorting Algorithms
|
||||
|
||||
* each algorithm does exactly n-1 stages
|
||||
* the work done at the i<sup>th</sup> stage varies with the algorithm (& input).
|
||||
* we take # from item comparisons as a measure of work/time\*.
|
||||
|
||||
<dl>
|
||||
<dt>Selection Sort</dt>
|
||||
<dd>exactly n-i comparisons to find num element in unsorted part</dd>
|
||||
<dt>Insertion Sort</dt>
|
||||
<dd>between 1 and i comparisons to find location for pivot</dd>
|
||||
<dt>HeapSort</dt>
|
||||
<dd>between 1 and {% katex %}2\log_{2} (n-i-1){% endkatex %} comparisons for percolate-down</dd>
|
||||
</dl>
|
||||
|
||||
## \* Number of comparisons
|
||||
|
||||
* We must verify # comparisons (or some constant times # comparisons) is an upper bound on work done by each algorithm.
|
||||
* # of assignments (& swaps) also matters in actual run time.
|
||||
|
||||
## Selection Sort
|
||||
|
||||
On input of size n, # of comparisons is always (regardless of input):
|
||||
|
||||
{% katex display %}
|
||||
\begin{aligned}
|
||||
\sum_{i=1}^{n-1} (n-i) & = \sum_{i=1}^{n-1} i\\
|
||||
& = S(n-i)\\
|
||||
& = \frac{(n-1)(n)}{2}\\
|
||||
& = \frac{n^2 -n}{2}\\
|
||||
& = \Theta(n^2)
|
||||
\end{aligned}
|
||||
{% endkatex %}
|
||||
|
||||
## Insertion Sort -- Worst Case
|
||||
|
||||
Upper Bound: {% katex display %}\text{\# comparisons} \leq \sum_{i=1}^{n-1} i = \frac{n^{2} -n}{2} = O(n^{2}){% endkatex %}
|
||||
|
||||
Lower Bound:
|
||||
|
||||
* Worst case initial sequence is in reverse order. e.g.:
|
||||
* n|n-1|n-2|...|1
|
||||
* In the i<sup>th</sup> stage we have:
|
||||
* n-i+1|n-1+2|...|n|n-1|n-1-1|...|2|1
|
||||
* n-i|n-i+1|...|n-1|n|n-i-1|...|2|1
|
||||
* This takes i comparisons, because the sorted part is of size i.
|
||||
* So, {% katex display %}\text{\# comparisons} \leq \sum{i=1}^{n-1} = \Omega(n^{2}){% endkatex %}
|
||||
|
||||
So, insertion sort worst case is $$\Theta(n^{2})$$
|
||||
|
||||
(Transcriber's note: I'm fairly certain you can only use big-O notation when talking about worst case scenario, not Theta. But I'm leaving it as written.)
|
||||
|
||||
## Insertion Sort Best Case
|
||||
|
||||
Best case: initial sequence is fully ordered.
|
||||
|
||||
Then: In each stage, exactly 1 comparison is made.
|
||||
|
||||
So, {% katex %}\text{\# comparisons} = n-1 = \Theta(n){% endkatex %}.
|
||||
|
||||
## Heapsort Worst Case
|
||||
|
||||
Upper bound:
|
||||
|
||||
{% katex display %}
|
||||
\begin{aligned}
|
||||
\text{\# comparisons} & \leq \sum_{i=1}^{n-1} 2\log_{2} (n-i+1)\\
|
||||
& = 2\sum_{i=1}^{n-1} \log_{2} (i+1)\\
|
||||
& = \leq 2\sum_{i=1}^{n-1} \log_{2} n\\
|
||||
& = \leq 2n\log_{2} n\\
|
||||
& = O(n \log n)
|
||||
\end{aligned}
|
||||
{% endkatex %}
|
||||
|
||||
Lower Bound? (empty space)
|
||||
|
||||
Base Case? (What input would lead to **no** movement during percolate-down?
|
||||
What if we exclude this case?)
|
||||
|
||||
## Recursive Divide & Conquer Sorting
|
||||
|
||||
TODO
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,8 +0,0 @@
|
||||
---
|
||||
layout: simple
|
||||
math: true
|
||||
---
|
||||
|
||||
{% katex display %}
|
||||
0011_{2} \And 1110_{2} = 0010_{2}
|
||||
{% endkatex %}
|
Binary file not shown.
@ -1,22 +0,0 @@
|
||||
Title: Activity - Code
|
||||
|
||||
Video of CERT Secure Coding Initiative Conference 2015 - Robert C. Seacord
|
||||
|
||||
https://www.youtube.com/watch?v=1ew0GvB3NpE
|
||||
|
||||
Blue box with code in it:
|
||||
|
||||
char *copy (size_t n, const char *a) {
|
||||
if (n == 0) return NULL;
|
||||
if (a == NULL) return NULL;
|
||||
char *p = (char *)malloc(n);
|
||||
|
||||
if (p == NULL) return NULL;
|
||||
|
||||
for (int i = 0; i < n; i++) p[i] = *a++;
|
||||
|
||||
return p;
|
||||
|
||||
}
|
||||
|
||||
White text over-laying the blue box: Spot the defect
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
@ -1,97 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
|
||||
|
||||
typedef unsigned char *byte_pointer;
|
||||
|
||||
void show_bytes(byte_pointer start, size_t len) {
|
||||
int i;
|
||||
|
||||
for ( i = len-1; i >= 0; i--)
|
||||
printf(" %.2x", start[i]);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
||||
if ( argc < 2 ) {
|
||||
printf("Forgot the argment! Try again!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
short aShort = atoi(argv[1]);
|
||||
|
||||
printf("\nAs a short data type, the variable aShort has the value %hd (hex: 0x", aShort);
|
||||
show_bytes((byte_pointer) &aShort, sizeof(short));
|
||||
printf(")\n\n");
|
||||
|
||||
|
||||
/* Convert - size - implicitly */
|
||||
printf("Converting SIZE implicitly: short -> integer *** Sign extension ***\n");
|
||||
printf("This is done by issuing the statement: int anInt = aShort;\n");
|
||||
int anInt = aShort;
|
||||
printf("As a int data type, the variable anInt has the value %d (hex: 0x", anInt);
|
||||
show_bytes((byte_pointer) &anInt, sizeof(int));
|
||||
printf(")\n\n");
|
||||
|
||||
/* Convert - size - implicitly */
|
||||
printf("Converting SIZE implicitly: short -> char *** Truncation ***\n");
|
||||
printf("This is done by issuing the statement: signed char aChar = aShort;\n");
|
||||
signed char aChar = aShort;
|
||||
printf("As a char data type, the variable aChar has the value %hhi (hex: 0x", aChar);
|
||||
show_bytes((byte_pointer) &aChar, sizeof(signed char));
|
||||
printf(")\n\n");
|
||||
|
||||
/* Convert - sign - implicitly*/
|
||||
printf("Converting SIGN implicitly: short -> unsigned short\n");
|
||||
printf("This is done by issuing the statement: unsigned short aUShort = aShort;\n");
|
||||
unsigned short aUShort = aShort;
|
||||
printf("As an unsigned short data type, the variable aUShort has the value %hu (hex: 0x", aUShort);
|
||||
show_bytes((byte_pointer) &aUShort, sizeof(unsigned short));
|
||||
printf(")\n\n");
|
||||
|
||||
/* Convert - sign - implicitly*/
|
||||
printf("Converting SIGN implicitly: unsigned short -> short\n");
|
||||
printf("This is done by issuing the statement: short aShort1 = aUShort;\n");
|
||||
short aShort1 = aUShort;
|
||||
printf("As a signed short data type, the variable aShort1 has the value %hi (hex: 0x", (signed short) aShort1);
|
||||
show_bytes((byte_pointer) &aShort1, sizeof(signed short));
|
||||
printf(")\n\n");
|
||||
|
||||
/* Convert - both: 1) size, 2) sign */
|
||||
printf("Converting both SIZE and SIGN: short -> unsigned int\n");
|
||||
printf("This is done by issuing the statement: unsigned aUInt = aShort;\n");
|
||||
unsigned aUInt = aShort;
|
||||
printf("As an unsigned int data type, the variable aUInt has the value %u (hex: 0x", aUInt);
|
||||
show_bytes((byte_pointer) &aUInt, sizeof(unsigned));
|
||||
printf(")\n\n");
|
||||
|
||||
/* One step at a time */
|
||||
printf("One step at a time - First conversion is SIZE: (int) aShort = %d\n", (int) aShort);
|
||||
printf("One step at a time - Second conversion is SIGN: (unsigned) (int) aShort = %u\n\n", (unsigned) (int) aShort);
|
||||
|
||||
/* Reverse the process and see what happens ... */
|
||||
printf("What if ... First conversion is SIGN: (unsigned short) aShort = %hu\n", (unsigned short) aShort);
|
||||
printf("What if ... Second conversion is SIZE: (unsigned int) (unsigned short) aShort = %d\n\n", (unsigned int) (unsigned short) aShort);
|
||||
|
||||
/* Convert - both: 1) size, 2) sign */
|
||||
printf("Converting both SIZE and SIGN: short -> unsigned char\n");
|
||||
printf("This is done by issuing the statement: unsigned char anUChar = aShort;\n");
|
||||
unsigned char anUChar = aShort;
|
||||
printf("As an unsigned char data type, the variable anUChar has the value %hhu (hex: 0x", anUChar);
|
||||
show_bytes((byte_pointer) &anUChar, sizeof(unsigned char));
|
||||
printf(")\n\n");
|
||||
|
||||
/* One step at a time */
|
||||
printf("One step at a time - First conversion is SIZE: (signed char) aShort = %hhi\n", (signed char) aShort);
|
||||
printf("One step at a time - Second conversion is SIGN: (unsigned char) (signed char) aShort = %hhu\n\n", (unsigned char) (signed char) aShort);
|
||||
|
||||
/* Reverse the process and see what happens ... */
|
||||
printf("What if ... First conversion is SIGN: (unsigned short) aShort = %hu\n", (unsigned short) aShort);
|
||||
printf("What if ... Second conversion is SIZE: (unsigned char) (unsigned short) aShort = %hhu\n\n", (unsigned char) (unsigned short) aShort);
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
@ -1,81 +0,0 @@
|
||||
$ ./Demo 12345
|
||||
|
||||
As a short data type, the variable aShort has the value 12345 (hex: 0x 30 39)
|
||||
|
||||
Converting SIZE implicitly: short -> integer *** Sign extension ***
|
||||
This is done by issuing the statement: int anInt = aShort;
|
||||
As a int data type, the variable anInt has the value 12345 (hex: 0x 00 00 30 39)
|
||||
|
||||
Converting SIZE implicitly: short -> char *** Truncation ***
|
||||
This is done by issuing the statement: signed char aChar = aShort;
|
||||
As a char data type, the variable aChar has the value 57 (hex: 0x 39)
|
||||
|
||||
Converting SIGN implicitly: short -> unsigned short
|
||||
This is done by issuing the statement: unsigned short aUShort = aShort;
|
||||
As an unsigned short data type, the variable aUShort has the value 12345 (hex: 0x 30 39)
|
||||
|
||||
Converting SIGN implicitly: unsigned short -> short
|
||||
This is done by issuing the statement: short aShort1 = aUShort;
|
||||
As a signed short data type, the variable aShort1 has the value 12345 (hex: 0x 30 39)
|
||||
|
||||
Converting both SIZE and SIGN: short -> unsigned int
|
||||
This is done by issuing the statement: unsigned aUInt = aShort;
|
||||
As an unsigned int data type, the variable aUInt has the value 12345 (hex: 0x 00 00 30 39)
|
||||
|
||||
One step at a time - First conversion is SIZE: (int) aShort = 12345
|
||||
One step at a time - Second conversion is SIGN: (unsigned) (int) aShort = 12345
|
||||
|
||||
What if ... First conversion is SIGN: (unsigned short) aShort = 12345
|
||||
What if ... Second conversion is SIZE: (unsigned int) (unsigned short) aShort = 12345
|
||||
|
||||
Converting both SIZE and SIGN: short -> unsigned char
|
||||
This is done by issuing the statement: unsigned char anUChar = aShort;
|
||||
As an unsigned char data type, the variable anUChar has the value 57 (hex: 0x 39)
|
||||
|
||||
One step at a time - First conversion is SIZE: (signed char) aShort = 57
|
||||
One step at a time - Second conversion is SIGN: (unsigned char) (signed char) aShort = 57
|
||||
|
||||
What if ... First conversion is SIGN: (unsigned short) aShort = 12345
|
||||
What if ... Second conversion is SIZE: (unsigned char) (unsigned short) aShort = 57
|
||||
|
||||
----------------------------------------------------------------------------------------------
|
||||
|
||||
$ ./Demo -12345
|
||||
|
||||
As a short data type, the variable aShort has the value -12345 (hex: 0x cf c7)
|
||||
|
||||
Converting SIZE implicitly: short -> integer *** Sign extension ***
|
||||
This is done by issuing the statement: int anInt = aShort;
|
||||
As a int data type, the variable anInt has the value -12345 (hex: 0x ff ff cf c7)
|
||||
|
||||
Converting SIZE implicitly: short -> char *** Truncation ***
|
||||
This is done by issuing the statement: signed char aChar = aShort;
|
||||
As a char data type, the variable aChar has the value -57 (hex: 0x c7)
|
||||
|
||||
Converting SIGN implicitly: short -> unsigned short
|
||||
This is done by issuing the statement: unsigned short aUShort = aShort;
|
||||
As an unsigned short data type, the variable aUShort has the value 53191 (hex: 0x cf c7)
|
||||
|
||||
Converting SIGN implicitly: unsigned short -> short
|
||||
This is done by issuing the statement: short aShort1 = aUShort;
|
||||
As a signed short data type, the variable aShort1 has the value -12345 (hex: 0x cf c7)
|
||||
|
||||
Converting both SIZE and SIGN: short -> unsigned int
|
||||
This is done by issuing the statement: unsigned aUInt = aShort;
|
||||
As an unsigned int data type, the variable aUInt has the value 4294954951 (hex: 0x ff ff cf c7)
|
||||
|
||||
One step at a time - First conversion is SIZE: (int) aShort = -12345
|
||||
One step at a time - Second conversion is SIGN: (unsigned) (int) aShort = 4294954951
|
||||
|
||||
What if ... First conversion is SIGN: (unsigned short) aShort = 53191
|
||||
What if ... Second conversion is SIZE: (unsigned int) (unsigned short) aShort = 53191
|
||||
|
||||
Converting both SIZE and SIGN: short -> unsigned char
|
||||
This is done by issuing the statement: unsigned char anUChar = aShort;
|
||||
As an unsigned char data type, the variable anUChar has the value 199 (hex: 0x c7)
|
||||
|
||||
One step at a time - First conversion is SIZE: (signed char) aShort = -57
|
||||
One step at a time - Second conversion is SIGN: (unsigned char) (signed char) aShort = 199
|
||||
|
||||
What if ... First conversion is SIGN: (unsigned short) aShort = 53191
|
||||
What if ... Second conversion is SIZE: (unsigned char) (unsigned short) aShort = 199
|
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue