From 304d06f4f6ed58ccc2088f33c9dc1604fe4ee862 Mon Sep 17 00:00:00 2001
From: jonas <jonas.stirnemann@etu.hesge.ch>
Date: Wed, 10 Nov 2021 12:00:24 +0100
Subject: [PATCH] Added sorts insertion and bubble

---
 tableaux_uni/.vscode/settings.json |   5 +
 tableaux_uni/Makefile              |   2 +-
 tableaux_uni/bin/main              | Bin 17072 -> 45512 bytes
 tableaux_uni/include/jrandom.h     |   8 +-
 tableaux_uni/include/jtableaux.h   |  32 +++-
 tableaux_uni/include/sort.h        |  22 +++
 tableaux_uni/src/jrandom.c         |   5 +-
 tableaux_uni/src/jtableaux.c       | 297 +++++++++++++++++++++++++----
 tableaux_uni/src/main.c            |  50 +----
 tableaux_uni/src/sort.c            | 145 ++++++++++++++
 10 files changed, 475 insertions(+), 91 deletions(-)
 create mode 100644 tableaux_uni/.vscode/settings.json
 create mode 100644 tableaux_uni/include/sort.h
 create mode 100644 tableaux_uni/src/sort.c

diff --git a/tableaux_uni/.vscode/settings.json b/tableaux_uni/.vscode/settings.json
new file mode 100644
index 0000000..28dbe18
--- /dev/null
+++ b/tableaux_uni/.vscode/settings.json
@@ -0,0 +1,5 @@
+{
+    "files.associations": {
+        "jrandom.h": "c"
+    }
+}
\ No newline at end of file
diff --git a/tableaux_uni/Makefile b/tableaux_uni/Makefile
index 2a3a263..0abe67f 100644
--- a/tableaux_uni/Makefile
+++ b/tableaux_uni/Makefile
@@ -1,5 +1,5 @@
 CC       := gcc
-CC_FLAGS := -Wall -Wextra
+CC_FLAGS := -Wall -Wextra -fsanitize=address -g
 
 BIN     	:= bin
 SRC     	:= src
diff --git a/tableaux_uni/bin/main b/tableaux_uni/bin/main
index b6e316f2850932719f1506b91f64e01cc8826d35..ba299c93216bad3b8d45e5eb56c44216c76f44ee 100755
GIT binary patch
literal 45512
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

literal 17072
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

diff --git a/tableaux_uni/include/jrandom.h b/tableaux_uni/include/jrandom.h
index 8b64fa0..e021697 100644
--- a/tableaux_uni/include/jrandom.h
+++ b/tableaux_uni/include/jrandom.h
@@ -5,12 +5,18 @@
 	! DESCRIPTION
 */
 
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <math.h>
+
 #ifndef _JRANDOM_H_
 #define _JRANDOM_H_
 
 // DEFINES
 
 // PROTOTYPE FUNCTIONS
-uint64_t getRandomNumber(uint64_t highLimit, uint64_t lowLimit);
+uint64_t getRandomNumber(uint64_t lowLimit, uint64_t highLimit);
 
 #endif
\ No newline at end of file
diff --git a/tableaux_uni/include/jtableaux.h b/tableaux_uni/include/jtableaux.h
index 974ab81..be90f1a 100644
--- a/tableaux_uni/include/jtableaux.h
+++ b/tableaux_uni/include/jtableaux.h
@@ -5,21 +5,43 @@
 	! DESCRIPTION
 */
 
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <math.h>
+#include <string.h>
+
 #ifndef _JTABLEAUX_H_
 #define _JTABLEAUX_H_
 
 // DEFINES
 
 // PROTOTYPE FUNCTIONS
