Skip to content

Commit 205ef27

Browse files
committed
feat(sorting): add sorting topic
1 parent 1bb7ffc commit 205ef27

2 files changed

Lines changed: 315 additions & 3 deletions

File tree

intro/10-sorting/README.md

Lines changed: 312 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,312 @@
1+
# Sorting algorithms
2+
3+
Sorting are algorithms that put elements of a list in a certain order. It is cruxial to understand the basics of sorting in order to start understanding more complex algorithms and why you have to pay attention to efficiency.
4+
5+
Many of the algorithms will have to swap elements from the array, vector or list. In order to do that, we will need to create a function that swaps two elements. Here is the function:
6+
7+
```c++
8+
// A function to swap two elements
9+
void swap(int *xp, int *yp) {
10+
int temp = *xp;
11+
*xp = *yp;
12+
*yp = temp;
13+
}
14+
```
15+
16+
## Bubble sort
17+
18+
Bubble sort is the simplest sorting algorithm that works by repeatedly swapping the adjacent elements if they are in wrong order.
19+
20+
```c++
21+
// A function to implement bubble sort
22+
void bubbleSort(int arr[], int n) {
23+
int i, j;
24+
for (i = 0; i < n-1; i++)
25+
// Last i elements are already in place
26+
for (j = 0; j < n-i-1; j++)
27+
if (arr[j] > arr[j+1])
28+
swap(&arr[j], &arr[j+1]);
29+
}
30+
```
31+
32+
As you can see, the algorithm is very simple, but it is not very efficient. It has a time complexity of O(n^2) and a space complexity of O(1).
33+
34+
One of the drawbacks of this algorithm is the sheer amount of swaps. In the worst scenario, it does n^2 swaps, which is a lot. If your machine have slow writes, it will be very slow.
35+
36+
## Insertion sort
37+
38+
Insertion sort is a simple sorting algorithm that works the way we sort playing cards in our hands. You pick one card and insert it in the correct position in the sorted part of the list. You repeat this process until you have sorted the whole list. Here is the code:
39+
40+
```c++
41+
// A function to implement insertion sort
42+
void insertionSort(int arr[], int n) {
43+
int i, key, j;
44+
for (i = 1; i < n; i++) {
45+
key = arr[i];
46+
j = i - 1;
47+
48+
/* Move elements of arr[0..i-1], that are
49+
greater than key, to one position ahead
50+
of their current position */
51+
while (j >= 0 && arr[j] > key) {
52+
arr[j + 1] = arr[j];
53+
j = j - 1;
54+
}
55+
arr[j + 1] = key;
56+
}
57+
}
58+
```
59+
60+
It falls in the same category of algorithms that are very simple, but not very efficient. It has a time complexity of O(n^2) and a space complexity of O(1).
61+
62+
Although it have the same complexity as bubble sort, it is a little bit more efficient. It does less swaps than bubble sort, but it is still not very efficient. It will swap all numbers to the left of the current number, which is a lot of swaps.
63+
64+
## Selection sort
65+
66+
Selection sort is a simple sorting algorithm. This sorting algorithm is an in-place comparison-based algorithm in which the list is divided into two parts, the sorted part at the left end and the unsorted part at the right end. Initially, the sorted part is empty and the unsorted part is the entire list. The smallest element is selected from the unsorted array and swapped with the leftmost element, and that element becomes a part of the sorted array. This process continues moving unsorted array boundary by one element to the right. Here is the code:
67+
68+
```c++
69+
// A function to implement selection sort
70+
void selectionSort(int arr[], int n) {
71+
int i, j, min_idx;
72+
73+
// One by one move boundary of unsorted subarray
74+
for (i = 0; i < n-1; i++) {
75+
// Find the minimum element in unsorted array
76+
min_idx = i;
77+
for (j = i+1; j < n; j++)
78+
if (arr[j] < arr[min_idx])
79+
min_idx = j;
80+
81+
// Swap the found minimum element with the first element
82+
swap(&arr[min_idx], &arr[i]);
83+
}
84+
}
85+
```
86+
87+
It is also a simple algorithm, but it is a little bit more efficient than the previous two. It has a time complexity of O(n^2) and a space complexity of O(1).
88+
89+
It does less swaps than the previous two algorithms, potentially n swaps, but it is still not very efficient. It selects for the current position, the smallest number to the right of it and swaps it with the current number. It does this for every number in the list, which fatally a lot of swaps.
90+
91+
## Merge sort
92+
93+
Merge sort is a divide and conquer algorithm. It divides input array in two halves, calls itself for the two halves and then merges the two sorted halves. Here is the code:
94+
95+
```c++
96+
// recursive merge sort
97+
void mergeSort(int arr[], int l, int r) {
98+
if (l < r) {
99+
// Same as (l+r)/2, but avoids overflow for
100+
// large l and h
101+
int m = l+(r-l)/2;
102+
103+
// Sort first and second halves
104+
mergeSort(arr, l, m);
105+
mergeSort(arr, m+1, r);
106+
107+
merge(arr, l, m, r);
108+
}
109+
}
110+
111+
// merge function
112+
void merge(int arr[], int l, int m, int r) {
113+
int i, j, k;
114+
int n1 = m - l + 1;
115+
int n2 = r - m;
116+
117+
// allocate memory for the sub arrays
118+
int *L = new int[n1];
119+
int *R = new int[n2];
120+
121+
/* Copy data to temp arrays L[] and R[] */
122+
for (i = 0; i < n1; i++)
123+
L[i] = arr[l + i];
124+
for (j = 0; j < n2; j++)
125+
R[j] = arr[m + 1+ j];
126+
127+
/* Merge the temp arrays back into arr[l..r]*/
128+
i = 0; // Initial index of first subarray
129+
j = 0; // Initial index of second subarray
130+
k = l; // Initial index of merged subarray
131+
while (i < n1 && j < n2) {
132+
if (L[i] <= R[j]) {
133+
arr[k] = L[i];
134+
i++;
135+
}
136+
else {
137+
arr[k] = R[j];
138+
j++;
139+
}
140+
k++;
141+
}
142+
143+
/* Copy the remaining elements of L[], if there are any */
144+
while (i < n1) {
145+
arr[k] = L[i];
146+
i++;
147+
k++;
148+
}
149+
150+
/* Copy the remaining elements of R[], if there
151+
are any */
152+
while (j < n2) {
153+
arr[k] = R[j];
154+
j++;
155+
k++;
156+
}
157+
158+
// deallocate memory
159+
delete[] L;
160+
delete[] R;
161+
}
162+
```
163+
164+
It is a very efficient algorithm that needs extra memory to work. It has a time complexity of O(n*log(n)) and a space complexity of O(n). It is a very efficient algorithm, but it is not very simple. It is quite more complex than the previous algorithms. It is a divide and conquer algorithm, which means that it divides the problem in smaller problems and solves them. It divides the list in two halves, sorts them and then merges them. It does this recursively until it has a list of size 1, which is sorted. Then it merges the lists and returns the sorted list.
165+
166+
## Quick sort
167+
168+
Quick sort is a divide and conquer algorithm. It picks an element as pivot and partitions the given array around the picked pivot. Here is the code:
169+
170+
```c++
171+
// recursive quick sort
172+
void quickSort(int arr[], int low, int high) {
173+
if (low < high) {
174+
/* pi is partitioning index, arr[p] is now
175+
at right place */
176+
int pi = partition(arr, low, high);
177+
178+
// Separately sort elements before
179+
// partition and after partition
180+
quickSort(arr, low, pi - 1);
181+
quickSort(arr, pi + 1, high);
182+
}
183+
}
184+
185+
// partition function
186+
int partition (int arr[], int low, int high) {
187+
int pivot = arr[high]; // pivot
188+
int i = (low - 1); // Index of smaller element
189+
190+
for (int j = low; j <= high- 1; j++) {
191+
// If current element is smaller than or
192+
// equal to pivot
193+
if (arr[j] <= pivot) {
194+
i++; // increment index of smaller element
195+
swap(&arr[i], &arr[j]);
196+
}
197+
}
198+
swap(&arr[i + 1], &arr[high]);
199+
return (i + 1);
200+
}
201+
```
202+
203+
It is a very efficient algorithm that don't needs extra memory, which means it is in-place. In average, it can be as fast as mergesort with time complexity of O(n*log(n)), but in the worst case it can be as slow as O(n^2). But it is a better choice if you are not allowed to use extra memory. It is a divide and conquer algorithm, which means that it divides the problem in smaller problems and solves them. It selects a pivot and partitions the list around the pivot. It does this recursively until it has a list of size 1, which is sorted. Then it merges the lists and returns the sorted list.
204+
205+
## Counting sort
206+
207+
Counting sort is a specialized algorithm for sorting numbers. It only works well if you have a small range of numbers. It counts the number of occurrences of each number and then uses the count to place the numbers in the right position. Here is the code:
208+
209+
```c++
210+
// counting sort
211+
void countingSort(int arr[], int n) {
212+
int max=arr[0];
213+
int min[0];
214+
215+
// find the max and min number
216+
for(int i=0; i<n; i++) {
217+
if(arr[i]>max) {
218+
max=arr[i];
219+
}
220+
if(arr[i]<min) {
221+
min=arr[i];
222+
}
223+
}
224+
225+
// allocate memory for the count array
226+
int *count = new int[max-min+1];
227+
228+
// initialize the count array
229+
for(int i=0; i<max-min+1; i++) {
230+
count[i]=0;
231+
}
232+
233+
// count the number of occurrences of each number
234+
for(int i=0; i<n; i++) {
235+
count[arr[i]-min]++;
236+
}
237+
238+
// place the numbers in the right position
239+
int j=0;
240+
for(int i=0; i<max-min+1; i++) {
241+
while(count[i]>0) {
242+
arr[j]=i+min;
243+
j++;
244+
count[i]--;
245+
}
246+
}
247+
248+
// deallocate memory
249+
delete[] count;
250+
}
251+
```
252+
253+
Counting sort is a very efficient sorting algorithm which do not rely on comparisons. It has a time complexity of O(n+k) where k is the range of numbers. Space complexity is O(k) which means it is not an in-place sorting algorithm. It is a very efficient algorithm, but it is not very simple. It counts the number of occurrences of each number and then uses the count to place the numbers in the right position.
254+
255+
## Radix sort
256+
257+
Radix sort is a specialized algorithm for sorting numbers. It only works well if you have a small range of numbers. It sorts the numbers by their digits. Here is the code:
258+
259+
```c++
260+
// Radix sort
261+
void radixSort(int arr[], int n) {
262+
int max=arr[0];
263+
264+
// find the max number
265+
for(int i=0; i<n; i++) {
266+
if(arr[i]>max) {
267+
max=arr[i];
268+
}
269+
}
270+
271+
// allocate memory for the count array
272+
int *count = new int[10]; // 10 digits
273+
274+
// allocate memory for the output array
275+
int *output = new int[n];
276+
277+
// do counting sort for every digit
278+
for(int exp=1; max/exp>0; exp*=10) {
279+
// initialize the count array
280+
for(int i=0; i<10; i++) {
281+
count[i]=0;
282+
}
283+
284+
// count the number of occurrences of each number
285+
for(int i=0; i<n; i++) {
286+
count[(arr[i]/exp)%10]++;
287+
}
288+
289+
// change count[i] so that count[i] now contains actual position of this digit in output[]
290+
for(int i=1; i<10; i++) {
291+
count[i]+=count[i-1];
292+
}
293+
294+
// build the output array
295+
for(int i=n-1; i>=0; i--) {
296+
output[count[(arr[i]/exp)%10]-1]=arr[i];
297+
count[(arr[i]/exp)%10]--;
298+
}
299+
300+
// copy the output array to the input array
301+
for(int i=0; i<n; i++) {
302+
arr[i]=output[i];
303+
}
304+
}
305+
}
306+
```
307+
308+
Radix sort is just a counting sort that is applied to every digit. It has a time complexity of O(n*k) where k is the number of digits.
309+
310+
## Conclusion
311+
312+
This is the first time we will talk about efficiency, and for now on, you will start evaluating and taking care about your algorithms' efficiency. You will learn more about efficiency in the next semester and course when we cover data structures.

