You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: content/Algorithm/Sorting.md
+10-8Lines changed: 10 additions & 8 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -6,7 +6,7 @@ Author Profile:
6
6
tags:
7
7
- dsa
8
8
Creation Date: 2024-01-03, 14:26
9
-
Last Date: 2024-03-11T20:07:26+08:00
9
+
Last Date: 2024-03-12T12:29:02+08:00
10
10
References:
11
11
draft:
12
12
description: Trying to sort my life out.
@@ -42,14 +42,14 @@ description: Trying to sort my life out.
42
42
43
43
>[!example]- Sorting algorithms that are unstable
44
44
> **Bogo Sort**
45
-
> - Random [[Permutation]] may sway elements with the same value
45
+
> - Random [[Permutation]] may swap elements with the same value
46
46
>
47
47
> **[[#Selection Sort]]**
48
48
> - Imagine in iteration $j$, the element at position $j$ is $8$ and element at position $j+1$ is $8$ too. Then the smallest element in the range $[j, k]$ is $7$. We swap $7$ with the $8$ at position $j$. As you can see, the order of the 2 same value is changed. Thus, unstable
49
49
50
50
### Divide-and-Conquer Sorting
51
51
-**Divide**: split array into two halves
52
-
-**[[Recursion]] up**: sort the two halves
52
+
-**[[Recursion]] up**: hit the base case, kickstart sorting the two halves
53
53
-**Combine**: merge the sorted halves
54
54
55
55
## Bubble Sort
@@ -83,7 +83,7 @@ description: Trying to sort my life out.
83
83
84
84
>[!note]- Time Complexity
85
85
> **Best-case**
86
-
> - $O(n^2)$, because at each iteration, we can only find the current smallest element. Even if we are given a fully sorted array, we need to perform$n$ iterations, in order to have the confidence to say that the array is sorted
86
+
> - $O(n^2)$, because at each iteration, we can only find the current smallest element. Even if we are given a fully sorted array, we need to perform$n$ iterations, in order to have the confidence to say that the array is sorted
87
87
>
88
88
> **Average-case**
89
89
> - $O(n^2)$, assume inputs are chosen at random
@@ -96,7 +96,7 @@ description: Trying to sort my life out.
96
96
- The idea here is that at each iteration $j$, we are are going to **insert** the element at the $j$ position to the prefix [[Array]] that is $j-1$ long, such that the new prefix array which is $j$ long remains sorted
97
97
98
98
>[!important] Loop Invariant
99
-
> At the end of iteration $j$, the first $j$ items in the array are **sorted order**.
99
+
> At the end of iteration $j$, the first $j$ items in the array are in **sorted order**.
100
100
101
101
>[!note]- Time Complexity
102
102
> **Best-case**
@@ -136,9 +136,11 @@ description: Trying to sort my life out.
136
136
> Guess the time complexity and verify it with the reoccurrence we obtained.
137
137
138
138
>[!caution] Slow on small arrays!
139
-
> Merge sort has a space complexity of $O(n)$, we know allocation of different arrays are scattered in the [[Main Memory]]. When we need to work multiple arrays we sacrifice the performance gain from [[CPU Cache#Cache Locality]]. And the [[Recursion]] nature of the algorithm comes with extra overhead. Recursion is also less predicable, thus negative impact on [[Branch Prediction]].
139
+
> The allocation of different arrays are scattered in the [[Main Memory]]. Merge sort has a space complexity of $O(n)$ with different temporary arrays at each merge layer. Working on multiple arrays means we sacrifice the performance gain from [[CPU Cache#Cache Locality]].
140
140
>
141
-
> When the array is small, such hardware level impact outweighs the performance gain from the better time complexity.
141
+
> The [[Recursion]] nature of the algorithm comes with extra overhead too. Recursion is also less predicable, thus negative impact on [[Branch Prediction]].
142
+
>
143
+
> When the array is small, such hardware level negative impact outweighs the performance gains from the better time complexity.
142
144
143
145
>[!caution] Slow on almost sorted array!
144
-
> Merge sort's performance is $O(nlogn)$ when the array is almost sorted, because it needs to perform the full divide-and-conquer process regardless how chaotic the given array is. While [[#Bubble Sort]] and [[#Insertion Sort]] have a time complexity of $O(n)$ only.
146
+
> Merge sort's performance is still $O(nlogn)$ when the array is almost sorted, because it needs to perform the full divide-and-conquer process regardless how chaotic the given array is. While [[#Bubble Sort]] and [[#Insertion Sort]] have a time complexity of $O(n)$.
- A [[Data Structure#Linear]] collection of elements of the same [[Datatype]] that are stored in [[Data Structure#Continuous Memory]]. The next node is obtained by adding a **constant value** to the [[Memory Address]] of current node
15
+
- Can be used to implement [[Hash Map]] when keys are fixed
> If we want to expand, we have to create another bigger array & **copy all the elements** to the new array which is very time consuming
20
+
21
+
>[!attention] Element Removal
22
+
> We can't delete elements in arrays, we can only overwrite
23
+
24
+
### Time Complexity
25
+
>[!note]- Search
26
+
> $O(1)$ to search for a value.
27
+
28
+
>[!note]- Indexing
29
+
> It is $O(1)$ to index any elements in an array. The indexing formula is `elementAddr = firtstElementAddr + elementLength * elementIndex`, `elementIndex` is $0$ when we try to access the first element
30
+
31
+
>[!note]- Insert, Delete
32
+
> $O(1)$ at the 2 ends of the array
33
+
>
34
+
> $O(n)$ in the middle of the array
35
+
> - For insert, we have to move all the elements next to the new element one step to right
36
+
> - For delete, we have move all element next to the deleted element one step to left
37
+
38
+
>[!info]- Performance comparison with Linked List when going through all elements
39
+
> Array is much faster if there is [[CPU Cache]], otherwise it will be slightly slower. Because Array has to calculate the address of the next element, while [[Linked List]] is already calculated.
40
+
>
41
+
> The reason why array is faster with CPU Cache is because array is stored in a [[Data Structure#Continuous Memory]] manner. Thus array is able to take advantage of [[CPU Cache#Cache Locality]]
42
+
43
+
### Contiguous Segment
44
+
- A continuous range of [[Array]]
45
+
46
+
47
+
## Dynamic Array
48
+
---
49
+
- Also known as **List**
50
+
- Resizable [[Array]], achieved by building an [[Abstraction (抽象)]] above the Array
51
+
52
+
53
+
>[!tip] Convenient
54
+
> Developers don't need to re-write battle-tested logic of re-sizeing Array etc, battery-packed with best practices.
55
+
56
+
>[!attention] More Resource Intense
57
+
> We can't fine tune every Array operations because the implementation details are abstracted away. We only have a limited interface to interact with it.
58
+
59
+
## Circular Array
60
+
---
61
+
- Connect the start and end of the [[Array]] to form a loop
62
+
- With taking remainder from ``frontIndex % arrayCapacity``, we are able to implement circular array on an array. Take a look at [Visual](https://www.hello-algo.com/chapter_stack_and_queue/queue/#2) for better understanding
63
+
- Used to implement [[Queue (FIFO)#Implementation|Queue]]
64
+
65
+
>[!info] Front Index
66
+
> A variable to keep track the index for the start of the circular array.
67
+
68
+
>[!info] Rear Index
69
+
> A variable to keep track the index of the slot after the last element of the circular array, Can be obtained with `frontIndex + arraySize`.
0 commit comments