mirror of
https://git.adityakumar.xyz/dsa.git
synced 2024-12-03 14:22:52 +00:00
add selection sort
This commit is contained in:
parent
810d524abc
commit
8b6289d4f6
4 changed files with 241 additions and 0 deletions
18
.gitignore
vendored
Normal file
18
.gitignore
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
# ---> Hugo
|
||||
# Generated files by hugo
|
||||
/public/
|
||||
/resources/_gen/
|
||||
/assets/jsconfig.json
|
||||
hugo_stats.json
|
||||
|
||||
# Executable may be added to repository
|
||||
hugo.exe
|
||||
hugo.darwin
|
||||
hugo.linux
|
||||
|
||||
# Temporary lock file while building
|
||||
/.hugo_build.lock
|
||||
|
||||
# Ignore swap files
|
||||
*.swp
|
||||
*~
|
9
content/_index.md
Normal file
9
content/_index.md
Normal file
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
title: "Data Strcutures and Algorithms"
|
||||
date: 2024-05-28T08:15:27+05:30
|
||||
type: docs
|
||||
---
|
||||
|
||||
# Data Structures and Algorithms
|
||||
|
||||
On this website, I document my explorations into the realm of Data Structures and Algorithms to serve as a personal resource for future reflection.
|
68
content/docs/dsa/sorting/_index.md
Normal file
68
content/docs/dsa/sorting/_index.md
Normal file
|
@ -0,0 +1,68 @@
|
|||
---
|
||||
title: "Sorting"
|
||||
date: 2024-05-28T07:49:20+05:30
|
||||
bookCollapseSection: true
|
||||
---
|
||||
|
||||
# Sorting
|
||||
|
||||
This section contains entries related to sorting algorithms.
|
||||
|
||||
Sorting in data structures and algorithms involves rearranging a collection of items, such as
|
||||
numbers or strings, into a sequence or list where the elements are organized according to a
|
||||
particular criterion (e.g., ascending numerical value). Various algorithms have been developed for
|
||||
this purpose, each with its own advantages and trade-offs in terms of time complexity, space
|
||||
efficiency, stability, adaptability, and ease of implementation. Some widely known sorting
|
||||
algorithms include:
|
||||
|
||||
1. **Bubble Sort** - A simple comparison-based algorithm that repeatedly steps through the list,
|
||||
compares adjacent elements, and swaps them if they are in the wrong order. It has a time complexity
|
||||
of O(n^2) in its average and worst cases.
|
||||
|
||||
2. **Selection Sort** - This algorithm divides the input list into two parts: a sorted sublist of
|
||||
items that are built up from left to right at the front (or beginning) of the list, and an unsorted
|
||||
sublist. On each iteration, it selects the smallest or largest element (depending on sorting order)
|
||||
from the unsorted sublist and moves that element to the end of the sorted sublist. Its time
|
||||
complexity is O(n^2).
|
||||
|
||||
3. **Insertion Sort** - Builds the final sorted array one item at a time. It has an average and
|
||||
worst-case performance of O(n^2), but it's efficient for small datasets or nearly sorted arrays,
|
||||
with best-case time complexity being O(n).
|
||||
|
||||
4. **Merge Sort** - A divide-and-conquer algorithm that divides the input array into two halves,
|
||||
recursively sorts them, and then merges the two sorted halves together. It has a time complexity of
|
||||
O(n log n) in all cases.
|
||||
|
||||
5. **Quick Sort** - Also utilizes a divide-and-conquer strategy by selecting a 'pivot' element from
|
||||
the array and partitioning the other elements into two sub-arrays, according to whether they are
|
||||
less than or greater than the pivot. The time complexity in average cases is O(n log n), but it can
|
||||
degrade to O(n^2) if the smallest or largest element is always chosen as the pivot.
|
||||
|
||||
6. **Heap Sort** - Builds a heap data structure from the input data and then repeatedly extracts
|
||||
the maximum (or minimum) element from the heap, swapping it with the last item in the unsorted
|
||||
portion of the array, and re-heaping the reduced array. The time complexity is O(n log n).
|
||||
|
||||
7. **Radix Sort** - This non-comparative integer sorting algorithm sorts data with integer keys by
|
||||
grouping keys by the individual digits which share the same significant position and value (radix).
|
||||
It has a linear time complexity of O(nk) where k is the number of passes of the sorting algorithm
|
||||
and n is the number of elements.
|
||||
|
||||
8. **Counting Sort** - Suitable for sorting integer arrays when the range of potential items in the
|
||||
input (i.e., their possible key values) is relatively small compared to the number of items. Its
|
||||
time complexity varies based on the specific implementation but generally has a linear time
|
||||
complexity, O(n+k), where k is the range of the input.
|
||||
|
||||
9. **Bucket Sort** - Works by distributing elements into several 'buckets' and then sorting these
|
||||
buckets individually using a different sorting algorithm or by recursively applying bucket sort to
|
||||
each bucket. Its time complexity can be as good as O(n+k) where n is the number of elements and k
|
||||
is the number of buckets, but it often performs better than O(n log n).
|
||||
|
||||
10. **Timsort** - A hybrid sorting algorithm derived from merge sort and insertion sort designed to
|
||||
perform well on many kinds of real-world data. It's used as the default sort in Python and Java.
|
||||
Timsort has a time complexity of O(n log n) for average and worst cases.
|
||||
|
||||
The choice of a particular sorting algorithm depends on several factors, including but not limited
|
||||
to: the size and nature of the dataset, the computational resources available (such as CPU and
|
||||
memory), the desired level of stability in the output, whether parallel computing is involved, etc.
|
||||
|
||||
{{<section summary >}}
|
146
content/docs/dsa/sorting/selection-sort.md
Normal file
146
content/docs/dsa/sorting/selection-sort.md
Normal file
|
@ -0,0 +1,146 @@
|
|||
---
|
||||
title: "Selection Sort"
|
||||
date: 2024-05-28T07:49:30+05:30
|
||||
---
|
||||
|
||||
# Selection Sort
|
||||
|
||||
Selection Sort is a simple comparison-based sorting algorithm. It operates by repeatedly finding
|
||||
the minimum element (considering ascending order) from the unsorted part of an array and putting it
|
||||
at the beginning. The process involves dividing the input list into two parts: a sorted sublist
|
||||
which is built up from left to right, and an unsorted sublist where elements are not yet in their
|
||||
final position.
|
||||
|
||||
<!--more-->
|
||||
|
||||
## Algorithm
|
||||
|
||||
Here's how Selection Sort works step by step:
|
||||
|
||||
1. Start with the first element of the array as the minimum.
|
||||
|
||||
2. Compare this "current" minimum with the rest of the array to find a new minimum.
|
||||
|
||||
3. Once you have found the true minimum, swap it with the value at the current position.
|
||||
|
||||
4. Move one position ahead in the array and consider this element as part of the unsorted segment
|
||||
while treating the remaining elements as the sorted sublist.
|
||||
|
||||
5. Repeat steps 2-4 until the entire list is sorted.
|
||||
|
||||
The algorithm's time complexity is O(n<sup>2</sup>) for all cases (worst, average, and best), making it
|
||||
inefficient on large lists compared to more advanced algorithms like quicksort, mergesort or
|
||||
heapsort. However, Selection Sort has its advantages such as simplicity and performing only a
|
||||
minimal number of swaps, which can be beneficial when the cost of swap is high.
|
||||
|
||||
## Code
|
||||
|
||||
Here is an implementation in C++.
|
||||
|
||||
```cpp
|
||||
import <print>;
|
||||
import <vector>;
|
||||
|
||||
constexpr auto sort(std::vector<ssize_t> &vec) -> void {
|
||||
for (auto it1{vec.begin()}; it1 < vec.end(); ++it1) {
|
||||
auto it{it1};
|
||||
for (auto it2{it1 + 1}; it2 < vec.end(); ++it2) {
|
||||
if (*it2 < *it) {
|
||||
it = it2;
|
||||
}
|
||||
}
|
||||
auto temp{*it1};
|
||||
*it1 = *it;
|
||||
*it = temp;
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
std::vector<ssize_t> v{4, 7, 3, 7, 2, 7, 4, 64, 32, 65,
|
||||
32, 4, 5, 5, 6456, 4, 5, 53, 5};
|
||||
sort(v);
|
||||
|
||||
for (const auto &a : v) {
|
||||
std::print("{} ", a);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Explanation
|
||||
|
||||
### Function Signature
|
||||
|
||||
```cpp
|
||||
constexpr auto sort(std::vector<ssize_t> &vec) -> void
|
||||
```
|
||||
|
||||
- `constexpr`: This keyword indicates that the function can be evaluated at compile time if provided with constant expressions. This is useful for performance optimization in some cases.
|
||||
- `auto sort`: Uses the auto keyword to automatically deduce the return type. In this case, the return type is explicitly specified as `void`.
|
||||
- `(std::vector<ssize_t> &vec)`: The function takes a reference to a `std::vector` of `ssize_t` integers as its parameter. Using a reference avoids copying the vector and allows the function to modify the original vector.
|
||||
- `-> void`: This specifies the return type of the function, which is `void` (meaning it doesn't return a value).
|
||||
|
||||
### Function Body
|
||||
|
||||
```cpp
|
||||
{
|
||||
for (auto it1{vec.begin()}; it1 < vec.end(); ++it1) {
|
||||
auto it{it1};
|
||||
for (auto it2{it1 + 1}; it2 < vec.end(); ++it2) {
|
||||
if (*it2 < *it) {
|
||||
it = it2;
|
||||
}
|
||||
}
|
||||
auto temp{*it1};
|
||||
*it1 = *it;
|
||||
*it = temp;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
1. **Outer Loop (Selection Sort)**:
|
||||
|
||||
```cpp
|
||||
for (auto it1{vec.begin()}; it1 < vec.end(); ++it1)
|
||||
```
|
||||
|
||||
- This loop iterates over each element of the vector from the beginning to the end.
|
||||
- `it1` is an iterator starting from the beginning of the vector and moving towards the end.
|
||||
|
||||
2. **Inner Loop (Finding Minimum)**
|
||||
|
||||
```cpp
|
||||
auto it{it1};
|
||||
for (auto it2{it1 + 1}; it2 < vec.end(); ++it2) {
|
||||
if (*it2 < *it) {
|
||||
it = it2;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- The inner loop starts from the next element after `it1` and iterates to the end of the vector.
|
||||
- `it` initially points to `it1`, which is the current element in the outer loop.
|
||||
- `it2` iterates over the remaining elements to find the smallest element.
|
||||
- If `*it2` (the value pointed to by `it2`) is smaller than `*it` (the value pointed to by `it`), `it` is updated to point to `it2`.
|
||||
|
||||
3. **Swapping Elements**:
|
||||
|
||||
```cpp
|
||||
auto temp{*it1};
|
||||
*it1 = *it;
|
||||
*it = temp;
|
||||
```
|
||||
|
||||
- After finding the smallest element in the unsorted portion of the vector, the smallest element (pointed to by `it`) is swapped with the element at the position `it1`.
|
||||
- `temp` temporarily holds the value of `*it1`.
|
||||
- `*it1` is set to `*it` (the smallest element found).
|
||||
- `*it` is then set to `temp` to complete the swap.
|
||||
|
||||
## Output
|
||||
|
||||
```console
|
||||
❯ ./main
|
||||
2 3 4 4 4 4 5 5 5 5 7 7 7 32 32 53 64 65 6456 [ble: EOF]
|
||||
```
|
Loading…
Reference in a new issue