From e7f12b54e9923a2faa4eb76ed59051e4b1aa4693 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Gu=C3=A9len?= Date: Mon, 10 Mar 2025 12:37:50 +0100 Subject: [PATCH] Expansion: A version of quicksort for wordlists It is intended to be used with the full version not the direct quicksort as the direct one is not currently correctly protected against end index being out of bounds. --- src/parser/wordlist/wordlist.h | 6 +-- src/parser/wordlist/wordlist_quicksort.c | 66 ++++++++++++++++++++++-- src/parser/wordlist/wordlist_quicksort.h | 7 +-- src/parser/wordlist/wordlist_utils.c | 58 +++++++++++++++++++++ 4 files changed, 128 insertions(+), 9 deletions(-) create mode 100644 src/parser/wordlist/wordlist_utils.c diff --git a/src/parser/wordlist/wordlist.h b/src/parser/wordlist/wordlist.h index 6a04bc6..35fe5a4 100644 --- a/src/parser/wordlist/wordlist.h +++ b/src/parser/wordlist/wordlist.h @@ -3,10 +3,10 @@ /* ::: :::::::: */ /* wordlist.h :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: khais +#+ +:+ +#+ */ +/* By: jguelen +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ -/* Created: 2025/03/11 11:14:10 by khais #+# #+# */ -/* Updated: 2025/03/11 11:14:32 by khais ### ########.fr */ +/* Created: 2025/02/13 15:46:02 by khais #+# #+# */ +/* Updated: 2025/03/21 10:11:30 by jguelen ### ########.fr */ /* */ /* ************************************************************************** */ diff --git a/src/parser/wordlist/wordlist_quicksort.c b/src/parser/wordlist/wordlist_quicksort.c index cccf9fa..f47d6a0 100644 --- a/src/parser/wordlist/wordlist_quicksort.c +++ b/src/parser/wordlist/wordlist_quicksort.c @@ -6,19 +6,79 @@ /* By: jguelen +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/03/08 17:29:05 by jguelen #+# #+# */ -/* Updated: 2025/03/08 17:31:56 by jguelen ### ########.fr */ +/* Updated: 2025/03/10 12:36:27 by jguelen ### ########.fr */ /* */ /* ************************************************************************** */ #include "wordlist_quicksort.h" +static void ft_swap_wordlist_contents(t_wordlist *list1, t_wordlist *list2) +{ + t_worddesc *tmp_word; + + tmp_word = list1->word; + list1->word = list2->word; + list2->word = tmp_word->word; +} + +/* +** The pivot is selected as in classic variations to be the last element of the +** list initially. +** The partitionning makes it so in the end all elements smaller than the pivot, +** which in this case will be determined by a simple order of growing ascii +** value on the word->word component of the wordlist, are on the left of the +** pivot value and all elements greater on the right. +** @RETURN the index at wich the pivot is now to be found. +*/ +static int wordlist_quicksort_partition(t_wordlist *list, int start, int end) +{ + int i; + int j; + t_wordlist *pivot; + t_wordlist *list_i; + t_wordlist *list_j; + + i = start; + j = start; + list_i = wordlist_get_elem(list, start); + list_j = wordlist_get_elem(list, start); + pivot = wordlist_get_elem(list, end); + while (j < end) + { + if (ft_strcmp(list_j->word->word, pivot->word->word) > 0) + { + ft_swap_wordlist_contents(list_i, list_j); + i++; + list_i = list_i->next; + } + j++; + list_j = list_j->next; + } + ft_swap_wordlist_contents(list_i, pivot); + return (i); +} + /* -** TODO ** Returns the wordlist list sorted in ascending ascii order. ** Proceeds by directly swapping the inside contents and not by rewiring the ** nodes themselves. */ -t_wordlist *wordlist_quicksort(t_wordlist *list) +t_wordlist *wordlist_quicksort(t_wordlist *list, int start, int end) { + int pivot; + + if (start >= end || !list || start < 0) + return (list); + pivot = wordlist_quicksort_partition(list, start, end); + wordlist_quicksort(list, start, pivot - 1); + wordlist_quicksort(list, pivot + 1, end); return (list); } + +/* +** Is intended as a shortcut for practical use as a full list sort. +*/ +t_wordlist *wordlist_quicksort_full(t_wordlist *list) +{ + return (wordlist_quicksort(list, 0, wordlist_size(list) - 1)); +} diff --git a/src/parser/wordlist/wordlist_quicksort.h b/src/parser/wordlist/wordlist_quicksort.h index 7d499e2..ab3f246 100644 --- a/src/parser/wordlist/wordlist_quicksort.h +++ b/src/parser/wordlist/wordlist_quicksort.h @@ -3,10 +3,10 @@ /* ::: :::::::: */ /* wordlist_quicksort.h :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: jguelen +#+ +:+ +#+ */ +/* By: jguelen +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/03/08 17:26:52 by jguelen #+# #+# */ -/* Updated: 2025/03/08 17:28:59 by jguelen ### ########.fr */ +/* Updated: 2025/03/10 12:34:23 by jguelen ### ########.fr */ /* */ /* ************************************************************************** */ @@ -15,6 +15,7 @@ # include "wordlist.h" -t_wordlist *wordlist_quicksort(t_wordlist *list); +t_wordlist *wordlist_quicksort(t_wordlist *list, int low, int high); +t_wordlist *wordlist_quicksort_full(t_wordlist *list); #endif diff --git a/src/parser/wordlist/wordlist_utils.c b/src/parser/wordlist/wordlist_utils.c new file mode 100644 index 0000000..3669bcc --- /dev/null +++ b/src/parser/wordlist/wordlist_utils.c @@ -0,0 +1,58 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* wordlist_utils.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jguelen +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/03/10 09:51:34 by jguelen #+# #+# */ +/* Updated: 2025/03/10 12:23:36 by jguelen ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "wordlist.h" +#include + +/* +** Returns the number of words present in the wordlist given as parameter. +** NOTE: Assumes that that list not to be circular. +*/ +int wordlist_size(t_wordlist *wordlist) +{ + int size; + + size = 0; + while (wordlist) + { + size++; + wordlist = wordlist->next; + } + return (size); +} + +t_wordlist *wordlist_last(t_wordlist *list) +{ + if (!list) + return (NULL); + while (list->next) + list = list->next; + return (list); +} + +/* +** Returns the node at index idx in list or NULL if idx is out +** of bounds. +*/ +t_wordlist *wordlist_get_elem(t_wordlist *list, int idx) +{ + if (list == NULL || idx < 0) + return (NULL); + while (idx > 0 && list != NULL) + { + list = list->next; + idx--; + } + if (list == NULL) + return (NULL); + return (list); +} \ No newline at end of file