mirror of
https://github.com/krahets/hello-algo.git
synced 2026-07-10 21:16:43 +08:00
deploy
This commit is contained in:
@@ -58,8 +58,8 @@
|
||||
|
||||
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CRoboto+Mono:400,400i,700,700i&display=fallback">
|
||||
<style>:root{--md-text-font:"Roboto";--md-code-font:"Roboto Mono"}</style>
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Lato:300,300i,400,400i,700,700i%7CJetBrains+Mono:400,400i,700,700i&display=fallback">
|
||||
<style>:root{--md-text-font:"Lato";--md-code-font:"JetBrains Mono"}</style>
|
||||
|
||||
|
||||
|
||||
@@ -371,7 +371,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
Before starting
|
||||
Before Starting
|
||||
|
||||
|
||||
|
||||
@@ -388,7 +388,7 @@
|
||||
<span class="md-nav__icon md-icon"></span>
|
||||
|
||||
|
||||
Before starting
|
||||
Before Starting
|
||||
|
||||
|
||||
</label>
|
||||
@@ -487,7 +487,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
0.1 About this book
|
||||
0.1 About This Book
|
||||
|
||||
|
||||
|
||||
@@ -515,7 +515,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
0.2 How to read
|
||||
0.2 How to Use This Book
|
||||
|
||||
|
||||
|
||||
@@ -604,7 +604,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
Chapter 1. Encounter with algorithms
|
||||
Chapter 1. Encounter With Algorithms
|
||||
|
||||
|
||||
|
||||
@@ -626,7 +626,7 @@
|
||||
<span class="md-nav__icon md-icon"></span>
|
||||
|
||||
|
||||
Chapter 1. Encounter with algorithms
|
||||
Chapter 1. Encounter With Algorithms
|
||||
|
||||
|
||||
</label>
|
||||
@@ -648,7 +648,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
1.1 Algorithms are everywhere
|
||||
1.1 Algorithms Are Everywhere
|
||||
|
||||
|
||||
|
||||
@@ -676,7 +676,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
1.2 What is an algorithm
|
||||
1.2 What Is an Algorithm
|
||||
|
||||
|
||||
|
||||
@@ -769,7 +769,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
Chapter 2. Complexity analysis
|
||||
Chapter 2. Complexity Analysis
|
||||
|
||||
|
||||
|
||||
@@ -791,7 +791,7 @@
|
||||
<span class="md-nav__icon md-icon"></span>
|
||||
|
||||
|
||||
Chapter 2. Complexity analysis
|
||||
Chapter 2. Complexity Analysis
|
||||
|
||||
|
||||
</label>
|
||||
@@ -813,7 +813,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
2.1 Algorithm efficiency assessment
|
||||
2.1 Algorithm Efficiency Evaluation
|
||||
|
||||
|
||||
|
||||
@@ -841,7 +841,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
2.2 Iteration and recursion
|
||||
2.2 Iteration and Recursion
|
||||
|
||||
|
||||
|
||||
@@ -869,7 +869,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
2.3 Time complexity
|
||||
2.3 Time Complexity
|
||||
|
||||
|
||||
|
||||
@@ -897,7 +897,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
2.4 Space complexity
|
||||
2.4 Space Complexity
|
||||
|
||||
|
||||
|
||||
@@ -990,7 +990,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
Chapter 3. Data structures
|
||||
Chapter 3. Data Structures
|
||||
|
||||
|
||||
|
||||
@@ -1012,7 +1012,7 @@
|
||||
<span class="md-nav__icon md-icon"></span>
|
||||
|
||||
|
||||
Chapter 3. Data structures
|
||||
Chapter 3. Data Structures
|
||||
|
||||
|
||||
</label>
|
||||
@@ -1034,7 +1034,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
3.1 Classification of data structures
|
||||
3.1 Classification of Data Structures
|
||||
|
||||
|
||||
|
||||
@@ -1062,7 +1062,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
3.2 Basic data types
|
||||
3.2 Basic Data Types
|
||||
|
||||
|
||||
|
||||
@@ -1090,7 +1090,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
3.3 Number encoding *
|
||||
3.3 Number Encoding *
|
||||
|
||||
|
||||
|
||||
@@ -1118,7 +1118,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
3.4 Character encoding *
|
||||
3.4 Character Encoding *
|
||||
|
||||
|
||||
|
||||
@@ -1211,7 +1211,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
Chapter 4. Array and linked list
|
||||
Chapter 4. Array and Linked List
|
||||
|
||||
|
||||
|
||||
@@ -1233,7 +1233,7 @@
|
||||
<span class="md-nav__icon md-icon"></span>
|
||||
|
||||
|
||||
Chapter 4. Array and linked list
|
||||
Chapter 4. Array and Linked List
|
||||
|
||||
|
||||
</label>
|
||||
@@ -1283,7 +1283,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
4.2 Linked list
|
||||
4.2 Linked List
|
||||
|
||||
|
||||
|
||||
@@ -1339,7 +1339,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
4.4 Memory and cache *
|
||||
4.4 Memory and Cache *
|
||||
|
||||
|
||||
|
||||
@@ -1430,7 +1430,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
Chapter 5. Stack and queue
|
||||
Chapter 5. Stack and Queue
|
||||
|
||||
|
||||
|
||||
@@ -1452,7 +1452,7 @@
|
||||
<span class="md-nav__icon md-icon"></span>
|
||||
|
||||
|
||||
Chapter 5. Stack and queue
|
||||
Chapter 5. Stack and Queue
|
||||
|
||||
|
||||
</label>
|
||||
@@ -1530,7 +1530,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
5.3 Double-ended queue
|
||||
5.3 Double-Ended Queue
|
||||
|
||||
|
||||
|
||||
@@ -1621,7 +1621,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
Chapter 6. Hash table
|
||||
Chapter 6. Hashing
|
||||
|
||||
|
||||
|
||||
@@ -1643,7 +1643,7 @@
|
||||
<span class="md-nav__icon md-icon"></span>
|
||||
|
||||
|
||||
Chapter 6. Hash table
|
||||
Chapter 6. Hashing
|
||||
|
||||
|
||||
</label>
|
||||
@@ -1665,7 +1665,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
6.1 Hash table
|
||||
6.1 Hash Table
|
||||
|
||||
|
||||
|
||||
@@ -1693,7 +1693,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
6.2 Hash collision
|
||||
6.2 Hash Collision
|
||||
|
||||
|
||||
|
||||
@@ -1721,7 +1721,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
6.3 Hash algorithm
|
||||
6.3 Hash Algorithm
|
||||
|
||||
|
||||
|
||||
@@ -1860,7 +1860,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
7.1 Binary tree
|
||||
7.1 Binary Tree
|
||||
|
||||
|
||||
|
||||
@@ -1888,7 +1888,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
7.2 Binary tree traversal
|
||||
7.2 Binary Tree Traversal
|
||||
|
||||
|
||||
|
||||
@@ -1916,7 +1916,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
7.3 Array Representation of tree
|
||||
7.3 Array Representation of Tree
|
||||
|
||||
|
||||
|
||||
@@ -1944,7 +1944,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
7.4 Binary Search tree
|
||||
7.4 Binary Search Tree
|
||||
|
||||
|
||||
|
||||
@@ -1972,7 +1972,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
7.5 AVL tree *
|
||||
7.5 AVL Tree *
|
||||
|
||||
|
||||
|
||||
@@ -2135,7 +2135,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
8.2 Building a heap
|
||||
8.2 Building a Heap
|
||||
|
||||
|
||||
|
||||
@@ -2163,7 +2163,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
8.3 Top-k problem
|
||||
8.3 Top-K Problem
|
||||
|
||||
|
||||
|
||||
@@ -2326,7 +2326,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
9.2 Basic graph operations
|
||||
9.2 Basic Operations on Graphs
|
||||
|
||||
|
||||
|
||||
@@ -2354,7 +2354,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
9.3 Graph traversal
|
||||
9.3 Graph Traversal
|
||||
|
||||
|
||||
|
||||
@@ -2493,7 +2493,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.1 Binary search
|
||||
10.1 Binary Search
|
||||
|
||||
|
||||
|
||||
@@ -2521,7 +2521,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.2 Binary search insertion
|
||||
10.2 Binary Search Insertion
|
||||
|
||||
|
||||
|
||||
@@ -2549,7 +2549,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.3 Binary search boundaries
|
||||
10.3 Binary Search Edge Cases
|
||||
|
||||
|
||||
|
||||
@@ -2577,7 +2577,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.4 Hashing optimization strategies
|
||||
10.4 Hash Optimization Strategy
|
||||
|
||||
|
||||
|
||||
@@ -2605,7 +2605,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.5 Search algorithms revisited
|
||||
10.5 Search Algorithms Revisited
|
||||
|
||||
|
||||
|
||||
@@ -2756,7 +2756,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
11.1 Sorting algorithms
|
||||
11.1 Sorting Algorithms
|
||||
|
||||
|
||||
|
||||
@@ -2784,7 +2784,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
11.2 Selection sort
|
||||
11.2 Selection Sort
|
||||
|
||||
|
||||
|
||||
@@ -2812,7 +2812,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
11.3 Bubble sort
|
||||
11.3 Bubble Sort
|
||||
|
||||
|
||||
|
||||
@@ -2840,7 +2840,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
11.4 Insertion sort
|
||||
11.4 Insertion Sort
|
||||
|
||||
|
||||
|
||||
@@ -2868,7 +2868,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
11.5 Quick sort
|
||||
11.5 Quick Sort
|
||||
|
||||
|
||||
|
||||
@@ -2896,7 +2896,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
11.6 Merge sort
|
||||
11.6 Merge Sort
|
||||
|
||||
|
||||
|
||||
@@ -2924,7 +2924,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
11.7 Heap sort
|
||||
11.7 Heap Sort
|
||||
|
||||
|
||||
|
||||
@@ -2952,7 +2952,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
11.8 Bucket sort
|
||||
11.8 Bucket Sort
|
||||
|
||||
|
||||
|
||||
@@ -2980,7 +2980,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
11.9 Counting sort
|
||||
11.9 Counting Sort
|
||||
|
||||
|
||||
|
||||
@@ -3008,7 +3008,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
11.10 Radix sort
|
||||
11.10 Radix Sort
|
||||
|
||||
|
||||
|
||||
@@ -3092,7 +3092,7 @@
|
||||
<a href="#1-key-review" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
1. Key review
|
||||
1. Key Review
|
||||
|
||||
</span>
|
||||
</a>
|
||||
@@ -3170,7 +3170,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
Chapter 12. Divide and conquer
|
||||
Chapter 12. Divide and Conquer
|
||||
|
||||
|
||||
|
||||
@@ -3192,7 +3192,7 @@
|
||||
<span class="md-nav__icon md-icon"></span>
|
||||
|
||||
|
||||
Chapter 12. Divide and conquer
|
||||
Chapter 12. Divide and Conquer
|
||||
|
||||
|
||||
</label>
|
||||
@@ -3214,7 +3214,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
12.1 Divide and conquer algorithms
|
||||
12.1 Divide and Conquer Algorithms
|
||||
|
||||
|
||||
|
||||
@@ -3242,7 +3242,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
12.2 Divide and conquer search strategy
|
||||
12.2 Divide and Conquer Search Strategy
|
||||
|
||||
|
||||
|
||||
@@ -3270,7 +3270,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
12.3 Building binary tree problem
|
||||
12.3 Building a Binary Tree Problem
|
||||
|
||||
|
||||
|
||||
@@ -3298,7 +3298,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
12.4 Tower of Hanoi Problem
|
||||
12.4 Hanoi Tower Problem
|
||||
|
||||
|
||||
|
||||
@@ -3435,7 +3435,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
13.1 Backtracking algorithms
|
||||
13.1 Backtracking Algorithm
|
||||
|
||||
|
||||
|
||||
@@ -3463,7 +3463,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
13.2 Permutation problem
|
||||
13.2 Permutations Problem
|
||||
|
||||
|
||||
|
||||
@@ -3491,7 +3491,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
13.3 Subset sum problem
|
||||
13.3 Subset-Sum Problem
|
||||
|
||||
|
||||
|
||||
@@ -3519,7 +3519,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
13.4 n queens problem
|
||||
13.4 N-Queens Problem
|
||||
|
||||
|
||||
|
||||
@@ -3616,7 +3616,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
Chapter 14. Dynamic programming
|
||||
Chapter 14. Dynamic Programming
|
||||
|
||||
|
||||
|
||||
@@ -3638,7 +3638,7 @@
|
||||
<span class="md-nav__icon md-icon"></span>
|
||||
|
||||
|
||||
Chapter 14. Dynamic programming
|
||||
Chapter 14. Dynamic Programming
|
||||
|
||||
|
||||
</label>
|
||||
@@ -3660,7 +3660,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
14.1 Introduction to dynamic programming
|
||||
14.1 Introduction to Dynamic Programming
|
||||
|
||||
|
||||
|
||||
@@ -3688,7 +3688,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
14.2 Characteristics of DP problems
|
||||
14.2 Characteristics of Dynamic Programming Problems
|
||||
|
||||
|
||||
|
||||
@@ -3716,7 +3716,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
14.3 DP problem-solving approach¶
|
||||
14.3 Dynamic Programming Problem-Solving Approach
|
||||
|
||||
|
||||
|
||||
@@ -3744,7 +3744,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
14.4 0-1 Knapsack problem
|
||||
14.4 0-1 Knapsack Problem
|
||||
|
||||
|
||||
|
||||
@@ -3772,7 +3772,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
14.5 Unbounded knapsack problem
|
||||
14.5 Unbounded Knapsack Problem
|
||||
|
||||
|
||||
|
||||
@@ -3800,7 +3800,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
14.6 Edit distance problem
|
||||
14.6 Edit Distance Problem
|
||||
|
||||
|
||||
|
||||
@@ -3937,7 +3937,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
15.1 Greedy algorithms
|
||||
15.1 Greedy Algorithm
|
||||
|
||||
|
||||
|
||||
@@ -3965,7 +3965,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
15.2 Fractional knapsack problem
|
||||
15.2 Fractional Knapsack Problem
|
||||
|
||||
|
||||
|
||||
@@ -3993,7 +3993,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
15.3 Maximum capacity problem
|
||||
15.3 Maximum Capacity Problem
|
||||
|
||||
|
||||
|
||||
@@ -4021,7 +4021,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
15.4 Maximum product cutting problem
|
||||
15.4 Maximum Product Cutting Problem
|
||||
|
||||
|
||||
|
||||
@@ -4154,7 +4154,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
16.1 Installation
|
||||
16.1 Programming Environment Installation
|
||||
|
||||
|
||||
|
||||
@@ -4182,7 +4182,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
16.2 Contributing
|
||||
16.2 Contributing Together
|
||||
|
||||
|
||||
|
||||
@@ -4210,7 +4210,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
16.3 Terminology
|
||||
16.3 Terminology Table
|
||||
|
||||
|
||||
|
||||
@@ -4327,7 +4327,7 @@
|
||||
<a href="#1-key-review" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
1. Key review
|
||||
1. Key Review
|
||||
|
||||
</span>
|
||||
</a>
|
||||
@@ -4383,37 +4383,37 @@
|
||||
|
||||
<!-- Page content -->
|
||||
<h1 id="1111-summary">11.11 Summary<a class="headerlink" href="#1111-summary" title="Permanent link">¶</a></h1>
|
||||
<h3 id="1-key-review">1. Key review<a class="headerlink" href="#1-key-review" title="Permanent link">¶</a></h3>
|
||||
<h3 id="1-key-review">1. Key Review<a class="headerlink" href="#1-key-review" title="Permanent link">¶</a></h3>
|
||||
<ul>
|
||||
<li>Bubble sort works by swapping adjacent elements. By adding a flag to enable early return, we can optimize the best-case time complexity of bubble sort to <span class="arithmatex">\(O(n)\)</span>.</li>
|
||||
<li>Insertion sort sorts each round by inserting elements from the unsorted interval into the correct position in the sorted interval. Although the time complexity of insertion sort is <span class="arithmatex">\(O(n^2)\)</span>, it is very popular in sorting small amounts of data due to relatively fewer operations per unit.</li>
|
||||
<li>Quick sort is based on sentinel partitioning operations. In sentinel partitioning, it's possible to always pick the worst pivot, leading to a time complexity degradation to <span class="arithmatex">\(O(n^2)\)</span>. Introducing median or random pivots can reduce the probability of such degradation. Tail recursion effectively reduce the recursion depth, optimizing the space complexity to <span class="arithmatex">\(O(\log n)\)</span>.</li>
|
||||
<li>Merge sort includes dividing and merging two phases, typically embodying the divide-and-conquer strategy. In merge sort, sorting an array requires creating auxiliary arrays, resulting in a space complexity of <span class="arithmatex">\(O(n)\)</span>; however, the space complexity for sorting a list can be optimized to <span class="arithmatex">\(O(1)\)</span>.</li>
|
||||
<li>Bucket sort consists of three steps: distributing data into buckets, sorting within each bucket, and merging results in bucket order. It also embodies the divide-and-conquer strategy, suitable for very large datasets. The key to bucket sort is the even distribution of data.</li>
|
||||
<li>Counting sort is a variant of bucket sort, which sorts by counting the occurrences of each data point. Counting sort is suitable for large datasets with a limited range of data and requires data conversion to positive integers.</li>
|
||||
<li>Radix sort processes data by sorting it digit by digit, requiring data to be represented as fixed-length numbers.</li>
|
||||
<li>Overall, we seek sorting algorithm that has high efficiency, stability, in-place operation, and adaptability. However, like other data structures and algorithms, no sorting algorithm can meet all these conditions simultaneously. In practical applications, we need to choose the appropriate sorting algorithm based on the characteristics of the data.</li>
|
||||
<li>Figure 11-19 compares mainstream sorting algorithms in terms of efficiency, stability, in-place nature, and adaptability.</li>
|
||||
<li>Bubble sort achieves sorting by swapping adjacent elements. By adding a flag to enable early return, we can optimize the best-case time complexity of bubble sort to <span class="arithmatex">\(O(n)\)</span>.</li>
|
||||
<li>Insertion sort completes sorting by inserting elements from the unsorted interval into the correct position in the sorted interval each round. Although the time complexity of insertion sort is <span class="arithmatex">\(O(n^2)\)</span>, it is very popular in small data volume sorting tasks because it involves relatively few unit operations.</li>
|
||||
<li>Quick sort is implemented based on sentinel partitioning operations. In sentinel partitioning, it is possible to select the worst pivot every time, causing the time complexity to degrade to <span class="arithmatex">\(O(n^2)\)</span>. Introducing median pivot or random pivot can reduce the probability of such degradation. By preferentially recursing on the shorter sub-interval, the recursion depth can be effectively reduced, optimizing the space complexity to <span class="arithmatex">\(O(\log n)\)</span>.</li>
|
||||
<li>Merge sort includes two phases: divide and merge, which typically embody the divide-and-conquer strategy. In merge sort, sorting an array requires creating auxiliary arrays, with a space complexity of <span class="arithmatex">\(O(n)\)</span>; however, the space complexity of sorting a linked list can be optimized to <span class="arithmatex">\(O(1)\)</span>.</li>
|
||||
<li>Bucket sort consists of three steps: distributing data into buckets, sorting within buckets, and merging results. It also embodies the divide-and-conquer strategy and is suitable for very large data volumes. The key to bucket sort is distributing data evenly.</li>
|
||||
<li>Counting sort is a special case of bucket sort, which achieves sorting by counting the number of occurrences of data. Counting sort is suitable for situations where the data volume is large but the data range is limited, and requires that data can be converted to positive integers.</li>
|
||||
<li>Radix sort achieves data sorting by sorting digit by digit, requiring that data can be represented as fixed-digit numbers.</li>
|
||||
<li>Overall, we hope to find a sorting algorithm that is efficient, stable, in-place, and adaptive, with good versatility. However, just like other data structures and algorithms, no sorting algorithm has been found so far that simultaneously possesses all these characteristics. In practical applications, we need to select the appropriate sorting algorithm based on the specific characteristics of the data.</li>
|
||||
<li>Figure 11-19 compares mainstream sorting algorithms in terms of efficiency, stability, in-place property, and adaptability.</li>
|
||||
</ul>
|
||||
<p><a class="glightbox" href="../summary.assets/sorting_algorithms_comparison.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="Sorting Algorithm Comparison" class="animation-figure" src="../summary.assets/sorting_algorithms_comparison.png" /></a></p>
|
||||
<p align="center"> Figure 11-19 Sorting Algorithm Comparison </p>
|
||||
<p><a class="glightbox" href="../summary.assets/sorting_algorithms_comparison.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="Sorting algorithm comparison" class="animation-figure" src="../summary.assets/sorting_algorithms_comparison.png" /></a></p>
|
||||
<p align="center"> Figure 11-19 Sorting algorithm comparison </p>
|
||||
|
||||
<h3 id="2-q-a">2. Q & A<a class="headerlink" href="#2-q-a" title="Permanent link">¶</a></h3>
|
||||
<p><strong>Q</strong>: When is the stability of sorting algorithms necessary?</p>
|
||||
<p>In reality, we might sort based on one attribute of an object. For example, students have names and heights as attributes, and we aim to implement multi-level sorting: first by name to get <code>(A, 180) (B, 185) (C, 170) (D, 170)</code>; then by height. Because the sorting algorithm is unstable, we might end up with <code>(D, 170) (C, 170) (A, 180) (B, 185)</code>.</p>
|
||||
<p>It can be seen that the positions of students D and C have been swapped, disrupting the orderliness of the names, which is undesirable.</p>
|
||||
<p><strong>Q</strong>: In what situations is the stability of sorting algorithms necessary?</p>
|
||||
<p>In reality, we may sort based on a certain attribute of objects. For example, students have two attributes: name and height. We want to implement multi-level sorting: first sort by name to get <code>(A, 180) (B, 185) (C, 170) (D, 170)</code>; then sort by height. Because the sorting algorithm is unstable, we may get <code>(D, 170) (C, 170) (A, 180) (B, 185)</code>.</p>
|
||||
<p>It can be seen that the positions of students D and C have been swapped, and the orderliness of names has been disrupted, which is something we don't want to see.</p>
|
||||
<p><strong>Q</strong>: Can the order of "searching from right to left" and "searching from left to right" in sentinel partitioning be swapped?</p>
|
||||
<p>No, when using the leftmost element as the pivot, we must first "search from right to left" then "search from left to right". This conclusion is somewhat counterintuitive, so let's analyze the reason.</p>
|
||||
<p>The last step of the sentinel partition <code>partition()</code> is to swap <code>nums[left]</code> and <code>nums[i]</code>. After the swap, the elements to the left of the pivot are all <code><=</code> the pivot, <strong>which requires that <code>nums[left] >= nums[i]</code> must hold before the last swap</strong>. Suppose we "search from left to right" first, and if no element larger than the pivot is found, <strong>we will exit the loop when <code>i == j</code>, possibly with <code>nums[j] == nums[i] > nums[left]</code></strong>. In other words, the final swap operation will exchange an element larger than the pivot to the left end of the array, causing the sentinel partition to fail.</p>
|
||||
<p>For example, given the array <code>[0, 0, 0, 0, 1]</code>, if we first "search from left to right", the array after the sentinel partition is <code>[1, 0, 0, 0, 0]</code>, which is incorrect.</p>
|
||||
<p>Upon further consideration, if we choose <code>nums[right]</code> as the pivot, then exactly the opposite, we must first "search from left to right".</p>
|
||||
<p><strong>Q</strong>: Regarding tail recursion optimization, why does choosing the shorter array ensure that the recursion depth does not exceed <span class="arithmatex">\(\log n\)</span>?</p>
|
||||
<p>The recursion depth is the number of currently unreturned recursive methods. Each round of sentinel partition divides the original array into two subarrays. With tail recursion optimization, the length of the subarray to be recursively followed is at most half of the original array length. Assuming the worst case always halves the length, the final recursion depth will be <span class="arithmatex">\(\log n\)</span>.</p>
|
||||
<p>Reviewing the original quicksort, we might continuously recursively process larger arrays, in the worst case from <span class="arithmatex">\(n\)</span>, <span class="arithmatex">\(n - 1\)</span>, ..., <span class="arithmatex">\(2\)</span>, <span class="arithmatex">\(1\)</span>, with a recursion depth of <span class="arithmatex">\(n\)</span>. Tail recursion optimization can avoid this scenario.</p>
|
||||
<p><strong>Q</strong>: When all elements in the array are equal, is the time complexity of quicksort <span class="arithmatex">\(O(n^2)\)</span>? How should this degenerate case be handled?</p>
|
||||
<p>Yes. For this situation, consider using sentinel partitioning to divide the array into three parts: less than, equal to, and greater than the pivot. Only recursively proceed with the less than and greater than parts. In this method, an array where all input elements are equal can be sorted in just one round of sentinel partitioning.</p>
|
||||
<p>No. When we use the leftmost element as the pivot, we must first "search from right to left" and then "search from left to right". This conclusion is somewhat counterintuitive; let's analyze the reason.</p>
|
||||
<p>The last step of sentinel partitioning <code>partition()</code> is to swap <code>nums[left]</code> and <code>nums[i]</code>. After the swap is complete, the elements to the left of the pivot are all <code><=</code> the pivot, <strong>which requires that <code>nums[left] >= nums[i]</code> must hold before the last swap</strong>. Suppose we first "search from left to right", then if we cannot find an element larger than the pivot, <strong>we will exit the loop when <code>i == j</code>, at which point it may be that <code>nums[j] == nums[i] > nums[left]</code></strong>. In other words, the last swap operation will swap an element larger than the pivot to the leftmost end of the array, causing sentinel partitioning to fail.</p>
|
||||
<p>For example, given the array <code>[0, 0, 0, 0, 1]</code>, if we first "search from left to right", the array after sentinel partitioning is <code>[1, 0, 0, 0, 0]</code>, which is incorrect.</p>
|
||||
<p>Thinking deeper, if we select <code>nums[right]</code> as the pivot, then it's exactly the opposite - we must first "search from left to right".</p>
|
||||
<p><strong>Q</strong>: Regarding the optimization of recursion depth in quick sort, why can selecting the shorter array ensure that the recursion depth does not exceed <span class="arithmatex">\(\log n\)</span>?</p>
|
||||
<p>The recursion depth is the number of currently unreturned recursive methods. Each round of sentinel partitioning divides the original array into two sub-arrays. After recursion depth optimization, the length of the sub-array to be recursively processed is at most half of the original array length. Assuming the worst case is always half the length, the final recursion depth will be <span class="arithmatex">\(\log n\)</span>.</p>
|
||||
<p>Reviewing the original quick sort, we may continuously recurse on the longer array. In the worst case, it would be <span class="arithmatex">\(n\)</span>, <span class="arithmatex">\(n - 1\)</span>, <span class="arithmatex">\(\dots\)</span>, <span class="arithmatex">\(2\)</span>, <span class="arithmatex">\(1\)</span>, with a recursion depth of <span class="arithmatex">\(n\)</span>. Recursion depth optimization can avoid this situation.</p>
|
||||
<p><strong>Q</strong>: When all elements in the array are equal, is the time complexity of quick sort <span class="arithmatex">\(O(n^2)\)</span>? How should this degenerate case be handled?</p>
|
||||
<p>Yes. For this situation, consider partitioning the array into three parts through sentinel partitioning: less than, equal to, and greater than the pivot. Only recursively process the less than and greater than parts. Under this method, an array where all input elements are equal can complete sorting in just one round of sentinel partitioning.</p>
|
||||
<p><strong>Q</strong>: Why is the worst-case time complexity of bucket sort <span class="arithmatex">\(O(n^2)\)</span>?</p>
|
||||
<p>In the worst case, all elements are placed in the same bucket. If we use an <span class="arithmatex">\(O(n^2)\)</span> algorithm to sort these elements, the time complexity will be <span class="arithmatex">\(O(n^2)\)</span>.</p>
|
||||
<p>In the worst case, all elements are distributed into the same bucket. If we use an <span class="arithmatex">\(O(n^2)\)</span> algorithm to sort these elements, the time complexity will be <span class="arithmatex">\(O(n^2)\)</span>.</p>
|
||||
|
||||
<!-- Source file information -->
|
||||
|
||||
@@ -4436,7 +4436,7 @@ aria-label="Footer"
|
||||
<a
|
||||
href="../radix_sort/"
|
||||
class="md-footer__link md-footer__link--prev"
|
||||
aria-label="Previous: 11.10 Radix sort"
|
||||
aria-label="Previous: 11.10 Radix Sort"
|
||||
rel="prev"
|
||||
>
|
||||
<div class="md-footer__button md-icon">
|
||||
@@ -4448,7 +4448,7 @@ aria-label="Footer"
|
||||
Previous
|
||||
</span>
|
||||
<div class="md-ellipsis">
|
||||
11.10 Radix sort
|
||||
11.10 Radix Sort
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
@@ -4460,7 +4460,7 @@ aria-label="Footer"
|
||||
<a
|
||||
href="../../chapter_divide_and_conquer/"
|
||||
class="md-footer__link md-footer__link--next"
|
||||
aria-label="Next: Chapter 12. &nbsp; Divide and conquer"
|
||||
aria-label="Next: Chapter 12. &nbsp; Divide and Conquer"
|
||||
rel="next"
|
||||
>
|
||||
<div class="md-footer__title">
|
||||
@@ -4468,7 +4468,7 @@ aria-label="Footer"
|
||||
Next
|
||||
</span>
|
||||
<div class="md-ellipsis">
|
||||
Chapter 12. Divide and conquer
|
||||
Chapter 12. Divide and Conquer
|
||||
</div>
|
||||
</div>
|
||||
<div class="md-footer__button md-icon">
|
||||
@@ -4561,7 +4561,7 @@ aria-label="Footer"
|
||||
<nav class="md-footer__inner md-grid" aria-label="Footer" >
|
||||
|
||||
|
||||
<a href="../radix_sort/" class="md-footer__link md-footer__link--prev" aria-label="Previous: 11.10 Radix sort">
|
||||
<a href="../radix_sort/" class="md-footer__link md-footer__link--prev" aria-label="Previous: 11.10 Radix Sort">
|
||||
<div class="md-footer__button md-icon">
|
||||
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z"/></svg>
|
||||
@@ -4571,20 +4571,20 @@ aria-label="Footer"
|
||||
Previous
|
||||
</span>
|
||||
<div class="md-ellipsis">
|
||||
11.10 Radix sort
|
||||
11.10 Radix Sort
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
<a href="../../chapter_divide_and_conquer/" class="md-footer__link md-footer__link--next" aria-label="Next: Chapter 12. &nbsp; Divide and conquer">
|
||||
<a href="../../chapter_divide_and_conquer/" class="md-footer__link md-footer__link--next" aria-label="Next: Chapter 12. &nbsp; Divide and Conquer">
|
||||
<div class="md-footer__title">
|
||||
<span class="md-footer__direction">
|
||||
Next
|
||||
</span>
|
||||
<div class="md-ellipsis">
|
||||
Chapter 12. Divide and conquer
|
||||
Chapter 12. Divide and Conquer
|
||||
</div>
|
||||
</div>
|
||||
<div class="md-footer__button md-icon">
|
||||
|
||||
Reference in New Issue
Block a user