-void showTab(uint64_t *tab, uint64_t tabSize);
-void fillTabRandom(uint64_t *tab, uint64_t tabSize, uint64_t min, uint64_t max);
+uint64_t* createTab(uint64_t tabSize);
+void destroyTab(uint64_t * tab);
+uint64_t* sumTabs(uint64_t* tab1, uint64_t* tab2, uint64_t tabSize);
+uint64_t* mulTabs(uint64_t* tab1, uint64_t multiplier, uint64_t tabSize);
+double* convertToDouble(uint64_t* tab, uint64_t tabSize);
+
+
+void showTab(uint64_t *tab, uint64_t tabSize, char* text);
+void fillTabRandomValues(uint64_t *tab, uint64_t tabSize, uint64_t min, uint64_t max);
 void fillTabWithZeroes(uint64_t *tab, uint64_t tabSize);
+void fillTabUniformRandom(uint64_t* tab, uint64_t tabSize);
 
-uint64_t getTabSmallestValue(uint64_t *tab, uint64_t tabSize);
-uint64_t getTabBiggestValue(uint64_t *tab, uint64_t tabSize);
+void shuffleTab(uint64_t* tab, uint64_t tabSize, uint64_t numberOfSwaps);
+void losslessShifTab(uint64_t* tab, uint64_t tabSize, uint64_t n);
+
+uint64_t getTabSmallestValueIndex(uint64_t *tab, uint64_t tabSize);
+uint64_t getTabBiggestValueIndex(uint64_t *tab, uint64_t tabSize);
 uint64_t getIndexOfTabElement(uint64_t *tab, uint64_t tabSize, uint64_t element);
+uint64_t getNumberOfSmallerElements(uint64_t* tab, uint64_t tabSize, uint64_t valElement);
+
 
 void sortTabLTH(uint64_t *tab, uint64_t tabSize);
+void sortInsertionLTH(uint64_t *tab, uint64_t tabSize);
+void sortInsertionHTL(uint64_t *tab, uint64_t tabSize);
 void countOccurence(uint64_t *tab, uint64_t tabSize, uint64_t *occurences, uint64_t sizeOfTabOcc);
 
 double getMeanOfTab(uint64_t *tab, uint64_t tabSize);
@@ -29,4 +51,6 @@ uint64_t getMedianOfTab(uint64_t *tab, uint64_t tabSize);
 void showVerticalHistoOfTab(uint64_t *tab, uint64_t tabSize);
 void showHorizonalHistoOfTab(uint64_t *occurences, uint64_t tabSize);
 
+void swapIndex(uint64_t* tab, uint64_t index1, uint64_t index2);
+
 #endif
\ No newline at end of file
diff --git a/tableaux_uni/include/sort.h b/tableaux_uni/include/sort.h
new file mode 100644
index 0000000..9caff8b
--- /dev/null
+++ b/tableaux_uni/include/sort.h
@@ -0,0 +1,22 @@
+/*
+	* HEADER SORT
+	* Author : Jonas S.
+	* Date   : 10/11/2021
+	! DESCRIPTION
+*/
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+#ifndef _SORT_H_
+#define _SORT_H_
+
+// DEFINES
+
+// PROTOTYPE FUNCTIONS
+void quicksort(uint64_t* tab, uint64_t tabSize, uint64_t first, uint64_t last);
+
+#endif
\ No newline at end of file
diff --git a/tableaux_uni/src/jrandom.c b/tableaux_uni/src/jrandom.c
index 49ec99c..8fe8ed4 100644
--- a/tableaux_uni/src/jrandom.c
+++ b/tableaux_uni/src/jrandom.c
@@ -6,6 +6,7 @@
 */
 
 #include <stdlib.h>
+#include <stdio.h>
 #include <stdint.h>
 #include <time.h>
 
@@ -14,11 +15,11 @@
 /**
  * @brief Returns a random number
  * 
+ * @param lowLimit  
  * @param highLimit 
- * @param lowLimit 
  * @return uint64_t 
  */
-uint64_t getRandomNumber(uint64_t highLimit, uint64_t lowLimit)
+uint64_t getRandomNumber(uint64_t lowLimit, uint64_t highLimit)
 {
 	return (rand() % (highLimit - lowLimit + 1) + lowLimit);
 }
