Archives d’Auteur: alain
M3103 – TP3 Exercice 2
Nous avons montré précédemment que les listes simplement chaînées présentent entre autres un inconvénient majeur : celui d’interdire le retour arrière. Cette impossibilité nécessite, même pour les opérations élémentaires et indispensables comme la suppression d’un élément, de mémoriser au minimum le pointeur vers l’élément précédent au fur et à mesure du parcours. Cependant, toute permutation, tout déplacement (en particulier les tris) deviennent inutilement complexes et malcommodes.
L’alternative est de construire des éléments possédant un double chaînage, vers le précédent et vers le suivant. En fait, chaque information appartient à deux listes simples inverses l’une de l’autre.
Le parcours de la liste double pouvant être effectué à tout moment dans les deux sens, il est normal qu’elle possède deux points d’entrée, la Tete et la Queue.
Dans l’exercice “Sentinelle dans une liste simple”, nous avons montré que les ajouts/suppressions en tête pouvaient être banalisés en insérant au début de la liste, et dès sa construction, un élément “vide”, appelé sentinelle.
Le problème est le même pour les listes doubles, et se reproduit avec les opérations d’ajout/suppression en queue. C’est pourquoi les listes doublement chaînées sont généralement implémentées avec deux sentinelles, appelées naturellement sentinelles de tête et sentinelle de queue. Ainsi, la structure d’une liste double vide est illustrée dans l’encadré supérieur de la figure ci-dessous :
Travail à effectuer
Ajouter à la classe CNode
:
- la donnée membre
m_Prev
; - l’accesseur et le modifieur correspondants;
- le corps du constructeur et du destructeur de la classe.
Modifier, dans la classe CList
, le constructeur, les fonctions AddAfter()
et Delete()
.
Ajouter la fonction AddBefore()
de profil :
void AddBefore (const std::shared_ptr < CNode < T>> &, const T & val);
M3103 – TP3 EXERCICE 2 – Corrigé
M3103 – TP3 Exercice 3
L’ordre des éléments dans une liste LRU ne dépend que de l’ancienneté du dernier accès à chaque élément, ce qui implique deux conséquences :
-
- même si la liste est triée à un instant donné, chaque insertion ou recherche a probablement pour effet de modifier l’ordre de la liste (sauf si ce ne sont que de accès en tête). L’algorithme de recherche à utiliser est donc celui d’une recherche séquentielle dans un ensemble non trié.
- l’utilisateur ne peut plus choisir la position à laquelle un élément doit être inséré dans la liste : la propriété “LRU” impose qu’elle soit toujours effectuée en tête.
Travail à effectuer
Modifier la classe CList
pour qu’elle réponde au propriété “LRU”.
Nb: on considère que l’affichage ne modifie pas l’ordre des éléments de la liste.
M3103 – TP4 Exercice 4
- Faites en sorte de pouvoir afficher votre arbre sans utiliser de fonction d’aide dite “locale”.
- Afficher la vue arborescente de l’arbre : chaque fils est décalé d’une indentation par rapport à son père.
M3103 – TP3 Exercice 4
M3103 – Amphis
Amphi 1 :
- Récursivité
- Adresse mémoire
- Pointeurs en mémoire dynamique
https://ens.casali.me/wp-content/uploads/2017/09/Amphi1.pptx
Amphi 2 :
- Quelques problèmes avec les pointeurs en mémoire dynamique
- Idiome RAII
- Avant propos pour les listes chainées
- On veut faire quoi?
- Structure et fonctionnalités d’un nœud
- Une première liste chainée
- Classe pour liste chainée
- Technique de la sentinelle
https://ens.casali.me/wp-content/uploads/2017/09/Amphi2.pptx
Amphi 3 :
- Structures d’arbres
- Diverses implémentations d’un arbre binaire et n-aire
- Parcours d’arbres
https://ens.casali.me/wp-content/uploads/2017/09/Amphi3.ppt
Amphi 4 :
- Smart Pointers
- Liste chainée avec smart pointers
- Structures de données pour la recherche
https://ens.casali.me/wp-content/uploads/2017/09/Amphi4.pptx
Lien pour amphi 3 (23 / 09 /20) :
- zoom : 954 8259 6058
- pwd : prénom de la personne qui a fait le cours d’algo au début du semestre 1.
M4104C Amphi
M4104C
Compléter le code suivant :
#include <iostream> #include <vector> #include <iomanip> #include <cstdlib> #include <ctime> #include <algorithm> #include <thread> using namespace std; typedef vector <unsigned> CVUint; typedef vector < vector <double>> CMatrix; CMatrix Mat; void SelectSort (CVUint & VUint) { for (unsigned i (0); i < VUint.size(); ++i) { CVUint::iterator Min (min_element (VUint.begin() + i, VUint.end())); swap (VUint[i],VUint [Min - VUint.begin()]); } } void InsertSort (CVUint & VUint) { for (unsigned i (1); i < VUint.size(); ++i) { unsigned Val (VUint [i]); unsigned j (i); for (; j > 0 && VUint[j - 1] > Val; --j) VUint[j] = VUint[j - 1]; VUint[j] = Val; } } void BubbleSort (CVUint & VUint) { for (unsigned i (VUint.size()); i -- > 0; ) { bool TableauTrie = true; for (unsigned j (0); j < i ; ++j) { if (VUint[j + 1] < VUint[j]) { swap (VUint[j + 1], VUint[j]); TableauTrie = false; } } if (TableauTrie) return; } } void LanguageSort (CVUint & VUint) { sort (VUint.begin(), VUint.end()); } void InitMat (unsigned NbColumns) { Mat.resize(4, vector <double> (NbColumns)); } void protoGenericSort(void (*Sort) (CVUint & VUint), const CVUint & VUint, unsigned NbFois, unsigned PosMat, unsigned VectNum) { for (unsigned i (0); i < NbFois; ++i) { CVUint CopyVUint (VUint); /* TODO*/ double elapsed; /* TODO*/ Sort (CopyVUint); /* TODO*/ Mat [PosMat][i + NbFois * VectNum] = elapsed; } } void TraiterResultats (unsigned NbElemAEnlever) { for (vector <double> & UneLigne : Mat) { //tri sort (UneLigne.begin(), UneLigne.end()); //plus petit temps double min (UneLigne[0]); //plus grand temps double max (UneLigne[UneLigne.size()-1]); //temps median double med (UneLigne[UneLigne.size()/2]); //On assigne les valeurs memorisees aux 3 premières cases UneLigne[0] = min; UneLigne[1] = med; UneLigne [2] = max; } //Affichage cout << setw (20) << "Tri" << setw (10) << "Min" << setw (10) << "Med" << setw (10) << "Max" << endl; vector<string> VMetode {"Selection", "Insertion", "Bulles", "Langage"}; for (unsigned i (0); i < VMetode.size(); ++i) cout << setw (20) << VMetode[i] << setw (10) << setprecision(6) << Mat[i][0] << setw (10) << setprecision(6) << Mat[i][1] << setw (10) << setprecision(6) << Mat[i][2] << endl; } int main(int argc, char *argv[]) { if (argc != 4) { cerr << "boulette !\n utilisation : " << argv [0] << " (1) NbElem par vecteur (2) Nb de vecteurs differents (3) Nb itérations par vecteur" << endl; return 1; } unsigned NbElem (stoul(argv[1])); unsigned NbVecteurs (stoul(argv[2])); unsigned NbFois (stoul(argv[3])); srand (time(NULL)); CVUint VUInt (NbElem); InitMat(NbFois * NbVecteurs); for (unsigned i (0); i < NbVecteurs; ++i) { for (auto & Val : VUInt) Val = rand () % (VUInt.size() * 10); thread th1 (/* TODO*/); thread th2 (/* TODO*/); thread th3 (/* TODO*/); thread th4 (/* TODO*/); th1.join(); th2.join(); th3.join(); th4.join(); cout << i << "fini" << endl; } cout << "Taille des vecteurs : " << NbElem << "\nNb de vecteurs : " << NbVecteurs << "\nNb iterations par vecteur : " << NbFois << endl; TraiterResultats (NbFois * NbVecteurs / 10); return 0; }
R1.01 – PROG#13 – Exercice 1
Déclarerez une variable de type map < string, string >
. La première chaine de caractères désigne un nom de famille, le second le prénom d’une personne.
Dans le main ()
:
- déclarer une
map
, - insérer 4 éléments dans cette
map
, - parcourez la
map
pour l’afficher.