Angorithm4 Webinar #5
Host by Jiawei Wang 2021-11-19
1. Review Interpreter vs. Compiler
i. Interpreter == Virtual Machine
- There is no “Interpreted language” or “Compiled language”
- Just layer-by-layer interpret (running in the Virtual machine)
- Interpret means just update the state of this machine (Turing Machine)
- Finally interprete at the real-machine –> CPU
ii. Static Time
iii. Runtime
1. Stack-based VM
# stack contents (leftmost = top = most recent):
push A # A
push B # B A
push C # C B A
subtract # B-C A
multiply # A*(B-C)
push D # D A*(B-C)
push E # E D A*(B-C)
add # D+E A*(B-C)
add # A*(B-C)+(D+E)
public class JavaBytecode {
public static void main(String[] args) {
int x = 15;
System.out.println(x + 10 - 5);
}
};
Compiled from "JavaBytecode.java"
public class JavaBytecode {
public JavaBytecode();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: bipush 15
2: istore_1
3: getstatic #7 // Field java/lang/System.out:Ljava/io/PrintStream;
6: iload_1
7: bipush 10
9: iadd
10: iconst_5
11: isub
12: invokevirtual #13 // Method java/io/PrintStream.println:(I)V
15: return
}
2. Register-based VM (Real-CPU)
#include <stdio.h>
int main() {
int x = 15;
("%i", x);
printf}
section __TEXT,__text,regular,pure_instructions
., 11, 0 sdk_version 12, 0
.build_version macos## -- Begin function main
.globl _main 4, 0x90
.p2align _main: ## @main
.cfi_startproc.0:
## %bb%rbp
pushq 16
.cfi_def_cfa_offset %rbp, -16
.cfi_offset movq %rsp, %rbp
%rbp
.cfi_def_cfa_register $16, %rsp
subq $15, -4(%rbp)
movl -4(%rbp), %esi
movl .str(%rip), %rdi
leaq L_$0, %al
movb
callq _printf%eax, %eax
xorl $16, %rsp
addq %rbp
popq
retq
.cfi_endprocEnd function
## -- section __TEXT,__cstring,cstring_literals
.L_.str: ## @.str
"%i"
.asciz
.subsections_via_symbols
The Deeper, the faster!
2. Comparision Sort(III) - Heap Sort
i. Heap
- Heap is a special “Piority Queue”
- Heap is a Complete Binary Tree
- The value of each node must be no greater than (or no less than) the value of its child nodes.
void MaxHeaptify(vector<int>& A, int root, int length) {
// complete binary tree
int left = 2*root;
int right = 2*root + 1;
int largest;
if (left <= length && A[left] > A[root]) {
= left;
largest } else {
= root;
largest }
if (right <= length && A[right] > A[largest]) {
= right;
largest }
if (largest != root) {
// we need to update the subtree
(A[root], A[largest]);
swap(A, largest, length);
MaxHeaptify}
}
void BuildMaxHeap(vector<int>& A) {
// from the last parent node to root
for (int i = (int)A.size()/2; i >= 1; i--) {
(A, i, (int)A.size()-1);
MaxHeaptify}
}
ii. Heap Sort
void HeapSort(vector<int>& A) {
.insert(A.begin(), 0);
A(A);
BuildMaxHeap
int size = (int)A.size() - 1;
for (int i = (int)A.size()-1; i >= 2; i--) {
(A[1], A[i]);
swap--; // key
size(A, 1, size);
MaxHeaptify}
.erase(A.begin());
A}
iii. Time Complexity Analysis
Worse-case analysis:
BuildMaxHeap()
– O(N)MaxHeaptify()
– O(logN) (h)HeapSort()
– O(NlogN)
iv. Application (Example)
class Solution {
public int findKthLargest(int[] nums, int k) {
// init heap 'the smallest element first'
<Integer> heap =
PriorityQueuenew PriorityQueue<Integer>((n1, n2) -> n1 - n2);
// keep k largest elements in the heap
for (int n: nums) {
.add(n);
heapif (heap.size() > k)
.poll();
heap}
// output
return heap.poll();
}
}
3. Lower Bounds of Comparision Sort
1. Is O(NlogN) the best we can do?
N! <= 2^h
->h >= log(N!)
>= log(N/e)^N = Nlog(N/e) = NlogN - Nloge
=
O(NlogN)