\ No newline at end of file
diff --git a/tableaux_uni/src/jtableaux.c b/tableaux_uni/src/jtableaux.c
index 5ddf3d3..c2b4ad6 100644
--- a/tableaux_uni/src/jtableaux.c
+++ b/tableaux_uni/src/jtableaux.c
@@ -2,26 +2,81 @@
 	* CODE TABLEAUX_UNI
 	* Author : Jonas S.
 	* Date   : 12/10/2021
-	! Gestion de base de tableaux
-	! https://malaspinas.academy/prog_seq_c_tp/tableaux_unidimensionnels/index.html
+	! Gestion des tableaux avec malloc
+	! https://malaspinas.academy/prog_seq_c_tp/tableaux_unidimensionnels_dyn/tableaux_unidimensionnels_dyn.pdf
 */
 
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <math.h>
-#include "../include/jtableaux.h"
 #include "../include/jrandom.h"
+#include "../include/jtableaux.h"
+
+
+
+
+/**
+ * @brief Swap the values between to indexes of an array
+ * 
+ * @param tab
+ * @param index1
+ * @param index2
+ */
+void swapIndex(uint64_t* tab, uint64_t index1, uint64_t index2)
+{
+	uint64_t tmp;
+
+	tmp = tab[index1];
+	tab[index1] = tab[index2];
+	tab[index2] = tmp;
+}
+
+/**
+ * @brief Swap random indexe's values
+ * 
+ * @param tab
+ * @param tabSize
+ */
+void randomSwap(uint64_t* tab, uint64_t tabSize)
+{
+	swapIndex(tab, getRandomNumber(0, tabSize-1),  getRandomNumber(0, tabSize-1));
+}
+
+/**
+ * @brief Allocate memory for a tab of given size
+ * 		  and returns a pointer to it
+ * 
+ * @param tabSize
+ * @return uint64_t*
+ */
+uint64_t* createTab(uint64_t tabSize)
+{
+	uint64_t* tab = malloc(tabSize * sizeof(uint64_t));	
+	if(tab == NULL)
+	{
+		printf("MEMORY ALLOCATION FAILED\n");
+		exit(0);
+	}
+	return tab;
+}
+
+/**
+ * @brief Dealocate the memory of a given tab
+ * 
+ * @param tab
+ */
+void destroyTab(uint64_t * tab)
+{
+	free(tab);	
+}
 
 /**
  * @brief Print an array in the terminal
  * 
  * @param tab
  * @param tabSize
+ * @param text TAB NAME
  */
