diff --git a/lessons/contenu_cours_struct_queue.md b/lessons/contenu_cours_struct_queue.md index 6c456fa5096d138412a90886c80c143ff7ea6256..6d60b4ba5c52c2ad0ec58766c33982adaf348b1d 100644 --- a/lessons/contenu_cours_struct_queue.md +++ b/lessons/contenu_cours_struct_queue.md @@ -94,8 +94,7 @@ Il faut considérer plusieurs cas: #### Extraction en tête de file d'attente -Voici l'entête de la procédure: -`int queue_extraire(queue* fa);` +Voici l'entête de la procédure: `int queue_extraire(queue* fa);` On commence par récupérer, la valeur en tête de file d'attente via l'appel `queue_tete(*fa);` diff --git a/lessons/contenu_cours_struct_sorted_list.md b/lessons/contenu_cours_struct_sorted_list.md new file mode 100644 index 0000000000000000000000000000000000000000..fbe3f9d839f2083f2beb4a6bb194e287d6b74a3f --- /dev/null +++ b/lessons/contenu_cours_struct_sorted_list.md @@ -0,0 +1,206 @@ +# Algorithmes et structures de données + +# Structure de liste triée + +***** + +## 1. Définition + +On considère une liste chaînée d'articles. Chaque article comportera un champ pour stocker les valeurs +dans la liste et un champ contenant une variable de type pointeur pour assurer le chaînage. +Schématiquement: + + + +La liste est triée pour autant que l'insertion de chaque nouvelle valeur dans la liste maintienne cette +propriété. +L'accès à la liste se fera uniquement par le pointeur lst qui référence le début de la liste. +Une telle liste chaînée sera déclarée par exemple sous la forme suivante: + +```C + typedef struct _element { // Elément de liste + int n; + struct _element* suivant; + } element; + + typedef element* liste; // Pointeur sur des éléments de liste +``` + +## 2. Insertion dans une liste triée + +Voici l'entête de la procédure : `liste inserer(liste lst,int val);` + +Il faut considérer plusieurs cas. + +### La liste est vide: `lst == NULL` + + + +### L'insertion se fait en 1ère position: `val <= lst->n` + +Par exemple, pour `val = 1` + + + +### Les positions autres que la 1ère position + +Par exemple, pour `val = 13` + + + +```C + (1) tmp = malloc(sizeof(element)); + tmp->n = 13; +``` + +On déplace un pointeur crt jusqu'à l'élément précédent la position d'insertion de sorte que +```C + crt->n < val <= crt->suivant->n +``` + +On utilise une boucle: +```C + (2) while (NULL != crt->suivant && val > crt->suivant->n) { + crt = crt->suivant; + } +``` + +Puis on raccroche l'élément pointé par tmp à la liste +```C + (3) tmp->suivant = crt->suivant; + (4) crt->suivant = tmp; + return lst; +``` + +## 3. Extraction d'un élément dans une liste triée + +Voici l'entête de la procédure : `liste extraire(liste lst,int val);` + +Si la liste est vide, on retourne la liste vide. + +Ensuite, on déplace deux pointeurs prec et crt à travers la liste jusqu'à ce que : `prec->n < val <= crt->n` + +On utilise une boucle: +```C + while (NULL != crt && val > crt->n) { + prec = crt; + crt = crt->suivant; + } +``` + +Il faut à nouveau considérer plusieurs cas. + +### La valeur à retirer est supérieure à la dernière valeur de la liste. + +Ceci équivaut à: `crt == NULL` ou `prec->suivant == NULL` + +On retourne la liste inchangée. + +Par exemple, pour `val = 30` + + + +### La valeur à retirer n'est pas celle dans l'élément pointé par `crt`. + +Ceci équivaut à: `val < crt->n` + +On retourne la liste inchangée. + +Par exemple, pour `val = 9` + + + +ou pour val = 1 + + + +### La valeur à retirer est celle dans l'élément pointé par `crt`. + +Ceci équivaut à: `val == crt->n` + +#### La valeur à retirer est en début de liste. + +Ceci équivaut à: `crt == prec` + +On doit déplacer la tête de liste : lst = crt->suivant; + +Par exemple, pour `val = 3` + + + +#### La valeur à retirer n'est pas en début de liste. + +On doit raccrocher l'élément pointé par prec à celui suivant `crt`: `prec->suivant = crt->suivant;` + +Par exemple, pour `val = 12` + + + +ou pour `val = 21` + + + +Finalement, on libère la mémoire de l'élément pointé par `crt`: `free(crt);` + + + +## 4. Recherche dans une liste triée + +La fonction recherche retourne un pointeur sur l'élément qui contient la valeur recherchée ou un pointeur `NULL` si la valeur est absente de la liste triée. + +Voici l'entête de la procédure : `element* recherche(liste lst,int val);` + +On considère d'abord la fonction utilitaire `position` qui retourne un pointeur sur l'élément avant la +position d'insertion d'une valeur ou un pointeur `NULL` s'il s'agit de la tête de liste. +```C + element* position(liste lst,int val) { + element* pos = lst; + if (est_vide(lst) || val <= lst->n) { + pos = NULL; + } else { + while (NULL != pos->suivant && val > pos->suivant->n) { + pos = pos->suivant; + } + } + return pos; + } +``` + +Par exemple, pour val = 1 ou 3 + + + +et pour val = 29 + + + +et finalement pour val = 10 ou 12 + + + +Ainsi, la fonction de recherche s'écrit simplement : +```C + element* recherche(liste lst,int val) { + element* pos = position(lst,val); + if (est_vide(lst)) { + return NULL; + } + if (NULL == pos && val == lst->n) { + return lst; + } else if (NULL != pos->suivant && val == pos->suivant->n) { + return pos->suivant; + } else { + return NULL; + } + } +``` + +## Exercice + +Ecrire directement la fonction `recherche` sans utiliser la fonction `position`. +Faire les dessins illustrant les différents cas possibles. + + + + + diff --git a/lessons/figures/fig_1st_element_sorted_list_extract.png b/lessons/figures/fig_1st_element_sorted_list_extract.png new file mode 100644 index 0000000000000000000000000000000000000000..02057f27d58980d2f99a9cb3b5235e2e879ae993 Binary files /dev/null and b/lessons/figures/fig_1st_element_sorted_list_extract.png differ diff --git a/lessons/figures/fig_1st_element_sorted_list_search.png b/lessons/figures/fig_1st_element_sorted_list_search.png new file mode 100644 index 0000000000000000000000000000000000000000..d23b4911b12a86f08dfa84429ef5ede940881637 Binary files /dev/null and b/lessons/figures/fig_1st_element_sorted_list_search.png differ diff --git a/lessons/figures/fig_1st_position_sorted_list_insert.png b/lessons/figures/fig_1st_position_sorted_list_insert.png new file mode 100644 index 0000000000000000000000000000000000000000..fcc97e15b6175e7a0f83b5e8eebffaead14f013c Binary files /dev/null and b/lessons/figures/fig_1st_position_sorted_list_insert.png differ diff --git a/lessons/figures/fig_empty_sorted_list_insert.png b/lessons/figures/fig_empty_sorted_list_insert.png new file mode 100644 index 0000000000000000000000000000000000000000..6ffe0599a2f39cf2fadbc57e16385a9f13102f13 Binary files /dev/null and b/lessons/figures/fig_empty_sorted_list_insert.png differ diff --git a/lessons/figures/fig_free_element_sorted_list_extract.png b/lessons/figures/fig_free_element_sorted_list_extract.png new file mode 100644 index 0000000000000000000000000000000000000000..5a868acee5c8d3b95225f1abc6cb2bfe5bf9120a Binary files /dev/null and b/lessons/figures/fig_free_element_sorted_list_extract.png differ diff --git a/lessons/figures/fig_greater_value_sorted_list_extract.png b/lessons/figures/fig_greater_value_sorted_list_extract.png new file mode 100644 index 0000000000000000000000000000000000000000..4c9c23b8d88c7079f9ad8f8dfd5d4d4822eac217 Binary files /dev/null and b/lessons/figures/fig_greater_value_sorted_list_extract.png differ diff --git a/lessons/figures/fig_last_element_sorted_list_search.png b/lessons/figures/fig_last_element_sorted_list_search.png new file mode 100644 index 0000000000000000000000000000000000000000..65b22241c7bab9776841120c7bdb68e0034e813f Binary files /dev/null and b/lessons/figures/fig_last_element_sorted_list_search.png differ diff --git a/lessons/figures/fig_no_value_sorted_list_extract_1.png b/lessons/figures/fig_no_value_sorted_list_extract_1.png new file mode 100644 index 0000000000000000000000000000000000000000..a9e531e5f06ab409da277d37cba0a0dcd5ba4ebf Binary files /dev/null and b/lessons/figures/fig_no_value_sorted_list_extract_1.png differ diff --git a/lessons/figures/fig_no_value_sorted_list_extract_2.png b/lessons/figures/fig_no_value_sorted_list_extract_2.png new file mode 100644 index 0000000000000000000000000000000000000000..222afa8686d08c7039ee24be0d3bfb7382bda696 Binary files /dev/null and b/lessons/figures/fig_no_value_sorted_list_extract_2.png differ diff --git a/lessons/figures/fig_other_element_sorted_list_extract_1.png b/lessons/figures/fig_other_element_sorted_list_extract_1.png new file mode 100644 index 0000000000000000000000000000000000000000..5318ce34595ec1b14dd5a619bd9c50b627ca5167 Binary files /dev/null and b/lessons/figures/fig_other_element_sorted_list_extract_1.png differ diff --git a/lessons/figures/fig_other_element_sorted_list_extract_2.png b/lessons/figures/fig_other_element_sorted_list_extract_2.png new file mode 100644 index 0000000000000000000000000000000000000000..565a58210c3ab51a6bcbf6a320027242f0a4162e Binary files /dev/null and b/lessons/figures/fig_other_element_sorted_list_extract_2.png differ diff --git a/lessons/figures/fig_other_element_sorted_list_search.png b/lessons/figures/fig_other_element_sorted_list_search.png new file mode 100644 index 0000000000000000000000000000000000000000..1b116eb37e97c15bdcdbb8a2ec53d05594f6c10a Binary files /dev/null and b/lessons/figures/fig_other_element_sorted_list_search.png differ diff --git a/lessons/figures/fig_other_position_sorted_list_insert.png b/lessons/figures/fig_other_position_sorted_list_insert.png new file mode 100644 index 0000000000000000000000000000000000000000..92795feedcdc102d9067f982c1732c6559ddff67 Binary files /dev/null and b/lessons/figures/fig_other_position_sorted_list_insert.png differ diff --git a/source_codes/sorted_lists/sorted_list_full.c b/source_codes/sorted_lists/sorted_list_full.c new file mode 100644 index 0000000000000000000000000000000000000000..758000f9e1cb3f875ed4c688fdf040c463339d5f --- /dev/null +++ b/source_codes/sorted_lists/sorted_list_full.c @@ -0,0 +1,110 @@ +#include <stdio.h> +#include <stdlib.h> +#include <assert.h> +#include <stdbool.h> + +typedef struct _element { + int n; + struct _element* suivant; +} element; +typedef element* liste; + +// Crée une liste vide +liste liste_creer() { + return NULL; +} + +// Teste si la liste vide +bool liste_est_vide(liste lst) { + return NULL == lst; +} + +// Retourne un pointeur sur l'élement avant l'emplacement d'insertion; +// ce pointeur est nul si la liste est vide ou si l'insertion est en tête de liste +element* position(liste lst,int val) { + element* pos = lst; + if (liste_est_vide(lst) || val <= lst->n) { + pos = NULL; + } else { + while (NULL != pos->suivant && val > pos->suivant->n) { + pos = pos->suivant; + } + } + return pos; +} + +// Insère un élément dans la liste triée et retourne la liste mise à jour +liste liste_inserer(liste lst,int val) { + element* tmp = malloc(sizeof(element)); + tmp->n = val; + element* crt = position(lst,val); + if (NULL == crt) { // insertion dans une liste vide ou en tête de liste + tmp->suivant = lst; + lst = tmp; + } else { // insertion au milieu ou en fin de liste + tmp->suivant = crt->suivant; + crt->suivant = tmp; + } + return lst; +} + +// Extrait un élément avec la valeur <val> et retourne la liste mise à jour; +// la liste est inchangée si elle est initialement vide +// ou si la valeur est absente +liste liste_extraire(liste lst,int val) { + element *crt = lst, *prec = lst; + // boucle pour placer <val>: prec->n < val <= crt->n + while (NULL != crt && val > crt->n) { + prec = crt; + crt = crt->suivant; + } + // liste non-vide et <val> présente de la liste + if (NULL != crt && val == crt->n) { + if (crt == prec) { // extraction en début de liste + lst = lst->suivant; + } else { // extraction en milieu ou fin de liste + prec->suivant = crt->suivant; + } + free(crt); + } + return lst; +} + +// Retourne un pointeur sur l'élément qui contient <val> ou un pointeur nul +// si la liste est vide ou la valeur absente +element* liste_recherche(liste lst,int val) { + // à compléter + return NULL; +} + +// Imprime le contenu de la liste +void print(liste lst) { + element* crt = lst; + while (NULL != crt) { + printf("%d ",crt->n); + crt = crt->suivant; + } +} + +int main(int argc, char** argv) { + liste lst = liste_creer(); + char str[20]; + do { + printf("Insert: "); + scanf("%s", str); + if (0 == strcmp("quit",str)) break; + lst = liste_inserer(lst,atoi(str)); + print(lst); + printf("\n"); + } while (true); + do { + printf("Extract: "); + scanf("%s", str); + if (0 == strcmp("quit",str)) break; + lst = liste_extraire(lst,atoi(str)); + print(lst); + printf("\n"); + } while (true); + return 0; +} + diff --git a/source_codes/sorted_lists/sorted_list_partiel.c b/source_codes/sorted_lists/sorted_list_partiel.c new file mode 100644 index 0000000000000000000000000000000000000000..773e80f39c19b6113d77280769456eb3868bf6ff --- /dev/null +++ b/source_codes/sorted_lists/sorted_list_partiel.c @@ -0,0 +1,103 @@ +#include <stdio.h> +#include <stdlib.h> +#include <assert.h> +#include <stdbool.h> + +typedef struct _element { + int n; + struct _element* suivant; +} element; +typedef element* liste; + +// Crée une liste vide +liste liste_creer() { + return NULL; +} + +// Teste si la liste vide +bool liste_est_vide(liste lst) { + return NULL == lst; +} + +// Retourne un pointeur sur l'élement avant l'emplacement d'insertion; +// ce pointeur est nul si la liste est vide ou si l'insertion est en tête de liste +element* position(liste lst,int val) { + element* pos = lst; + if (liste_est_vide(lst) || val <= lst->n) { + pos = NULL; + } else { + while (NULL != pos->suivant && val > pos->suivant->n) { + pos = pos->suivant; + } + } + return pos; +} + +// Insère un élément dans la liste triée et retourne la liste mise à jour +liste liste_inserer(liste lst,int val) { + element* tmp = malloc(sizeof(element)); + tmp->n = val; + element* pos = position(lst,val); + if (NULL == pos) { // insertion dans une liste vide ou en tête de liste + // à compléter + } else { // insertion au milieu ou en fin de liste + // à compléter + } + return lst; +} + +// Extrait un élément avec la valeur <val> et retourne la liste mise à jour; +// la liste est inchangée si elle est initialement vide +// ou si la valeur est absente +liste liste_extraire(liste lst,int val) { + element* prec = lst; + element* crt = lst; + // boucle pour placer <val>: prec->n < val <= crt->n + // à compléter + + // liste non-vide et <val> présente de la liste + if (NULL != crt && val == crt->n) { + if (crt == prec) { // extraction en début de liste + lst = lst->suivant; + } else { // extraction en milieu ou fin de liste + prec->suivant = crt->suivant; + } + free(crt); + } + return lst; +} + +// Retourne un pointeur sur l'élément qui contient <val> ou un pointeur nul +// si la liste est vide ou la valeur absente +element* liste_recherche(liste lst,int val) { + // à compléter + return NULL; +} + +// Imprime le contenu de la liste +void print(liste lst) { + //à compléter +} + +int main(int argc, char** argv) { + liste lst = liste_creer(); + char str[20]; + do { + printf("Insert: "); + scanf("%s", str); + if (0 == strcmp("quit",str)) break; + lst = liste_inserer(lst,atoi(str)); + print(lst); + printf("\n"); + } while (true); + do { + printf("Extract: "); + scanf("%s", str); + if (0 == strcmp("quit",str)) break; + lst = liste_extraire(lst,atoi(str)); + print(lst); + printf("\n"); + } while (true); + return 0; +} +