portfolio/12-promoting/README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,15 @@ Before creating and running a promotion campaigns, we need to define the audienc
3333
To reach specific audiences, we need to be in the same platform they are. For example:
3434
- Game players: Steam, Twitch, YouTube, itchio, GameJolt, Discord;
3535
- Journalists: Twitter, LinkedIn;
36-
- Investors: AngelList, LinkedIn;
36+
- Investors: AngelList, Ycombinator, LinkedIn, Crunchbase;
3737
- Communities: Reddit, Discord, Facebook, Twitter;
3838
- Recruiters: mostly Linkedin.
3939

4040
Social media is a great way to promote yourself as a game developer. You can use it to share your work, your thoughts, your ideas, and your opinions. You can also use it to connect with other developers and learn from them.
4141

4242
Here goes my opinion about the most important platforms:
4343

44-
- Twitter: it is the best and easy way to communicate with anyone in the world. The distance between to reach anyone is zero. And it hawe an awesome tagging structure. It is a great way to share your thoughts and ideas and ask for feedbacks. It is a great way to connect with other developers and learn from them. You can also use it to share your work and promote your games.
44+
- Twitter: it is the best and easy way to communicate with anyone in the world. The distance between to reach anyone is zero. And it has an awesome tagging structure. It is a great way to share your thoughts and ideas and ask for feedbacks. It is a great way to connect with other developers and learn from them. You can also use it to share your work and promote your games.
4545
- LinkedIn: It is a great way to connect with recruiters and hiring managers. Usually you will see other developers publishing their thoughts and ideas, so try to post relevant comments on their publications to get noticed and improve your visibility.
4646
- Facebook: It is mostly a general purpose social media. You can use it to connect with your friends and family, and collect feedbacks for your content. It is a great way to promote your finished games.
4747
- Instagram and Tiktok: Are more focused in fast, small and visual content. You can use it to promote your games and your work, but it is not the best way to share your thoughts and ideas.
@@ -52,7 +52,7 @@ Here goes my opinion about the most important platforms:
5252

5353
## Mediums
5454

55-
The mediums are: Social media, Blogs, Email, Podcasts, Videos, Events, Conferences, Meetups, Workshops, Webinars, Webcasts, and more.
55+
The mediums are: Social media posts, Blog posts, Email, Podcasts, Videos, Events, Conferences, Meetups, Workshops, Webinars, Webcasts, and more.
5656

5757
For each type of medium, we need to plan the content, the frequency, and the duration. We have very nice tools to help us with that, like [Buffer](https://buffer.com/), [Hootsuite](https://hootsuite.com/) and many others.
5858

0 commit comments

Comments
 (0)