summaryrefslogtreecommitdiff
path: root/lib/BHeap.cc
diff options
context:
space:
mode:
Diffstat (limited to 'lib/BHeap.cc')
-rw-r--r--lib/BHeap.cc159
1 files changed, 153 insertions, 6 deletions
diff --git a/lib/BHeap.cc b/lib/BHeap.cc
index 4d7cc9e..ef4bd04 100644
--- a/lib/BHeap.cc
+++ b/lib/BHeap.cc
@@ -3,8 +3,52 @@
#include "BHeap.h"
#include "CList.h"
+/**********************************\
+* *
+* Tas binomial *
+* *
+\**********************************/
+
+/*
+ *
+ * Le tas binomial implémenté suit exactement les algorithmes présentés dans
+ * le livre "Introduction à l'algorithmique". La structure est récursive et
+ * les données de l'entête sont réparties comme suit:
+ * - Degree = -1 (pour signaler que nous somme dans l'entête)
+ * - Key contient le nombre d'éléments enregistrés
+ * - Brother est le pointeur sur le premier élément du tas
+ *
+ */
+
static int d, Depths[65536];
+
+/*
+ * Cette fonction sert à afficher le contenu du tas binomial sur le stream
+ * passé en argument. L'affichage sera structuré de sorte à ressembler aux
+ * diagrammes présentés dans le livre "Introduction à l'algorithmique", à
+ * ceci près qu'ils sont présentés à la verticale. Exemple:
+ *
+ * * Head cell.
+ * |
+ * |__ 6
+ * |_ 15
+ * | |__ 18
+ * |_ 5
+ * | |_ 10
+ * | | |__ 29
+ * | |__ 9
+ * |_ 2
+ * |_ 3
+ * | |_ 16
+ * | | |__ 23
+ * | |__ 17
+ * |_ 11
+ * | |__ 25
+ * |__ 14
+ *
+ */
+
void BHeap::Dump(ostream & os)
{
int i;
@@ -30,6 +74,12 @@ void BHeap::Dump(ostream & os)
}
}
+
+ /*
+ * Cette fonction est utilisée dans les tests "paranoïaques" pour compter
+ * le nombre véritable de cellules lors d'un parcours récursif.
+ */
+
int BHeap::rn(void)
{
int n = 0;
@@ -46,6 +96,11 @@ int BHeap::rn(void)
return n;
}
+
+ /*
+ * Implémentation directe de la primitive LIEN-BINOMIAL(y, z) avec y = this.
+ */
+
void BHeap::Link(BHeap * z)
{
Father = z;
@@ -54,6 +109,15 @@ void BHeap::Link(BHeap * z)
z->Degree = z->Degree + 1;
}
+
+ /*
+ * Implémentation de la primitive FUSIONNER-TAS-BINOMIAUX(T1, T2) avec T1 = this.
+ * L'algorithme a du être inventer car il n'est pas présenté dans le livre.
+ * Par contre, il s'inspire fortement de l'algorithme "Fusion" pour le
+ * tri-fusion. De plus, contrairement aux indication du livre, T2 sera rajouté
+ * APRES T1, et aucun tas binaire nouveau ne sera créé.
+ */
+
void BHeap::Merge(BHeap * H)
{
BHeap *P1, *P2, *T1, *T2;
@@ -78,21 +142,38 @@ void BHeap::Merge(BHeap * H)
H->Brother = NULL;
}
-BHeap::BHeap(void):Degree(-1), Father(NULL), Child(NULL), Brother(NULL),
-FP(new CList)
+
+ /*
+ * Constructeur d'un tas binomial.
+ */
+
+BHeap::BHeap(void):Degree(-1), Father(NULL), Child(NULL), Brother(NULL), FP(new CList)
{
- type = T_BHEAP;
+ type = T_BHEAP;
}
+
+ /*
+ * Constructeur interne. La structure est récursive, donc nous implémentons
+ * un constructeur privé.
+ */
+
BHeap::BHeap(Key_t IKey, Datas_t const &IDatas):PriorityList(IKey, IDatas),
Degree(0), Father(NULL), Child(NULL), Brother(NULL)
{
- type = T_BHEAP;
+ type = T_BHEAP;
#ifdef DEBUG
nc++;
#endif
}
+
+ /*
+ * Le destructeur. S'il est appelé sur l'entête, nous effacons récursivement
+ * la liste des pointeurs intermédiaires, ainsi que tout le tas
+ * récursivement (voir rapport).
+ */
+
BHeap::~BHeap(void)
{
if (Degree == -1)
@@ -109,6 +190,11 @@ BHeap::~BHeap(void)
#endif
}
+
+ /*
+ * Implémentation directe de l'algorithme MINIMUM-TAS-BINOMIAL(T) avec T = this.
+ */
+
Cell BHeap::Min(void)
{
BHeap *x = this, *y = NULL;
@@ -124,6 +210,12 @@ Cell BHeap::Min(void)
return y->FP;
}
+
+ /*
+ * Insertion d'une cellule déjà créé dans le tas.
+ * La routine fonctionne comme dans l'algorithme conseillé.
+ */
+
Cell BHeap::Insert(BHeap * E)
{
BHeap *H;
@@ -139,6 +231,11 @@ Cell BHeap::Insert(BHeap * E)
return ((E->FP = ((CList *) (FP->Insert(Key, E)))));
}
+
+ /*
+ * Insertion d'un couple (Clef, Données) dans le tas.
+ */
+
Cell BHeap::Insert(Key_t IKey, Datas_t const &IDatas)
{
BHeap *P;
@@ -150,6 +247,15 @@ Cell BHeap::Insert(Key_t IKey, Datas_t const &IDatas)
return (Insert(P));
}
+
+ /*
+ * Implémentation de l'algorithme TAS-BINOMIAL-EXTRAIRE-MIN(T) avec T = this.
+ * La clef extraite sera renvoyée et les données satellites seront écrites dans
+ * la variable Datas. L'implémentation est beaucoup plus longue que
+ * l'algorithme de quatre lignes présenté dans le livre mais il s'agit de la
+ * traduction entre les phrases en français présentées et le langage C.
+ */
+
Key_t BHeap::Extract_Min(Datas_t & Datas)
{
BHeap *x, *y = NULL, *P, *P2, *P3, *Before;
@@ -163,6 +269,8 @@ Key_t BHeap::Extract_Min(Datas_t & Datas)
Key--;
+ // 1. Trouver la racine x de clé minimum dans la liste des racines de T...
+
for (x = Brother; x; x = x->Brother) {
if ((x->Key < min)) {
min = x->Key;
@@ -172,10 +280,14 @@ Key_t BHeap::Extract_Min(Datas_t & Datas)
P = x;
}
+ // ... et supprimer x.
Before->Brother = y->Brother;
+ // 2. T' <- CREER-TAS-BINOMIAL
Before = new BHeap;
+ // 3. inverser l'ordre de la liste chaînée des fils de x,
+ // et faire pointer tête[T'] sur la tête de la liste résultante.
for (P = y->Child; P;) {
P2 = Before->Brother;
P3 = P->Brother;
@@ -184,9 +296,11 @@ Key_t BHeap::Extract_Min(Datas_t & Datas)
P = P3;
}
+ // 4. T <- UNION-TAS-BINOMIAUX(T, T')
Before->Key = 0;
Union(Before);
+ // 5. retourner x (et l'effacer)
k = y->Key;
y->Brother = y->Child = NULL;
FP->Delete(Datas, ((Cell) y->FP));
@@ -196,6 +310,11 @@ Key_t BHeap::Extract_Min(Datas_t & Datas)
return k;
}
+
+ /*
+ * Implémentation directe de l'algorithme UNION-TAS-BINOMIAUX(T1, T2) avec T1 = this.
+ */
+
PriorityList *BHeap::Union(PriorityList * P)
{
BHeap *x, *Before, *After;
@@ -231,6 +350,13 @@ PriorityList *BHeap::Union(PriorityList * P)
return this;
}
+
+ /*
+ * Implémentation de l'algorithme TAS-BINOMIAL-DIMINUER-CLE(T,x,k) avec T = this.
+ * L'implémentation de cette routine a nécessité le rajout d'une table de pointeurs
+ * pour conserver une structure correcte (voir rapport)
+ */
+
bool BHeap::Lower_Key(Cell x, Key_t NKey)
{
BHeap *y, *z, *tx = ((BHeap *) ((CList *) x)->Datas);
@@ -239,8 +365,7 @@ bool BHeap::Lower_Key(Cell x, Key_t NKey)
return false;
tx->Key = NKey;
- for (y = tx, z = tx->Father; z && (y->Key < z->Key);
- y = z, z = y->Father) {
+ for (y = tx, z = tx->Father; z && (y->Key < z->Key); y = z, z = y->Father) {
SWAP(y->Datas, z->Datas);
SWAP(y->Key, z->Key);
SWAP(y->FP, z->FP);
@@ -250,6 +375,13 @@ bool BHeap::Lower_Key(Cell x, Key_t NKey)
return true;
}
+
+ /*
+ * Implémentation directe de l'algorithme TAS-BINOMIAL-SUPPRIMER(T,x) avec T = this.
+ * La valeur de la clef supprimée est renvoyée par la routine et les données satellites
+ * sont écrites dans la variable Datas.
+ */
+
Key_t BHeap::Delete(Datas_t & Datas, Cell x)
{
Key_t K;
@@ -262,16 +394,31 @@ Key_t BHeap::Delete(Datas_t & Datas, Cell x)
return K;
}
+
+ /*
+ * Booléen qui détermine si le tas est vide ou pas.
+ */
+
bool BHeap::IsEmpty(void)
{
return (!(Brother));
}
+
+ /*
+ * Lit la clef d'une cellule d'un tas.
+ */
+
Key_t BHeap::ReadKey(Cell C)
{
return ((BHeap *) ((CList *) C)->Datas)->Key;
}
+
+ /*
+ * Lit les données d'une cellule d'un tas.
+ */
+
Datas_t BHeap::ReadDatas(Cell C)
{
return ((BHeap *) ((CList *) C)->Datas)->Datas;