-void showTab(uint64_t *tab, uint64_t tabSize)
+void showTab(uint64_t *tab, uint64_t tabSize, char* text)
 {
+	printf("%s : ", text);
 	for(uint64_t i = 0; i < tabSize; i++)
 	{	
 		printf(" %ld,", tab[i]);
@@ -37,14 +92,84 @@ void showTab(uint64_t *tab, uint64_t tabSize)
  * @param min 
  * @param max
  */
-void fillTabRandom(uint64_t *tab, uint64_t tabSize, uint64_t min, uint64_t max)
+void fillTabRandomValues(uint64_t *tab, uint64_t tabSize, uint64_t min, uint64_t max)
 {
 	for(uint64_t i = 0; i < tabSize; i++)
 	{
-		tab[i] = getRandomNumber(max, min);
+		tab[i] = getRandomNumber(min, max);
+	}
+}
+
+/**
+ * @brief Shuffle the values in a tab
+ * 
+ * @param tab
+ * @param tabSize
+ * @param numberOfSwaps
+ */
+void shuffleTab(uint64_t* tab, uint64_t tabSize, uint64_t numberOfSwaps)
+{
+	for(uint64_t i = 0; i < numberOfSwaps; i++)
+	{
+		randomSwap(tab, tabSize);
 	}
 }
 
+/**
+ * @brief Shift the tab pushing last element to first
+ * 		  Shifting to the right
+ * 
+ * @param tab
+ * @param tabSize
+ * @param n Number of shifts
+ */
+void losslessShifTab(uint64_t* tab, uint64_t tabSize, uint64_t n)
+{
+	uint64_t lastValue;;
+
+	for(uint64_t j = 0; j < n; j++)
+	{
+		lastValue = tab[tabSize-1];
+		// Shift once
+		for (uint64_t i = tabSize - 1; i > 0; i--)
+		{
+			tab[i] = tab[i - 1];
+		}
+		tab[0] = lastValue;
+	}
+}
+
+/**
+ * @brief swap The lowest value of a given tab 
+ * 		  with the last
+ * 
+ * @param tab
+ * @param tabSize
+ */
+void swapLowestWithLast(uint64_t* tab, uint64_t tabSize)
+{
+	swapIndex(tab, getTabSmallestValueIndex(tab, tabSize), tabSize - 1);
+}
+
+
+/**
+ * @brief Fill a tab with unique value randomly spaced
+ * 
+ * @param tab
+ * @param tabSize
+ */
+void fillTabUniformRandom(uint64_t* tab, uint64_t tabSize)
+{
+	// Fill tab with values from 0 to tabSize
+	// randomly swap 2 indexes n times 
+	for (uint64_t i = 0; i < tabSize; i++)
+	{
+		tab[i] = i;
+	}
+
+	shuffleTab(tab, tabSize, 1000);
+}
+
 /**
  * @brief Get smallest value's index of an array
  * 
@@ -52,7 +177,7 @@ void fillTabRandom(uint64_t *tab, uint64_t tabSize, uint64_t min, uint64_t max)
  * @param tabSize
  * @return uint64_t
  */
-uint64_t getTabSmallestValue(uint64_t *tab, uint64_t tabSize)
+uint64_t getTabSmallestValueIndex(uint64_t *tab, uint64_t tabSize)
 {
 	uint64_t value = tab[0];
 	uint64_t index = 0;
@@ -75,7 +200,7 @@ uint64_t getTabSmallestValue(uint64_t *tab, uint64_t tabSize)
  * @param tabSize
  * @return uint64_t
  */
-uint64_t getTabBiggestValue(uint64_t *tab, uint64_t tabSize)
+uint64_t getTabBiggestValueIndex(uint64_t *tab, uint64_t tabSize)
 {
 	uint64_t value = 0;
 	uint64_t index = 0;
@@ -92,7 +217,7 @@ uint64_t getTabBiggestValue(uint64_t *tab, uint64_t tabSize)
 }
 
 /**
- * @brief Sort an array Low to High Selection
+ * @brief Sort an array Low to High
  * 
  * @param tab
  * @param tabSize
@@ -105,12 +230,127 @@ void sortTabLTH(uint64_t *tab, uint64_t tabSize)
 	for (uint64_t i = 0; i < tabSize; i++)
 	{
 		tmp_v = tab[i];
-		min_i = getTabSmallestValue(tab+i, tabSize-i) ;
+		min_i = getTabSmallestValueIndex(tab+i, tabSize-i) ;
 		tab[i] = tab[min_i + i];
 		tab[min_i + i] = tmp_v;
 	}
 }
 
+
+/**
+ * @brief Sort Low to High with insertion algorithm
+ * ! source : https://en.wikipedia.org/wiki/Insertion_sort#Algorithm
+ * @param tab
+ * @param tabSize
+ */
+void sortInsertionLTH(uint64_t *tab, uint64_t tabSize)
+{
+	uint64_t i = 1, j;
+	while(i < tabSize)
+	{
+		j = i;
+		// Shift the value while its not at the right place
+		while( (j > 0) && ( tab[j - 1] > tab[j] ) )
+		{
+			swapIndex(tab, j, j - 1);
+			j --;
+		}
+		i++;
+	}
+}
+
+/**
+ * @brief Sort High to low with insertion algorithm
+ * 
+ * @param tab
+ * @param tabSize
+ */
+void sortInsertionHTL(uint64_t *tab, uint64_t tabSize)
+{
+	uint64_t j;
+	for (uint64_t i = 1; i < tabSize; i++)
+	{
+		j = i;
+		// Shift the value while its not at the right place
+		// Or its the last index
+		while( (j > 0) && ( tab[j - 1] < tab[j] ) )
+		{
+			swapIndex(tab, j, j - 1);
+			j--;
+		}
+	}
+}
+
+/**
+ * @brief Get the Number Of Smaller Elements from an value
+ * 
+ * @param tab
+ * @param tabSize
+ * @param element
+ */
+uint64_t getNumberOfSmallerElements(uint64_t* tab, uint64_t tabSize, uint64_t valElement)
+{
+	uint64_t res = 0;
+
+	for (uint64_t i = 0; i < tabSize; i++)
+	{
+		if(tab[i] < valElement)
+		{
+			res++;
+		}
+	}
+	return res;
+}
+
+/**
+ * @brief Sum the values element by element of 2 tabs
+ * 		  returns a pointer to a new tab 
+ * @param tab1
+ * @param tab2
+ * @param tabSize
+ * @return uint64_t*
+ */
+uint64_t* sumTabs(uint64_t* tab1, uint64_t* tab2, uint64_t tabSize) 
+{
+	uint64_t* tabBuff = createTab(tabSize);
+
+	for (uint64_t i = 0; i < tabSize; i++)
+	{
+		tabBuff[i] = tab1[i] + tab2[i];
+	}
+	return tabBuff;
+}
+
+uint64_t* mulTabs(uint64_t* tab1, uint64_t multiplier, uint64_t tabSize) 
+{
+	uint64_t* tabBuff = createTab(tabSize);
+
+	for (uint64_t i = 0; i < tabSize; i++)
+	{
+		tabBuff[i] = tab1[i] * multiplier;
+	}
+	return tabBuff;
+}
+
+double* convertToDouble(uint64_t* tab, uint64_t tabSize)
+{
+	// CREATE DOUBLE TAB
+	double* tabBuff = malloc(tabSize * sizeof(double));	
+	if(tabBuff == NULL)
+	{
+		printf("MEMORY ALLOCATION FAILED\n");
+		exit(0);
+	}
+
+	for (uint64_t i = 0; i < tabSize; i++)
+	{
+		tabBuff[i] = (double)tab[i];
+	}
+	return tabBuff;
+}
+
+
+
 /**
  * @brief Returns index of specified element in an array
  * 
@@ -205,7 +445,7 @@ void countOccurence(uint64_t *tab, uint64_t tabSize, uint64_t *occurences, uint6
  */
 void showVerticalHistoOfTab(uint64_t *occurences, uint64_t tabSize)
 {
-	uint64_t topValue = occurences[getTabBiggestValue(occurences, tabSize)];
+	uint64_t topValue = occurences[getTabBiggestValueIndex(occurences, tabSize)];
 	// PRINT ACTUAL BARS
 	for(uint64_t i = 0; i < tabSize; i++)
 	{
@@ -240,7 +480,7 @@ void showVerticalHistoOfTab(uint64_t *occurences, uint64_t tabSize)
  */
 void showHorizonalHistoOfTab(uint64_t *occurences, uint64_t tabSize)
 {
-	uint64_t topValue = occurences[getTabBiggestValue(occurences, tabSize)];
+	uint64_t topValue = occurences[getTabBiggestValueIndex(occurences, tabSize)];
 
 	// PRINT ACTUAL BARS
 	for(uint64_t i = topValue; i > 0; i--) // From topValue to 1
@@ -284,26 +524,3 @@ void fillTabWithZeroes(uint64_t *tab, uint64_t tabSize)
 		tab[i] = 0;
 	}
 }
-
-
-/**
- * @brief Get the pos where to place the element
- * 
- * @param tab
- * @param tabSize
- * @return uint64_t
- */
-uint64_t position(uint64_t *tab, uint64_t tabSize, uint64_t val)
-{
-	uint64_t currentPos = 0;
-	while( (currentPos < tabSize) && (val < tab[currentPos]))
-	{
-		currentPos++;
-	}
-	return c ←urrentPos;
-}
-
-void shift(uint64_t *tab, uint64_t tabSize, uint64_t pos)
-{
-
-}	
diff --git a/tableaux_uni/src/main.c b/tableaux_uni/src/main.c
index 5db9899..207ee27 100644
--- a/tableaux_uni/src/main.c
+++ b/tableaux_uni/src/main.c
@@ -13,61 +13,25 @@
 #include <stdint.h>
 
 #include "../include/jtableaux.h"
+#include "../include/sort.h"
 
 int main()
 {
 	uint64_t sizeOfTab;
-	uint64_t frac_sizeOfTab;
 
 	srand(time(NULL)); // Create seed
-
-	printf("--------------------------------------------------\n");
-	printf("    _ _____ _   ___ _    ___   _  _   ___  __\n");
-	printf(" _ | |_   _/_\\ | _ ) |  | __| /_\\| | | \\ \\/ /\n");
-	printf("| || | | |/ _ \\| _ \\ |__| _| / _ \\ |_| |>  <\n");
-	printf(" \\__/  |_/_/ \\_\\___/____|___/_/ \\_\\___//_/\\_\\\n\n");
-	printf("Jonas Stirnemann\n");
-	printf("--------------------------------------------------\n");
 	
 	// USER INPUT
 	printf("SIZE OF TAB : ");
 	scanf(" %ld", &sizeOfTab); 
-	frac_sizeOfTab = sizeOfTab / 10 - 1;
-	
-	// FIND ELEMENT 
-	uint64_t element;
-	printf("ELEMENT  : ");
-	scanf(" %ld", &element); 
-
-	// RANDOM TAB
+	// uint64_t* tab = createTab(sizeOfTab);
 	uint64_t tab[sizeOfTab];
-	printf("\nFILLING TAB WITH RANDOM VALUES ... \n");
-	fillTabRandom(tab, sizeOfTab, 0, frac_sizeOfTab);
-
-	// SORT 
-	printf("SORTING TAB ... \n\n");
-	sortTabLTH(tab, sizeOfTab);
-
-	printf("INDEX OF CHOSEN ELEMENT : %ld\n", getIndexOfTabElement(tab, sizeOfTab, element));
-
-	// GET MEAN
-	printf("MOYENNE  : %.2lf\n", getMeanOfTab(tab, sizeOfTab));
-
-	// GET VARIANCE
-	printf("VARIANCE : %.2lf\n", getVarianceOfTab(tab, sizeOfTab, getMeanOfTab(tab, sizeOfTab)));
-
-	// GET MEDIAN
-	printf("MEDIAN   : %ld\n\n", getMedianOfTab(tab, sizeOfTab));
-
-	// SHOW HISTOS	
-	uint64_t occurences[frac_sizeOfTab];
-	countOccurence(tab, sizeOfTab, occurences, frac_sizeOfTab);
+	fillTabRandomValues(tab, sizeOfTab, 0, sizeOfTab);
 
-	printf("HISTO VERTICAL\n");
-	showVerticalHistoOfTab(occurences, frac_sizeOfTab);
-	printf("\n\n");
-	printf("HISTO VERTICAL\n");
-	showHorizonalHistoOfTab(occurences, frac_sizeOfTab);
+	showTab(tab, sizeOfTab, "UNSORTED TAB");
+	bubbleSort(tab, sizeOfTab);
+	showTab(tab, sizeOfTab, "SORTED TAB");
 
+	destroyTab(tab);
 	return 0;
 }
diff --git a/tableaux_uni/src/sort.c b/tableaux_uni/src/sort.c
new file mode 100644
index 0000000..5e8130c
--- /dev/null
+++ b/tableaux_uni/src/sort.c
@@ -0,0 +1,145 @@
+/*
+	* CODE SORT
+	* Author : Jonas S.
+	* Date   : 10/11/2021
+	! DESCRIPTION
+*/
+
+#include "../include/sort.h"
+#include "../include/jtableaux.h" // swap index
+
+// -------------------- UTILS --------------------
+
+
+
+/**
+ * @brief Swap 2 values
+ * 
+ * @param a
+ * @param b
+ */
+void swap(uint64_t* a, uint64_t* b)
+{
+	uint64_t tmp = *a;
+	*a = *b;
+	*b = tmp;
+}
+
+
+//-------------------- INSERTION SORT --------------------
+// N**2
+// /**
+//  * @brief Sort Low to High with insertion algorithm
+//  * ! source : https://en.wikipedia.org/wiki/Insertion_sort#Algorithm
+//  * @param tab
+//  * @param tabSize
+//  */
+// void sortInsertionLTH(uint64_t *tab, uint64_t tabSize)
+// {
+// 	uint64_t i = 1, j;
+// 	while(i < tabSize)
+// 	{
+// 		j = i;
+// 		// Shift the value while its not at the right place
+// 		while( (j > 0) && ( tab[j - 1] > tab[j] ) )
+// 		{
+// 			swapIndex(tab, j, j - 1);
+// 			j --;
+// 		}
+// 		i++;
+// 	}
+// }
+
+// /**
+//  * @brief Sort High to low with insertion algorithm
+//  * 
+//  * @param tab
+//  * @param tabSize
+//  */
+// void sortInsertionHTL(uint64_t *tab, uint64_t tabSize)
+// {
+// 	uint64_t j;
+// 	for (uint64_t i = 1; i < tabSize; i++)
+// 	{
+// 		j = i;
+// 		// Shift the value while its not at the right place
+// 		// Or its the last index
+// 		while( (j > 0) && ( tab[j - 1] < tab[j] ) )
+// 		{
+// 			swapIndex(tab, j, j - 1);
+// 			j--;
+// 		}
+// 	}
+// }
+
+
+//-------------------- QUICKSORT --------------------
+
+/**
+ * @brief 
+ * 
+ * @param tab
+ * @param tabSize
+ * @param first First index of (sub)array
+ * @param last Last index of (sub)array
+ * @return uint64_t
+ */
+uint64_t partition(uint64_t* tab, uint64_t tabSize, uint64_t first, uint64_t last)
+{
+	uint64_t pivot = tab[last];
+	uint64_t i = first - 1, j = last;
+
+	do
+	{
+		do
+		{
+			i++;
+		} while (tab[i] < pivot && i < j) ;
+		do
+		{
+			j--;
+		} while (tab[j] > pivot && j > i);
+	} while (j > i);
+	swap(&tab[i], &tab[j]);
+	return i;
+}
+
+
+void quicksort(uint64_t* tab, uint64_t tabSize, uint64_t first, uint64_t last)
+{
+	if(first < last)
+	{
+		uint64_t midpoint = partition(tab, tabSize, first, last);
+		if(first < midpoint - 1)
+		{
+			quicksort(tab, tabSize, first, midpoint -1);
+		}
+		if(midpoint + 1 < last)
+		{
+			quicksort(tab, tabSize, midpoint - 1, last);
+		}
+	}
+}
+
+
+void bubbleSort(uint64_t* tab, uint64_t tabSize)
+{
+	bool sorted = 0;
+	for (uint64_t i = tabSize - 1; i > 1; i--)
+	{
+		sorted = true;
+		for (uint64_t j = 0;j < i - 1; j++)
+		{
+			if(tab[j] > tab[j + 1])
+			{
+				swap(&tab[i], &tab[i + 1]);
+				sorted = false;
+			}
+		}
+		if(sorted)
+		{
+			return;
+		}
+	}
+	
+}
\ No newline at end of file
-- 
GitLab