This commit is contained in:
krahets
2026-04-02 03:08:50 +08:00
parent 09a136c9fa
commit aaf9f58eb3
157 changed files with 3002 additions and 2994 deletions
+31 -31
View File
@@ -6,7 +6,7 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="description" content="Data Structures and Algorithms Crash Course with Animated Illustrations and Off-the-Shelf Code">
<meta name="description" content="Data structures and algorithms tutorial with animated illustrations and ready-to-run code">
<meta name="author" content="krahets">
@@ -576,7 +576,7 @@
<span class="md-ellipsis">
Chapter 1. Encounter With Algorithms
Chapter 1. Encounter with Algorithms
@@ -598,7 +598,7 @@
<span class="md-nav__icon md-icon"></span>
Chapter 1. Encounter With Algorithms
Chapter 1. Encounter with Algorithms
</label>
@@ -1183,7 +1183,7 @@
<span class="md-ellipsis">
Chapter 4. Array and Linked List
Chapter 4. Arrays and Linked Lists
@@ -1205,7 +1205,7 @@
<span class="md-nav__icon md-icon"></span>
Chapter 4. Array and Linked List
Chapter 4. Arrays and Linked Lists
</label>
@@ -1311,7 +1311,7 @@
<span class="md-ellipsis">
4.4 Memory and Cache *
4.4 Random-Access Memory and Cache *
@@ -1402,7 +1402,7 @@
<span class="md-ellipsis">
Chapter 5. Stack and Queue
Chapter 5. Stacks and Queues
@@ -1424,7 +1424,7 @@
<span class="md-nav__icon md-icon"></span>
Chapter 5. Stack and Queue
Chapter 5. Stacks and Queues
</label>
@@ -1502,7 +1502,7 @@
<span class="md-ellipsis">
5.3 Double-Ended Queue
5.3 Deque
@@ -1593,7 +1593,7 @@
<span class="md-ellipsis">
Chapter 6. Hashing
Chapter 6. Hash Table
@@ -1615,7 +1615,7 @@
<span class="md-nav__icon md-icon"></span>
Chapter 6. Hashing
Chapter 6. Hash Table
</label>
@@ -1888,7 +1888,7 @@
<span class="md-ellipsis">
7.3 Array Representation of Tree
7.3 Array Representation of Binary Trees
@@ -2107,7 +2107,7 @@
<span class="md-ellipsis">
8.2 Building a Heap
8.2 Heap Construction Operation
@@ -2135,7 +2135,7 @@
<span class="md-ellipsis">
8.3 Top-K Problem
8.3 Top-k Problem
@@ -2565,7 +2565,7 @@
<span class="md-ellipsis">
10.2 Binary Search Insertion
10.2 Binary Search Insertion Point
@@ -2593,7 +2593,7 @@
<span class="md-ellipsis">
10.3 Binary Search Edge Cases
10.3 Binary Search Boundaries
@@ -2649,7 +2649,7 @@
<span class="md-ellipsis">
10.5 Search Algorithms Revisited
10.5 Searching Algorithms Revisited
@@ -2798,7 +2798,7 @@
<span class="md-ellipsis">
11.1 Sorting Algorithms
11.1 Sorting Algorithm
@@ -3271,7 +3271,7 @@
<span class="md-ellipsis">
12.4 Hanoi Tower Problem
12.4 Hanota Problem
@@ -4183,7 +4183,7 @@
<span class="md-ellipsis">
16.3 Terminology Table
16.3 Glossary
@@ -4357,7 +4357,7 @@
<!-- Page content -->
<h1 id="101-binary-search">10.1 &nbsp; Binary Search<a class="headerlink" href="#101-binary-search" title="Permanent link">&para;</a></h1>
<p><u>Binary search</u> is an efficient searching algorithm based on the divide-and-conquer strategy. It leverages the orderliness of data to reduce the search range by half in each round until the target element is found or the search interval becomes empty.</p>
<p><u>Binary search</u> is an efficient search algorithm based on the divide-and-conquer strategy. It leverages the sorted order of the data to reduce the search range by half in each round until the target element is found or the search interval becomes empty.</p>
<div class="admonition question">
<p class="admonition-title">Question</p>
<p>Given an array <code>nums</code> of length <span class="arithmatex">\(n\)</span> with elements arranged in ascending order and no duplicates, search for and return the index of element <code>target</code> in the array. If the array does not contain the element, return <span class="arithmatex">\(-1\)</span>. An example is shown in Figure 10-1.</p>
@@ -4376,7 +4376,7 @@
</ol>
</li>
</ol>
<p>If the array does not contain the target element, the search interval will eventually shrink to empty. In this case, return <span class="arithmatex">\(-1\)</span>.</p>
<p>If the array does not contain the target element, the search interval will eventually become empty. In this case, return <span class="arithmatex">\(-1\)</span>.</p>
<div class="tabbed-set tabbed-alternate" data-tabs="1:7"><input checked="checked" id="__tabbed_1_1" name="__tabbed_1" type="radio" /><input id="__tabbed_1_2" name="__tabbed_1" type="radio" /><input id="__tabbed_1_3" name="__tabbed_1" type="radio" /><input id="__tabbed_1_4" name="__tabbed_1" type="radio" /><input id="__tabbed_1_5" name="__tabbed_1" type="radio" /><input id="__tabbed_1_6" name="__tabbed_1" type="radio" /><input id="__tabbed_1_7" name="__tabbed_1" type="radio" /><div class="tabbed-labels"><label for="__tabbed_1_1">&lt;1&gt;</label><label for="__tabbed_1_2">&lt;2&gt;</label><label for="__tabbed_1_3">&lt;3&gt;</label><label for="__tabbed_1_4">&lt;4&gt;</label><label for="__tabbed_1_5">&lt;5&gt;</label><label for="__tabbed_1_6">&lt;6&gt;</label><label for="__tabbed_1_7">&lt;7&gt;</label></div>
<div class="tabbed-content">
<div class="tabbed-block">
@@ -4404,7 +4404,7 @@
</div>
<p align="center"> Figure 10-2 &nbsp; Binary search process </p>
<p>It's worth noting that since both <span class="arithmatex">\(i\)</span> and <span class="arithmatex">\(j\)</span> are of <code>int</code> type, <strong><span class="arithmatex">\(i + j\)</span> may exceed the range of the <code>int</code> type</strong>. To avoid large number overflow, we typically use the formula <span class="arithmatex">\(m = \lfloor {i + (j - i) / 2} \rfloor\)</span> to calculate the midpoint.</p>
<p>It's worth noting that since both <span class="arithmatex">\(i\)</span> and <span class="arithmatex">\(j\)</span> are of <code>int</code> type, <strong><span class="arithmatex">\(i + j\)</span> may exceed the range of the <code>int</code> type</strong>. To avoid integer overflow, we typically use the formula <span class="arithmatex">\(m = \lfloor {i + (j - i) / 2} \rfloor\)</span> to calculate the midpoint.</p>
<p>The code is shown below:</p>
<div class="tabbed-set tabbed-alternate" data-tabs="2:13"><input checked="checked" id="__tabbed_2_1" name="__tabbed_2" type="radio" /><input id="__tabbed_2_2" name="__tabbed_2" type="radio" /><input id="__tabbed_2_3" name="__tabbed_2" type="radio" /><input id="__tabbed_2_4" name="__tabbed_2" type="radio" /><input id="__tabbed_2_5" name="__tabbed_2" type="radio" /><input id="__tabbed_2_6" name="__tabbed_2" type="radio" /><input id="__tabbed_2_7" name="__tabbed_2" type="radio" /><input id="__tabbed_2_8" name="__tabbed_2" type="radio" /><input id="__tabbed_2_9" name="__tabbed_2" type="radio" /><input id="__tabbed_2_10" name="__tabbed_2" type="radio" /><input id="__tabbed_2_11" name="__tabbed_2" type="radio" /><input id="__tabbed_2_12" name="__tabbed_2" type="radio" /><input id="__tabbed_2_13" name="__tabbed_2" type="radio" /><div class="tabbed-labels"><label for="__tabbed_2_1">Python</label><label for="__tabbed_2_2">C++</label><label for="__tabbed_2_3">Java</label><label for="__tabbed_2_4">C#</label><label for="__tabbed_2_5">Go</label><label for="__tabbed_2_6">Swift</label><label for="__tabbed_2_7">JS</label><label for="__tabbed_2_8">TS</label><label for="__tabbed_2_9">Dart</label><label for="__tabbed_2_10">Rust</label><label for="__tabbed_2_11">C</label><label for="__tabbed_2_12">Kotlin</label><label for="__tabbed_2_13">Ruby</label></div>
<div class="tabbed-content">
@@ -4693,10 +4693,10 @@
</div>
</div>
</div>
<p><strong>Time complexity is <span class="arithmatex">\(O(\log n)\)</span></strong>: In the binary loop, the interval is reduced by half each round, so the number of loops is <span class="arithmatex">\(\log_2 n\)</span>.</p>
<p><strong>Time complexity is <span class="arithmatex">\(O(\log n)\)</span></strong>: In the binary search loop, the interval is reduced by half each round, so the number of iterations is <span class="arithmatex">\(\log_2 n\)</span>.</p>
<p><strong>Space complexity is <span class="arithmatex">\(O(1)\)</span></strong>: Pointers <span class="arithmatex">\(i\)</span> and <span class="arithmatex">\(j\)</span> use constant-size space.</p>
<h2 id="1011-interval-representation-methods">10.1.1 &nbsp; Interval Representation Methods<a class="headerlink" href="#1011-interval-representation-methods" title="Permanent link">&para;</a></h2>
<p>In addition to the closed interval mentioned above, another common interval representation is the "left-closed right-open" interval, defined as <span class="arithmatex">\([0, n)\)</span>, meaning the left boundary includes itself while the right boundary does not. Under this representation, the interval <span class="arithmatex">\([i, j)\)</span> is empty when <span class="arithmatex">\(i = j\)</span>.</p>
<p>In addition to the closed interval mentioned above, another common interval representation is the "left-closed right-open" interval, defined as <span class="arithmatex">\([0, n)\)</span>, meaning that the left boundary is inclusive while the right boundary is exclusive. Under this representation, the interval <span class="arithmatex">\([i, j)\)</span> is empty when <span class="arithmatex">\(i = j\)</span>.</p>
<p>We can implement a binary search algorithm with the same functionality based on this representation:</p>
<div class="tabbed-set tabbed-alternate" data-tabs="3:13"><input checked="checked" id="__tabbed_3_1" name="__tabbed_3" type="radio" /><input id="__tabbed_3_2" name="__tabbed_3" type="radio" /><input id="__tabbed_3_3" name="__tabbed_3" type="radio" /><input id="__tabbed_3_4" name="__tabbed_3" type="radio" /><input id="__tabbed_3_5" name="__tabbed_3" type="radio" /><input id="__tabbed_3_6" name="__tabbed_3" type="radio" /><input id="__tabbed_3_7" name="__tabbed_3" type="radio" /><input id="__tabbed_3_8" name="__tabbed_3" type="radio" /><input id="__tabbed_3_9" name="__tabbed_3" type="radio" /><input id="__tabbed_3_10" name="__tabbed_3" type="radio" /><input id="__tabbed_3_11" name="__tabbed_3" type="radio" /><input id="__tabbed_3_12" name="__tabbed_3" type="radio" /><input id="__tabbed_3_13" name="__tabbed_3" type="radio" /><div class="tabbed-labels"><label for="__tabbed_3_1">Python</label><label for="__tabbed_3_2">C++</label><label for="__tabbed_3_3">Java</label><label for="__tabbed_3_4">C#</label><label for="__tabbed_3_5">Go</label><label for="__tabbed_3_6">Swift</label><label for="__tabbed_3_7">JS</label><label for="__tabbed_3_8">TS</label><label for="__tabbed_3_9">Dart</label><label for="__tabbed_3_10">Rust</label><label for="__tabbed_3_11">C</label><label for="__tabbed_3_12">Kotlin</label><label for="__tabbed_3_13">Ruby</label></div>
<div class="tabbed-content">
@@ -4991,15 +4991,15 @@
<p align="center"> Figure 10-3 &nbsp; Two interval definitions </p>
<h2 id="1012-advantages-and-limitations">10.1.2 &nbsp; Advantages and Limitations<a class="headerlink" href="#1012-advantages-and-limitations" title="Permanent link">&para;</a></h2>
<p>Binary search performs well in both time and space aspects.</p>
<p>Binary search offers good performance in both time and space.</p>
<ul>
<li>Binary search has high time efficiency. With large data volumes, the logarithmic time complexity has significant advantages. For example, when the data size <span class="arithmatex">\(n = 2^{20}\)</span>, linear search requires <span class="arithmatex">\(2^{20} = 1048576\)</span> loop rounds, while binary search only needs <span class="arithmatex">\(\log_2 2^{20} = 20\)</span> rounds.</li>
<li>Binary search has high time efficiency. With large data volumes, the logarithmic time complexity has significant advantages. For example, when the data size <span class="arithmatex">\(n = 2^{20}\)</span>, linear search requires <span class="arithmatex">\(2^{20} = 1048576\)</span> iterations, while binary search only needs <span class="arithmatex">\(\log_2 2^{20} = 20\)</span> iterations.</li>
<li>Binary search requires no extra space. Compared to searching algorithms that require additional space (such as hash-based search), binary search is more space-efficient.</li>
</ul>
<p>However, binary search is not suitable for all situations, mainly for the following reasons:</p>
<ul>
<li>Binary search is only applicable to sorted data. If the input data is unsorted, sorting specifically to use binary search would be counterproductive, as sorting algorithms typically have a time complexity of <span class="arithmatex">\(O(n \log n)\)</span>, which is higher than both linear search and binary search. For scenarios with frequent element insertions, maintaining array orderliness requires inserting elements at specific positions with a time complexity of <span class="arithmatex">\(O(n)\)</span>, which is also very expensive.</li>
<li>Binary search is only applicable to arrays. Binary search requires jump-style (non-contiguous) element access, and jump-style access has low efficiency in linked lists, making it unsuitable for linked lists or data structures based on linked list implementations.</li>
<li>Binary search is only applicable to sorted data. If the input data is unsorted, sorting specifically to use binary search would be counterproductive, as sorting algorithms typically have a time complexity of <span class="arithmatex">\(O(n \log n)\)</span>, which is higher than both linear search and binary search. For scenarios with frequent element insertions, keeping the array sorted requires inserting elements at specific positions with a time complexity of <span class="arithmatex">\(O(n)\)</span>, which is also very expensive.</li>
<li>Binary search is only applicable to arrays. Binary search requires non-contiguous, jump-style access to elements, and this kind of access is inefficient in linked lists, making it unsuitable for linked lists or linked-list-based data structures.</li>
<li>For small data volumes, linear search performs better. In linear search, each round requires only 1 comparison operation; while in binary search, it requires 1 addition, 1 division, 1-3 comparison operations, and 1 addition (subtraction), totaling 4-6 unit operations. Therefore, when the data volume <span class="arithmatex">\(n\)</span> is small, linear search is actually faster than binary search.</li>
</ul>
@@ -5048,7 +5048,7 @@ aria-label="Footer"
<a
href="../binary_search_insertion/"
class="md-footer__link md-footer__link--next"
aria-label="Next: 10.2 Binary Search Insertion"
aria-label="Next: 10.2 Binary Search Insertion Point"
rel="next"
>
<div class="md-footer__title">
@@ -5056,7 +5056,7 @@ aria-label="Footer"
Next
</span>
<div class="md-ellipsis">
10.2 Binary Search Insertion
10.2 Binary Search Insertion Point
</div>
</div>
<div class="md-footer__button md-icon">