diff --git a/notes/.obsidian/plugins/obsidian-to-anki-plugin/data.json b/notes/.obsidian/plugins/obsidian-to-anki-plugin/data.json index 9d99430..40177ac 100644 --- a/notes/.obsidian/plugins/obsidian-to-anki-plugin/data.json +++ b/notes/.obsidian/plugins/obsidian-to-anki-plugin/data.json @@ -118,12 +118,13 @@ "max-heap-tree.png", "max-heap-array.png", "max-heapify-1.png", - "max-heapify-2.png" + "max-heapify-2.png", + "heapsort.gif" ], "File Hashes": { "algorithms/index.md": "3ac071354e55242919cc574eb43de6f8", "algorithms/sorting/index.md": "4a66e28bce754de5df31ec2f4aed7e93", - "algorithms/sorting/insertion-sort.md": "656c9f13dadb8dd663701ff673dd0ee1", + "algorithms/sorting/insertion-sort.md": "8bb3217cc3f49083d45a0095c667d176", "bash/index.md": "22083ea1ee9505cc96b02f82f63ba2c9", "bash/prompts.md": "cc51c210fa819338d4e95658955173df", "bash/quoting.md": "b1d8869a91001f8b22f0cdc54d806f61", @@ -164,7 +165,7 @@ "algorithms/running-time.md": "5efc0791097d2c996f931c9046c95f65", "algorithms/order-growth.md": "12bf6c10653912283921dcc46c7fa0f8", "_journal/2024-02-08.md": "19092bdfe378f31e2774f20d6afbfbac", - "algorithms/sorting/selection-sort.md": "0dc0b5237cf992e97b78f2584982fdbf", + "algorithms/sorting/selection-sort.md": "4c63541e8a886f17e4dc2b24215fefe8", "algorithms/index 1.md": "6fada1f3d5d3af64687719eb465a5b97", "binary/hexadecimal.md": "c3d485f1fd869fe600334ecbef7d5d70", "binary/index.md": "9089c6f0e86a0727cd03984f51350de0", @@ -172,7 +173,7 @@ "c/types.md": "cf3e66e5aee58a94db3fdf0783908555", "logic/quantification.md": "df25c9b73548438f010f450e3755d030", "c/declarations.md": "2de27f565d1020819008ae80593af435", - "algorithms/sorting/bubble-sort.md": "ed480530146aabe122f4dbf00cdacb09", + "algorithms/sorting/bubble-sort.md": "872fb23e41fb3ac36e8c46240e9a027f", "_journal/2024-02-10.md": "562b01f60ea36a3c78181e39b1c02b9f", "_journal/2024-01/2024-01-31.md": "7c7fbfccabc316f9e676826bf8dfe970", "_journal/2024-02/2024-02-09.md": "a798d35f0b2bd1da130f7ac766166109", @@ -205,7 +206,7 @@ "_journal/2024-02/2024-02-14.md": "aa009f9569e175a8104b0537ebcc5520", "_journal/2024-02-16.md": "5cc129254afd553829be3364facd23db", "_journal/2024-02/2024-02-15.md": "16cb7563d404cb543719b7bb5037aeed", - "algebra/floor-ceiling.md": "412e4fdc424cb17fd818688857c4b5b3", + "algebra/floor-ceiling.md": "aa89a485faeb7e71ef68da9200544184", "algebra/index.md": "90b842eb694938d87c7c68779a5cacd1", "algorithms/binary-search.md": "8533a05ea372e007ab4e8a36fd2772a9", "_journal/2024-02-17.md": "7c37cb10515ed3d2f5388eaf02a67048", @@ -375,14 +376,14 @@ "_journal/2024-04/2024-04-23.md": "20514052da91b06b979cacb3da758837", "_journal/2024-04-25.md": "10c98531cb90a6bc940ea7ae3342f98b", "_journal/2024-04/2024-04-24.md": "4cb04e0dea56e0b471fc0e428471a390", - "algorithms/heaps.md": "ed37002a7600a05794f668e092265522", + "algorithms/heaps.md": "9978cd8abebca41e8f123e0f8ea4c5c8", "_journal/2024-04-26.md": "3ce37236a9e09e74b547a4f7231df5f0", "_journal/2024-04/2024-04-25.md": "5a81123af29f8ebf0a0d28f820a3a52e", "_journal/2024-04-28.md": "46726bf76a594b987c63ba8b9b6d13d3", "_journal/2024-04/2024-04-27.md": "b0f3753821c232bf819b00fb49415bd0", "_journal/2024-04/2024-04-26.md": "3ce37236a9e09e74b547a4f7231df5f0", - "algorithms/sorting/heapsort.md": "e0d368882a8f33d2f42bd3ead4e3914d", - "_journal/2024-04-29.md": "7888f4e9497c9d8bd6f4aa759d9abc4d", + "algorithms/sorting/heapsort.md": "94ac936dac6c841b4d0c9b7df3eba0d3", + "_journal/2024-04-29.md": "f751826099e2c746605a4e562288d480", "_journal/2024-04/2024-04-28.md": "b34a9fe3bccb1f224b96ca00e78ad061", "programming/assertions.md": "bdef9b934d8db94169d6befbc02f33d2", "programming/text-sub.md": "003b8c32ae2f6767cb0d900f85196e67", diff --git a/notes/_journal/2024-04-29.md b/notes/_journal/2024-04-29.md index 8655198..9d32f56 100644 --- a/notes/_journal/2024-04-29.md +++ b/notes/_journal/2024-04-29.md @@ -11,4 +11,5 @@ title: "2024-04-29" - [x] Log Work Hours (Max 3 hours) * Notes on chapter 5.3 of "The Science of Programming". Covered nested arrays. -* Read chapter 6 of "The Science of Programming". Still need to convert into notes though. \ No newline at end of file +* Read chapter 6 of "The Science of Programming". Still need to convert into notes though. +* Finished notes on heaps and heapsort. \ No newline at end of file diff --git a/notes/algebra/floor-ceiling.md b/notes/algebra/floor-ceiling.md index d33bc59..f102ed7 100644 --- a/notes/algebra/floor-ceiling.md +++ b/notes/algebra/floor-ceiling.md @@ -218,31 +218,31 @@ END%% %%ANKI Basic -Given $r = \lfloor (p + q) / 2 \rfloor$, fair partitioning requires `A[r]` to be included in which of `A[p..r-1]` or `A[r+1..q]`? -Back: `A[p..r-1]` +Given $r = \lfloor (p + q) / 2 \rfloor$, fair partitioning requires `A[r]` to be included in which of `A[p:r-1]` or `A[r+1:q]`? +Back: `A[p:r-1]` Reference: Ronald L. Graham, Donald Ervin Knuth, and Oren Patashnik, *Concrete Mathematics: A Foundation for Computer Science*, 2nd ed (Reading, Mass: Addison-Wesley, 1994). END%% %%ANKI Basic -Given $r = \lfloor (p + q) / 2 \rfloor$, when is `A[p..r]` or `A[r+1..q]` equally sized? -Back: When `A[p..q]` has even size. +Given $r = \lfloor (p + q) / 2 \rfloor$, when is `A[p:r]` or `A[r+1:q]` equally sized? +Back: When `A[p:q]` has even size. Reference: Ronald L. Graham, Donald Ervin Knuth, and Oren Patashnik, *Concrete Mathematics: A Foundation for Computer Science*, 2nd ed (Reading, Mass: Addison-Wesley, 1994). END%% %%ANKI Basic -Given $r = \lceil (p + q) / 2 \rceil$, fair partitioning requires `A[r]` to be included in which of `A[p..r-1]` or `A[r+1..q]`? -Back: `A[r+1..q]` +Given $r = \lceil (p + q) / 2 \rceil$, fair partitioning requires `A[r]` to be included in which of `A[p:r-1]` or `A[r+1:q]`? +Back: `A[r+1:q]` Reference: Ronald L. Graham, Donald Ervin Knuth, and Oren Patashnik, *Concrete Mathematics: A Foundation for Computer Science*, 2nd ed (Reading, Mass: Addison-Wesley, 1994). END%% %%ANKI Basic -If `A[p..q]` has odd size, what `r` most fairly allows partitions `A[p..r]` and `A[r+1..q]`? +If `A[p:q]` has odd size, what `r` most fairly allows partitions `A[p:r]` and `A[r+1:q]`? Back: $r = (p + q) / 2$ Reference: Ronald L. Graham, Donald Ervin Knuth, and Oren Patashnik, *Concrete Mathematics: A Foundation for Computer Science*, 2nd ed (Reading, Mass: Addison-Wesley, 1994). @@ -250,7 +250,7 @@ END%% %%ANKI Basic -If `A[p..q]` has odd size, what `r` most fairly allows partitions `A[p..r-1]` and `A[r..q]`? +If `A[p:q]` has odd size, what `r` most fairly allows partitions `A[p:r-1]` and `A[r:q]`? Back: $r = (p + q) / 2$ Reference: Ronald L. Graham, Donald Ervin Knuth, and Oren Patashnik, *Concrete Mathematics: A Foundation for Computer Science*, 2nd ed (Reading, Mass: Addison-Wesley, 1994). @@ -258,7 +258,7 @@ END%% %%ANKI Basic -If `A[p..q]` has odd size, what `r` ensures `A[p..r-1]` has same size as `A[r+1..q]`? +If `A[p:q]` has odd size, what `r` ensures `A[p:r-1]` has same size as `A[r+1:q]`? Back: $r = (p + q) / 2$ Reference: Ronald L. Graham, Donald Ervin Knuth, and Oren Patashnik, *Concrete Mathematics: A Foundation for Computer Science*, 2nd ed (Reading, Mass: Addison-Wesley, 1994). @@ -266,7 +266,7 @@ END%% %%ANKI Basic -If `A[p..q]` has even size, what `r` most fairly allows partitions `A[p..r]` and `A[r+1..q]`? +If `A[p:q]` has even size, what `r` most fairly allows partitions `A[p:r]` and `A[r+1:q]`? Back: $r = \lfloor (p + q) / 2 \rfloor$ Reference: Ronald L. Graham, Donald Ervin Knuth, and Oren Patashnik, *Concrete Mathematics: A Foundation for Computer Science*, 2nd ed (Reading, Mass: Addison-Wesley, 1994). @@ -274,7 +274,7 @@ END%% %%ANKI Basic -If `A[p..q]` has even size, what `r` most fairly allows partitions `A[p..r-1]` and `A[r..q]`? +If `A[p:q]` has even size, what `r` most fairly allows partitions `A[p:r-1]` and `A[r:q]`? Back: $r = \lceil (p + q) / 2 \rceil$ Reference: Ronald L. Graham, Donald Ervin Knuth, and Oren Patashnik, *Concrete Mathematics: A Foundation for Computer Science*, 2nd ed (Reading, Mass: Addison-Wesley, 1994). @@ -282,7 +282,7 @@ END%% %%ANKI Basic -Given `A[p..q]` and $r = \lfloor (p + q) / 2 \rfloor$, how does the size of `A[p..r]` compare to `A[r+1..q]`? +Given `A[p:q]` and $r = \lfloor (p + q) / 2 \rfloor$, how does the size of `A[p:r]` compare to `A[r+1:q]`? Back: It either has zero or one more members. Reference: Ronald L. Graham, Donald Ervin Knuth, and Oren Patashnik, *Concrete Mathematics: A Foundation for Computer Science*, 2nd ed (Reading, Mass: Addison-Wesley, 1994). @@ -290,7 +290,7 @@ END%% %%ANKI Basic -Given `A[p..q]` and $r = \lfloor (p + q) / 2 \rfloor$, what is the size of `A[p..r]` in terms of $n = q - p + 1$? +Given `A[p:q]` and $r = \lfloor (p + q) / 2 \rfloor$, what is the size of `A[p:r]` in terms of $n = q - p + 1$? Back: $\lceil n / 2 \rceil$. Reference: Thomas H. Cormen et al., *Introduction to Algorithms*, 3rd ed (Cambridge, Mass: MIT Press, 2009). @@ -298,7 +298,7 @@ END%% %%ANKI Basic -Given `A[p..q]` and $r = \lfloor (p + q) / 2 \rfloor$, what is the size of `A[r+1..q]` in terms of $n = q - p + 1$? +Given `A[p:q]` and $r = \lfloor (p + q) / 2 \rfloor$, what is the size of `A[r+1:q]` in terms of $n = q - p + 1$? Back: $\lfloor n / 2 \rfloor$. Reference: Thomas H. Cormen et al., *Introduction to Algorithms*, 3rd ed (Cambridge, Mass: MIT Press, 2009). @@ -306,7 +306,7 @@ END%% %%ANKI Basic -Given `A[p..q]` and $r = \lceil (p + q) / 2 \rceil$, how does the size of `A[p..r-1]` compare to `A[r..q]`? +Given `A[p:q]` and $r = \lceil (p + q) / 2 \rceil$, how does the size of `A[p:r-1]` compare to `A[r:q]`? Back: It either has zero or one fewer members. Reference: Ronald L. Graham, Donald Ervin Knuth, and Oren Patashnik, *Concrete Mathematics: A Foundation for Computer Science*, 2nd ed (Reading, Mass: Addison-Wesley, 1994). @@ -314,7 +314,7 @@ END%% %%ANKI Basic -Given `A[p..q]` and $r = \lceil (p + q) / 2 \rceil$, what is the size of `A[r..q]` in terms of $n = q - p + 1$? +Given `A[p:q]` and $r = \lceil (p + q) / 2 \rceil$, what is the size of `A[r:q]` in terms of $n = q - p + 1$? Back: $\lceil n / 2 \rceil$. Reference: Thomas H. Cormen et al., *Introduction to Algorithms*, 3rd ed (Cambridge, Mass: MIT Press, 2009). @@ -322,7 +322,7 @@ END%% %%ANKI Basic -Given `A[p..q]` and $r = \lceil (p + q) / 2 \rceil$, what is the size of `A[p..r-1]` in terms of $n = q - p + 1$? +Given `A[p:q]` and $r = \lceil (p + q) / 2 \rceil$, what is the size of `A[p:r-1]` in terms of $n = q - p + 1$? Back: $\lfloor n / 2 \rfloor$. Reference: Thomas H. Cormen et al., *Introduction to Algorithms*, 3rd ed (Cambridge, Mass: MIT Press, 2009). @@ -330,7 +330,7 @@ END%% %%ANKI Basic -Given `A[p..q]` and $r = \lfloor (p + q) / 2 \rfloor$, how does the size of `A[p..r-1]` compare to `A[r..q]`? +Given `A[p:q]` and $r = \lfloor (p + q) / 2 \rfloor$, how does the size of `A[p:r-1]` compare to `A[r:q]`? Back: It either has one or two fewer members. Reference: Ronald L. Graham, Donald Ervin Knuth, and Oren Patashnik, *Concrete Mathematics: A Foundation for Computer Science*, 2nd ed (Reading, Mass: Addison-Wesley, 1994). @@ -338,7 +338,7 @@ END%% %%ANKI Basic -Given `A[p..q]` and $r = \lceil (p + q) / 2 \rceil$, how does the size of `A[p..r]` compare to `A[r+1..q]`? +Given `A[p:q]` and $r = \lceil (p + q) / 2 \rceil$, how does the size of `A[p:r]` compare to `A[r+1:q]`? Back: It either has one or two more members. Reference: Ronald L. Graham, Donald Ervin Knuth, and Oren Patashnik, *Concrete Mathematics: A Foundation for Computer Science*, 2nd ed (Reading, Mass: Addison-Wesley, 1994). @@ -346,8 +346,8 @@ END%% %%ANKI Basic -Given `A[p..q]` and $r = \lfloor (p + q) / 2 \rfloor$, *why* is the size of `A[p..r]` potentially larger than `A[r+1..q]`? -Back: If `A[p..q]` has odd size, `A[p..r]` contains the midpoint. +Given `A[p:q]` and $r = \lfloor (p + q) / 2 \rfloor$, *why* is the size of `A[p:r]` potentially larger than `A[r+1:q]`? +Back: If `A[p:q]` has odd size, `A[p:r]` contains the midpoint. Reference: Ronald L. Graham, Donald Ervin Knuth, and Oren Patashnik, *Concrete Mathematics: A Foundation for Computer Science*, 2nd ed (Reading, Mass: Addison-Wesley, 1994). END%% diff --git a/notes/algorithms/heaps.md b/notes/algorithms/heaps.md index 1fa10a2..65b3a62 100644 --- a/notes/algorithms/heaps.md +++ b/notes/algorithms/heaps.md @@ -1,10 +1,11 @@ --- title: Heaps TARGET DECK: Obsidian::STEM -FILE TAGS: algorithm::data_structure +FILE TAGS: data_structure::heap tags: - algorithm - data_structure + - heap --- ## Overview @@ -13,6 +14,37 @@ The **binary heap** data structure is an array object that can be viewed as a [[ The primary function used to maintain the max-heap property is `MAX_HEAPIFY_DOWN`. This function assumes the left and right- subtrees at a given node are max heaps but that the current node may be smaller than its children. An analagous function and assumptions exist for `MIN_HEAPIFY_DOWN`. +```c +inline int left_child(int i) { return (i << 1) + 1; } +inline int right_child(int i) { return (i << 1) + 2; } + +void max_heapify_down(int n, int H[static n], int i) { + while (true) { + int lc = left_child(i); + int rc = right_child(i); + int next = i; + + if (lc < n && H[next] < H[lc]) { + next = lc; + } + if (rc < n && H[next] < H[rc]) { + next = rc; + } + if (next == i) { + return; + } + swap(H, i, next); + i = next; + } +} + +void build_max_heap(int n, int H[static n]) { + for (int i = n / 2 - 1; i >= 0; --i) { + max_heapify_down(n, H, i); + } +} +``` + %%ANKI Cloze A binary heap is an {array} that can be viewed as a {binary tree}. @@ -321,8 +353,8 @@ END%% %%ANKI Basic -Given heap $H[0{..}n{-}1]$, what is `BUILD_MAX_HEAP`'s loop invariant? -Back: Each node in $H[i{+}1{..}n{-}1]$ is the root of a max-heap. +Given heap `H[0:n-1]`, what is `BUILD_MAX_HEAP`'s loop invariant? +Back: Each node in `H[i+1:n-1]` is the root of a max-heap. Reference: Thomas H. Cormen et al., Introduction to Algorithms, Fourth edition (Cambridge, Massachusett: The MIT Press, 2022). END%% @@ -400,8 +432,8 @@ END%% %%ANKI Basic -Given heap $H[0{..}n{-}1]$, what is `BUILD_MIN_HEAP`'s loop invariant? -Back: Each node in $H[i{+}1{..}n{-}1]$ is the root of a min-heap. +Given heap `H[0:n-1]`, what is `BUILD_MIN_HEAP`'s loop invariant? +Back: Each node in `H[i+1:n-1]` is the root of a min-heap. Reference: Thomas H. Cormen et al., Introduction to Algorithms, Fourth edition (Cambridge, Massachusett: The MIT Press, 2022). END%% @@ -437,6 +469,14 @@ Reference: Thomas H. Cormen et al., Introduction to Algorithms, Fourth edition ( END%% +%%ANKI +Basic +`BUILD_MIN_HEAP` can sort arrays of what sizes? +Back: $\leq 2$ +Reference: Thomas H. Cormen et al., Introduction to Algorithms, Fourth edition (Cambridge, Massachusett: The MIT Press, 2022). + +END%% + ## Bibliography * Thomas H. Cormen et al., Introduction to Algorithms, Fourth edition (Cambridge, Massachusett: The MIT Press, 2022). \ No newline at end of file diff --git a/notes/algorithms/sorting/bubble-sort.md b/notes/algorithms/sorting/bubble-sort.md index 4e91301..9edf8bd 100644 --- a/notes/algorithms/sorting/bubble-sort.md +++ b/notes/algorithms/sorting/bubble-sort.md @@ -134,21 +134,21 @@ END%% Consider [[loop-invariant|loop invariant]] $P$ given by -> `A[0..i-1]` is a sorted array of the `i` least elements of `A`. +> `A[0:i-1]` is a sorted array of the `i` least elements of `A`. We prove $P$ maintains the requisite properties: * Initialization - * When `i = 0`, `A[0..-1]` is an empty array. This trivially satisfies $P$. + * When `i = 0`, `A[0:-1]` is an empty array. This trivially satisfies $P$. * Maintenance - * Suppose $P$ holds for some `0 ≤ i < n - 1`. Then `A[0..i-1]` is a sorted array of the `i` least elements of `A`. Our inner loop now starts at the end of the array and swaps each adjacent pair, putting the smaller of the two closer to position `i`. Repeating this process across all pairs from `n - 1` to `i + 1` ensures `A[i]` is the smallest element of `A[i..n-1]`. Therefore `A[0..i]` is a sorted array of the `i + 1` least elements of `A`. At the end of the iteration, `i` is incremented meaning `A[0..i-1]` still satisfies $P$. + * Suppose $P$ holds for some `0 ≤ i < n - 1`. Then `A[0:i-1]` is a sorted array of the `i` least elements of `A`. Our inner loop now starts at the end of the array and swaps each adjacent pair, putting the smaller of the two closer to position `i`. Repeating this process across all pairs from `n - 1` to `i + 1` ensures `A[i]` is the smallest element of `A[i:n-1]`. Therefore `A[0:i]` is a sorted array of the `i + 1` least elements of `A`. At the end of the iteration, `i` is incremented meaning `A[0:i-1]` still satisfies $P$. * Termination - * Termination happens when `i = n - 1`. Then $P$ implies `A[0..n-2]` is a sorted array of the `n - 1` least elements of `A`. But then `A[n-1]` must be the greatest element of `A` meaning `A[0..n-1]`, the entire array, is in sorted order. + * Termination happens when `i = n - 1`. Then $P$ implies `A[0:n-2]` is a sorted array of the `n - 1` least elements of `A`. But then `A[n-1]` must be the greatest element of `A` meaning `A[0:n-1]`, the entire array, is in sorted order. %%ANKI Basic -Given array `A[0..n-1]`, what is `BUBBLE_SORT`'s loop invariant? -Back: `A[0..i-1]` is a sorted array of the `i` least elements of `A`. +Given array `A[0:n-1]`, what is `BUBBLE_SORT`'s loop invariant? +Back: `A[0:i-1]` is a sorted array of the `i` least elements of `A`. Reference: Thomas H. Cormen et al., Introduction to Algorithms, Fourth edition (Cambridge, Massachusett: The MIT Press, 2022). END%% diff --git a/notes/algorithms/sorting/heapsort.md b/notes/algorithms/sorting/heapsort.md index 7d6015d..3a4c273 100644 --- a/notes/algorithms/sorting/heapsort.md +++ b/notes/algorithms/sorting/heapsort.md @@ -1,64 +1,196 @@ --- title: Heapsort TARGET DECK: Obsidian::STEM -FILE TAGS: algorithm::sorting +FILE TAGS: algorithm::sorting data_structure::heap tags: - algorithm + - heap - sorting --- ## Overview -Property | Value ------------ | -------- -Best Case | - -Worst Case | - -Avg. Case | - -Aux. Memory | - -Stable | - -Adaptive | - +| Property | Value | +| ----------- | ------------ | +| Best Case | $O(n)$ | +| Worst Case | $O(n\lg{n})$ | +| Avg. Case | $O(n\lg{n})$ | +| Aux. Memory | $O(1)$ | +| Stable | No | +| Adaptive | Yes | ![[heapsort.gif]] +%%ANKI +Basic +Describe `HEAPSORT` in a single sentence. +Back: Build a heap and then repeatedly extract the max to create a sorted array. +Reference: Thomas H. Cormen et al., Introduction to Algorithms, Fourth edition (Cambridge, Massachusett: The MIT Press, 2022). + +END%% + +%%ANKI +Basic +What is `HEAPSORT`'s best case runtime? +Back: $\Omega(n)$ +Reference: “Heapsort.” In _Wikipedia_, April 27, 2024. [https://en.wikipedia.org/w/index.php?title=Heapsort&oldid=1220986714](https://en.wikipedia.org/w/index.php?title=Heapsort&oldid=1220986714). + +END%% + +%%ANKI +Basic +What input produces `HEAPSORT`'s best case runtime? +Back: An array of equal keys. +Reference: Thomas H. Cormen et al., Introduction to Algorithms, Fourth edition (Cambridge, Massachusett: The MIT Press, 2022). + +END%% + +%%ANKI +Basic +What is `HEAPSORT`'s worst case runtime? +Back: $O(n\lg{n})$ +Reference: Thomas H. Cormen et al., Introduction to Algorithms, Fourth edition (Cambridge, Massachusett: The MIT Press, 2022). + +END%% + +%%ANKI +Basic +What is `HEAPSORT`'s average case runtime? +Back: $O(n\lg{n})$ +Reference: Thomas H. Cormen et al., Introduction to Algorithms, Fourth edition (Cambridge, Massachusett: The MIT Press, 2022). + +END%% + +%%ANKI +Basic +Is `HEAPSORT` in place? +Back: Yes. +Reference: Thomas H. Cormen et al., Introduction to Algorithms, Fourth edition (Cambridge, Massachusett: The MIT Press, 2022). + +END%% + +%%ANKI +Basic +Is `HEAPSORT` stable? +Back: No. +Reference: Thomas H. Cormen et al., Introduction to Algorithms, Fourth edition (Cambridge, Massachusett: The MIT Press, 2022). + +END%% + +%%ANKI +Basic +*Why* does `HEAPSORT` have $O(n\lg{n})$ runtime? +Back: Because `BUILD_MAX_HEAP` runs in $O(n)$ time and `MAX_HEAPIFY_DOWN` runs in $O(\lg{n})$ time. +Reference: Thomas H. Cormen et al., Introduction to Algorithms, Fourth edition (Cambridge, Massachusett: The MIT Press, 2022). + +END%% + +%%ANKI +Basic +What sorting algorithm does the following demonstrate? +![[heapsort.gif]] +Back: `HEAPSORT` +Reference: Thomas H. Cormen et al., Introduction to Algorithms, Fourth edition (Cambridge, Massachusett: The MIT Press, 2022). + +END%% + ```c -inline int left_child(int i) { return (i << 1) + 1; } -inline int right_child(int i) { return (i << 1) + 2; } - -void max_heapify(int n, int H[static n], int i) { - while (true) { - int lc = left_child(i); - int rc = right_child(i); - int next = i; - - if (lc < n && H[next] < H[lc]) { - next = lc; - } - if (rc < n && H[next] < H[rc]) { - next = rc; - } - if (next == i) { - return; - } - swap(H, i, next); - i = next; - } -} - -void build_max_heap(int n, int H[static n]) { - for (int i = n / 2 - 1; i >= 0; --i) { - max_heapify(n, H, i); - } -} - void heapsort(int n, int H[static n]) { build_max_heap(n, H); while (n > 1) { swap(A, 0, --n); - max_heapify(n, A, 0); + max_heapify_down(n, A, 0); } } ``` +Refer to [[heaps]] for implementations of `build_max_heap` and `max_heapify_down`. + +%%ANKI +Basic +Which element will `HEAPSORT` move to `sorted`? +``` +[ heap | sorted ] +``` +Back: The first element in `heap`. +Reference: Thomas H. Cormen et al., Introduction to Algorithms, Fourth edition (Cambridge, Massachusett: The MIT Press, 2022). + +END%% + +%%ANKI +Basic +How are elements of the following moved in an iteration of `HEAPSORT`? +``` +[ heap | sorted ] +``` +Back: The last element of `heap` is swapped with the first. +Reference: Thomas H. Cormen et al., Introduction to Algorithms, Fourth edition (Cambridge, Massachusett: The MIT Press, 2022). + +END%% + +%%ANKI +Cloze +{`HEAPSORT`} is {`SELECTION_SORT`} using the right data structure. +Reference: “Heapsort.” In _Wikipedia_, April 27, 2024. [https://en.wikipedia.org/w/index.php?title=Heapsort&oldid=1220986714](https://en.wikipedia.org/w/index.php?title=Heapsort&oldid=1220986714). + +END%% + +%%ANKI +Basic +What improvement does `HEAPSORT` introduce to `SELECTION_SORT`? +Back: `HEAPSORT` avoids linear scanning by keeping unsorted elements in a heap. +Reference: “Heapsort.” In _Wikipedia_, April 27, 2024. [https://en.wikipedia.org/w/index.php?title=Heapsort&oldid=1220986714](https://en.wikipedia.org/w/index.php?title=Heapsort&oldid=1220986714). + +END%% + +%%ANKI +Basic +What are the two high-level steps taken in `HEAPSORT`? +Back: Heap construction and heap extraction. +Reference: “Heapsort.” In _Wikipedia_, April 27, 2024. [https://en.wikipedia.org/w/index.php?title=Heapsort&oldid=1220986714](https://en.wikipedia.org/w/index.php?title=Heapsort&oldid=1220986714). + +END%% + +## Loop Invariant + +Consider [[loop-invariant|loop invariant]] $P$ given by + +> `A[0:i-1]` is a max-heap containing the `i` smallest elements of `A`. `A[i:n-1]` contains the `n - i` largest elements of `A` sorted. + +We prove $P$ maintains the requisite properties: + +* Initialization + * `A[0:n-1]` is a max-heap and `A[n:n-1]` is empty. +* Maintenance + * On each iteration, `A[0]` is swapped with `A[i-1]`. `A[0]` is originally the largest element of the max-heap and is smaller than the elements of `A[i:n-1]`. Thus `A[i-1:n-1]` is in sorted order. Decrementing `i`, decrementing the heap size, and invoking `MAX_HEAPIFY_DOWN` on `A[0]` fixes the max-heap property of `A[0:i-1]`. +* Termination + * We terminate when `i = 1`. Since `A[0:1]` is a max-heap, it follows `A[0] < A[1]`. Furthermore, `A[2:n-1]` are the largest `n - 2` elements of `A` in sorted order. Thus `A` is sorted. + +%%ANKI +Basic +Given array `A[0:n-1]`, what two properties make up `HEAPSORT`'s loop invariant? +Back: `A[0:i-1]` is a max-heap of the `i` smallest elements. `A[i+1:n]` contains the `n - i` largest elements sorted. +Reference: Thomas H. Cormen et al., Introduction to Algorithms, Fourth edition (Cambridge, Massachusett: The MIT Press, 2022). + +END%% + +%%ANKI +Basic +What is initialization of `HEAPSORT`'s loop invariant? +Back: `A` is a max-heap. +Reference: Thomas H. Cormen et al., Introduction to Algorithms, Fourth edition (Cambridge, Massachusett: The MIT Press, 2022). + +END%% + +%%ANKI +Basic +What is maintenance of `HEAPSORT`'s loop invariant? +Back: Each iteration puts the next largest element in sorted order and then heapifies the remaining elements again. +Reference: Thomas H. Cormen et al., Introduction to Algorithms, Fourth edition (Cambridge, Massachusett: The MIT Press, 2022). + +END%% + ## Bibliography -* Thomas H. Cormen et al., Introduction to Algorithms, Fourth edition (Cambridge, Massachusett: The MIT Press, 2022). \ No newline at end of file +* “Heapsort.” In _Wikipedia_, April 27, 2024. [https://en.wikipedia.org/w/index.php?title=Heapsort&oldid=1220986714](https://en.wikipedia.org/w/index.php?title=Heapsort&oldid=1220986714). +* Thomas H. Cormen et al., Introduction to Algorithms, Fourth edition (Cambridge, Massachusett: The MIT Press, 2022). diff --git a/notes/algorithms/sorting/insertion-sort.md b/notes/algorithms/sorting/insertion-sort.md index 0b75c6e..fd9b572 100644 --- a/notes/algorithms/sorting/insertion-sort.md +++ b/notes/algorithms/sorting/insertion-sort.md @@ -118,21 +118,22 @@ END%% Consider [[loop-invariant|loop invariant]] $P$ given by -> `A[0..i-1]` consists of the original `A[0..i-1]` elements but in sorted order. +> `A[0:i-1]` consists of the original `A[0:i-1]` elements but in sorted order. We prove $P$ maintains the requisite properties: * Initialization - * When `i = 1`, `A[0..0]` contains a single element. This trivially satisfies $P$. + * When `i = 1`, `A[0:0]` contains a single element. This trivially satisfies $P$. * Maintenance - * Suppose $P$ holds for some `1 ≤ i < n`. Then `A[0..i-1]` consists of the original `A[0..i-1]` elements but in sorted order. On iteration `i + 1`, the nested for loop puts `A[0..i]` in sorted order. At the end of the iteration, `i` is incremented meaning `A[0..i-1]` still satisfies $P$. + * Suppose $P$ holds for some `1 ≤ i < n`. Then `A[0:i-1]` consists of the original `A[0:i-1]` elements but in sorted order. On iteration `i + 1`, the nested for loop puts `A[0:i]` in sorted order. At the end of the iteration, `i` is incremented meaning `A[0:i-1]` still satisfies $P$. * Termination - * The loop ends because `i < n` is no longer true. Then `i = n`. Since $P$ holds, this means `A[0..n-1]`, the entire array, is in sorted order. + * The loop ends because `i < n` is no longer true. Then `i = n`. Since $P$ holds, this means `A[0:n-1]`, the entire array, is in sorted order. %%ANKI Basic -Given array `A[0..n-1]`, what is `INSERTION_SORT`'s loop invariant? -Back: `A[0..i-1]` consists of the original `A[0..i-1]` elements but in sorted order. +Given array `A[0:n-1]`, what is `INSERTION_SORT`'s loop invariant? +Back: `A[0:i-1]` consists of the original `A[0:i-1]` elements but in sorted order. +Reference: Thomas H. Cormen et al., Introduction to Algorithms, Fourth edition (Cambridge, Massachusett: The MIT Press, 2022). END%% diff --git a/notes/algorithms/sorting/selection-sort.md b/notes/algorithms/sorting/selection-sort.md index 01b688b..0f9dba8 100644 --- a/notes/algorithms/sorting/selection-sort.md +++ b/notes/algorithms/sorting/selection-sort.md @@ -110,21 +110,21 @@ END%% Consider [[loop-invariant|loop invariant]] $P$ given by -> `A[0..i-1]` is a sorted array of the `i` least elements of `A`. +> `A[0:i-1]` is a sorted array of the `i` least elements of `A`. We prove $P$ maintains the requisite properties: * Initialization - * When `i = 0`, `A[0..-1]` is an empty array. This trivially satisfies $P$. + * When `i = 0`, `A[0:-1]` is an empty array. This trivially satisfies $P$. * Maintenance - * Suppose $P$ holds for some `0 ≤ i < n - 1`. Then `A[0..i-1]` is a sorted array of the `i` least elements of `A`. Our inner loop then finds the smallest element in `A[i..n]` and swaps it with `A[i]`. Therefore `A[0..i]` is a sorted array of the `i + 1` least elements of `A`. At the end of the iteration, `i` is incremented meaning `A[0..i-1]` still satisfies $P$. + * Suppose $P$ holds for some `0 ≤ i < n - 1`. Then `A[0:i-1]` is a sorted array of the `i` least elements of `A`. Our inner loop then finds the smallest element in `A[i:n]` and swaps it with `A[i]`. Therefore `A[0:i]` is a sorted array of the `i + 1` least elements of `A`. At the end of the iteration, `i` is incremented meaning `A[0:i-1]` still satisfies $P$. * Termination - * On termination, `i = n - 1` and `A[0..n-2]` are the `n - 1` least elements of `A` in sorted order. But, by exhaustion, `A[n-1]` must be the largest element meaning `A[0..n-1]`, the entire array, is in sorted order. + * On termination, `i = n - 1` and `A[0:n-2]` are the `n - 1` least elements of `A` in sorted order. But, by exhaustion, `A[n-1]` must be the largest element meaning `A[0:n-1]`, the entire array, is in sorted order. %%ANKI Basic -Given array `A[0..n-1]`, what is `SELECTION_SORT`'s loop invariant? -Back: `A[0..i-1]` is a sorted array of the `i` least elements of `A`. +Given array `A[0:n-1]`, what is `SELECTION_SORT`'s loop invariant? +Back: `A[0:i-1]` is a sorted array of the `i` least elements of `A`. Reference: Thomas H. Cormen et al., Introduction to Algorithms, Fourth edition (Cambridge, Massachusett: The MIT Press, 2022). END%%