mirror of
https://github.com/TheAlgorithms/C
synced 2024-11-22 13:31:21 +03:00
feat: created heap_sort_2.c (#809)
* feat: created heap_sort_2.c * Update sorting/heap_sort_2.c Co-authored-by: David Leal <halfpacho@gmail.com> * Update sorting/heap_sort_2.c Co-authored-by: David Leal <halfpacho@gmail.com> * Update sorting/heap_sort_2.c Co-authored-by: David Leal <halfpacho@gmail.com> * Update sorting/heap_sort_2.c Co-authored-by: David Leal <halfpacho@gmail.com> * Update sorting/heap_sort_2.c Co-authored-by: David Leal <halfpacho@gmail.com> * Update sorting/heap_sort_2.c Co-authored-by: David Leal <halfpacho@gmail.com> * updating DIRECTORY.md * added deatiled description of the algorithm * Update sorting/heap_sort_2.c Co-authored-by: David Leal <halfpacho@gmail.com> * Update sorting/heap_sort_2.c Co-authored-by: David Leal <halfpacho@gmail.com> * Apply suggestions from code review * Apply suggestions from code review Co-authored-by: David Leal <halfpacho@gmail.com> Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com>
This commit is contained in:
parent
1a92f523fa
commit
e0c6f6e403
@ -376,6 +376,7 @@
|
|||||||
* [Cycle Sort](https://github.com/TheAlgorithms/C/blob/master/sorting/cycle_sort.c)
|
* [Cycle Sort](https://github.com/TheAlgorithms/C/blob/master/sorting/cycle_sort.c)
|
||||||
* [Gnome Sort](https://github.com/TheAlgorithms/C/blob/master/sorting/gnome_sort.c)
|
* [Gnome Sort](https://github.com/TheAlgorithms/C/blob/master/sorting/gnome_sort.c)
|
||||||
* [Heap Sort](https://github.com/TheAlgorithms/C/blob/master/sorting/heap_sort.c)
|
* [Heap Sort](https://github.com/TheAlgorithms/C/blob/master/sorting/heap_sort.c)
|
||||||
|
* [Heap Sort 2](https://github.com/TheAlgorithms/C/blob/master/sorting/heap_sort_2.c)
|
||||||
* [Insertion Sort](https://github.com/TheAlgorithms/C/blob/master/sorting/insertion_sort.c)
|
* [Insertion Sort](https://github.com/TheAlgorithms/C/blob/master/sorting/insertion_sort.c)
|
||||||
* [Insertion Sort Recursive](https://github.com/TheAlgorithms/C/blob/master/sorting/insertion_sort_recursive.c)
|
* [Insertion Sort Recursive](https://github.com/TheAlgorithms/C/blob/master/sorting/insertion_sort_recursive.c)
|
||||||
* [Merge Sort](https://github.com/TheAlgorithms/C/blob/master/sorting/merge_sort.c)
|
* [Merge Sort](https://github.com/TheAlgorithms/C/blob/master/sorting/merge_sort.c)
|
||||||
|
156
sorting/heap_sort_2.c
Normal file
156
sorting/heap_sort_2.c
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* @author [Dhruv Pasricha](https://github.com/DhruvPasricha)
|
||||||
|
* @brief [Heap Sort](https://en.wikipedia.org/wiki/Heapsort) implementation
|
||||||
|
* @details
|
||||||
|
* Heap-sort is a comparison-based sorting algorithm.
|
||||||
|
* Heap-sort can be thought of as an improved selection sort:
|
||||||
|
* like selection sort, heap sort divides its input into a sorted
|
||||||
|
* and an unsorted region, and it iteratively shrinks the unsorted
|
||||||
|
* region by extracting the largest element from it and inserting
|
||||||
|
* it into the sorted region.
|
||||||
|
*
|
||||||
|
* Unlike selection sort,
|
||||||
|
* heap sort does not waste time with a linear-time scan of the
|
||||||
|
* unsorted region; rather, heap sort maintains the unsorted region
|
||||||
|
* in a heap data structure to more quickly find the largest element
|
||||||
|
* in each step.
|
||||||
|
* Time Complexity : O(Nlog(N))
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h> /// for assert
|
||||||
|
#include <stdio.h> /// for IO operations
|
||||||
|
#include <stdlib.h> /// for dynamic memory allocation
|
||||||
|
#include <time.h> /// for random numbers generation
|
||||||
|
#include <inttypes.h> /// for uint8_t, int8_t
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Swapped two numbers using pointer
|
||||||
|
* @param first pointer of first number
|
||||||
|
* @param second pointer of second number
|
||||||
|
*/
|
||||||
|
void swap(int8_t *first, int8_t *second)
|
||||||
|
{
|
||||||
|
int8_t temp = *first;
|
||||||
|
*first = *second;
|
||||||
|
*second = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief heapifyDown Adjusts new root to the correct position in the heap
|
||||||
|
* This heapify procedure can be thought of as building a heap from
|
||||||
|
* the top down by successively shifting downward to establish the
|
||||||
|
* heap property.
|
||||||
|
* @param arr array to be sorted
|
||||||
|
* @param size size of array
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
void heapifyDown(int8_t *arr, const uint8_t size)
|
||||||
|
{
|
||||||
|
uint8_t i = 0;
|
||||||
|
|
||||||
|
while (2 * i + 1 < size)
|
||||||
|
{
|
||||||
|
uint8_t maxChild = 2 * i + 1;
|
||||||
|
|
||||||
|
if (2 * i + 2 < size && arr[2 * i + 2] > arr[maxChild])
|
||||||
|
{
|
||||||
|
maxChild = 2 * i + 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (arr[maxChild] > arr[i])
|
||||||
|
{
|
||||||
|
swap(&arr[i], &arr[maxChild]);
|
||||||
|
i = maxChild;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief heapifyUp Adjusts arr[i] to the correct position in the heap
|
||||||
|
* This heapify procedure can be thought of as building a heap from
|
||||||
|
* the bottom up by successively shifting upward to establish the
|
||||||
|
* heap property.
|
||||||
|
* @param arr array to be sorted
|
||||||
|
* @param i index of the pushed element
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
void heapifyUp(int8_t *arr, uint8_t i)
|
||||||
|
{
|
||||||
|
while (i > 0 && arr[i / 2] < arr[i])
|
||||||
|
{
|
||||||
|
swap(&arr[i / 2], &arr[i]);
|
||||||
|
i /= 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Heap Sort algorithm
|
||||||
|
* @param arr array to be sorted
|
||||||
|
* @param size size of the array
|
||||||
|
* @returns void
|
||||||
|
*/
|
||||||
|
void heapSort(int8_t *arr, const uint8_t size)
|
||||||
|
{
|
||||||
|
if (size <= 1)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
// Pushing `arr[i]` to the heap
|
||||||
|
|
||||||
|
/*heapifyUp Adjusts arr[i] to the correct position in the heap*/
|
||||||
|
heapifyUp(arr, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint8_t i = size - 1; i >= 1; i--)
|
||||||
|
{
|
||||||
|
// Moving current root to the end
|
||||||
|
swap(&arr[0], &arr[i]);
|
||||||
|
|
||||||
|
// `heapifyDown` adjusts new root to the correct position in the heap
|
||||||
|
heapifyDown(arr, i);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Self-test implementations
|
||||||
|
* @returns void
|
||||||
|
*/
|
||||||
|
static void test()
|
||||||
|
{
|
||||||
|
const uint8_t size = 10;
|
||||||
|
int8_t *arr = (int8_t *)calloc(size, sizeof(int8_t));
|
||||||
|
|
||||||
|
/* generate size random numbers from 0 to 100 */
|
||||||
|
for (uint8_t i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
arr[i] = rand() % 100;
|
||||||
|
}
|
||||||
|
heapSort(arr, size);
|
||||||
|
for (uint8_t i = 0; i < size - 1; ++i)
|
||||||
|
{
|
||||||
|
assert(arr[i] <= arr[i + 1]);
|
||||||
|
}
|
||||||
|
free(arr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Main function
|
||||||
|
* @returns 0 on exit
|
||||||
|
*/
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// Intializes random number generator
|
||||||
|
srand(time(NULL));
|
||||||
|
|
||||||
|
test(); // run self-test implementations
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user