Skip to content
GitLab
Projets
Groupes
Sujets
Extraits de code
/
Aide
Aide
Support
Forum de la communauté
Raccourcis clavier
?
Proposer une rétroaction
Contribuer à GitLab
Connexion
Activer/désactiver la navigation
Menu
Mathys MACIA
AlgoAvance
Comparer les révisions
ad9389a93ba7d21f09aa2248f915208dbbfa35a6...48bfbd490d74c5ac0c0c1d49be338a0e8516df00
Commits (2)
ajout des tests
· d3d64f4d
Mathys MACIA
a écrit
déc. 02, 2025
d3d64f4d
Merge branch 'test' into 'master'
· 48bfbd49
Mathys MACIA
a écrit
déc. 02, 2025
ajout des tests See merge request
!1
48bfbd49
Tout étendre
Masquer les modifications d'espaces
En ligne
Côte à côte
ABR_insert.csv
Voir le fichier @
48bfbd49
n,1000,2000,5000,10000,20000,50000
n,1000,2000,5000,10000,20000,50000
ASCENDANT,
1231700,00,4418640,00,30034160,00,116455020,0
0,474
819140,00,3056061360,0
0
ASCENDANT,
2741266,60,4242239,60,25764592,60,103848038,6
0,4
2
74
39882,20,2674167635,6
0
ALEATOIRE,
149580,00,167500,0
0,
3
56
340,00,830320,00,1814660,00,560992
0,
0
0
ALEATOIRE,
296387,40,450203,4
0,
6
56
077,20,1670061,80,3761467,60,1195784
0,
2
0
ABR_search.csv
Voir le fichier @
48bfbd49
n,1000,2000,5000,10000,20000,50000
n,1000,2000,5000,10000,20000,50000
ASCENDANT,
2658220,00,9699160,00,60452520,00,233926280,00,907753720,00,5800536280
,00
ASCENDANT,
4158852,60,12248819,80,76968346,20,319434800,40,1309307052,20,8234666725
,00
ALEATOIRE,
128340,00,122680,00,310240,00,577920,00,1311820,00,3409080
,00
ALEATOIRE,
266154,80,235807,80,574324,40,1102771,40,2151257,40,5866763
,00
ARN_insert.csv
Voir le fichier @
48bfbd49
n,1000,2000,5000,10000,20000,50000
n,1000,2000,5000,10000,20000,50000
ASCENDANT,
221140,00,242880,00,405760,00,720540,00,761520,00,1803680,0
0
ASCENDANT,
429293,00,541214,60,1492209,80,1450807,80,1846437,80,4429069,4
0
ALEATOIRE,
153900,00,219500,00,457300,00,938200,00,2106160,00,6222500
,00
ALEATOIRE,
402464,80,359252,00,1019308,20,1808727,00,3546869,20,11937927
,00
ARN_search.csv
Voir le fichier @
48bfbd49
n,1000,2000,5000,10000,20000,50000
n,1000,2000,5000,10000,20000,50000
ASCENDANT,
136940,00,128920,00,320120,0
0,
7
33
100,00,1475920,00,4872060,0
0
ASCENDANT,
353458,80,290777,00,621226,2
0,
1
33
6956,20,2635875,60,9406446,4
0
ALEATOIRE,
51780,00,101540,00,308340,00,616120,00,1244160,00,3500360,0
0
ALEATOIRE,
63701,80,132267,60,378176,00,815282,80,1745943,60,5169691,2
0
pom.xml
Voir le fichier @
48bfbd49
...
@@ -61,13 +61,43 @@
...
@@ -61,13 +61,43 @@
<artifactId>
maven-site-plugin
</artifactId>
<artifactId>
maven-site-plugin
</artifactId>
<version>
3.21.0
</version>
<version>
3.21.0
</version>
</plugin>
</plugin>
</plugins>
<plugin>
<groupId>
org.jacoco
</groupId>
<artifactId>
jacoco-maven-plugin
</artifactId>
<version>
0.8.12
</version>
<executions>
<execution>
<id>
default-prepare-agent
</id>
<goals>
<goal>
prepare-agent
</goal>
</goals>
</execution>
<execution>
<id>
default-report
</id>
<goals>
<goal>
report
</goal>
</goals>
</execution>
<execution>
<id>
default-check
</id>
<goals>
<goal>
check
</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
<pluginManagement>
<pluginManagement>
<plugins>
<plugins>
<plugin>
<plugin>
<groupId>
org.apache.maven.plugins
</groupId>
<groupId>
org.apache.maven.plugins
</groupId>
<artifactId>
maven-checkstyle-plugin
</artifactId>
<artifactId>
maven-checkstyle-plugin
</artifactId>
<version>
3.6.0
</version>
<version>
3.6.0
</version>
<configuration>
<configLocation>
google_checks.xml
</configLocation>
</configuration>
<dependencies>
<dependencies>
<dependency>
<dependency>
<groupId>
com.puppycrawl.tools
</groupId>
<groupId>
com.puppycrawl.tools
</groupId>
...
@@ -102,6 +132,19 @@
...
@@ -102,6 +132,19 @@
<artifactId>
maven-javadoc-plugin
</artifactId>
<artifactId>
maven-javadoc-plugin
</artifactId>
<version>
3.12.0
</version>
<version>
3.12.0
</version>
</plugin>
</plugin>
</plugins>
<plugin>
</reporting>
<groupId>
org.jacoco
</groupId>
<artifactId>
jacoco-maven-plugin
</artifactId>
<version>
0.8.12
</version>
<reportSets>
<reportSet>
<reports>
<!-- select non-aggregate reports -->
<report>
report
</report>
</reports>
</reportSet>
</reportSets>
</plugin>
</plugins>
</reporting>
</project>
</project>
src/main/java/collection/ArbreBinaireRecherche.java
Voir le fichier @
48bfbd49
...
@@ -12,261 +12,282 @@ import java.util.Stack;
...
@@ -12,261 +12,282 @@ import java.util.Stack;
*/
*/
public
class
ArbreBinaireRecherche
<
E
extends
Comparable
<
E
>>
implements
Collection
<
E
>
{
public
class
ArbreBinaireRecherche
<
E
extends
Comparable
<
E
>>
implements
Collection
<
E
>
{
/** Classe interne représentant un nœud de l'arbre */
/** Classe interne représentant un nœud de l'arbre */
private
class
Noeud
{
private
class
Noeud
{
E
cle
;
E
cle
;
Noeud
gauche
,
droit
;
Noeud
gauche
;
Noeud
droit
;
Noeud
(
E
k
)
{
this
.
cle
=
k
;
Noeud
(
E
k
)
{
}
this
.
cle
=
k
;
}
}
}
private
Noeud
racine
;
private
Noeud
racine
;
private
int
size
=
0
;
private
int
taille
=
0
;
@Override
@Override
public
boolean
add
(
E
e
)
{
public
boolean
add
(
E
e
)
{
Objects
.
requireNonNull
(
e
);
Objects
.
requireNonNull
(
e
);
// Si l’arbre est vide : racine = nouvel élément
// Si l’arbre est vide : racine = nouvel élément
if
(
racine
==
null
)
{
if
(
racine
==
null
)
{
racine
=
new
Noeud
(
e
);
racine
=
new
Noeud
(
e
);
size
++;
taille
++;
return
true
;
return
true
;
}
}
Noeud
cur
=
racine
,
parent
=
null
;
Noeud
actuel
=
racine
;
int
cmp
=
0
;
Noeud
parent
=
null
;
int
cmp
=
0
;
// Recherche de la position correcte pour insérer
while
(
cur
!=
null
)
{
// Recherche de la position correcte pour insérer
parent
=
cur
;
while
(
actuel
!=
null
)
{
cmp
=
e
.
compareTo
(
cur
.
cle
);
parent
=
actuel
;
cmp
=
e
.
compareTo
(
actuel
.
cle
);
if
(
cmp
<
0
)
cur
=
cur
.
gauche
;
// aller à gauche
if
(
cmp
<
0
)
{
else
if
(
cmp
>
0
)
actuel
=
actuel
.
gauche
;
// aller à gauche
cur
=
cur
.
droit
;
// aller à droite
}
else
if
(
cmp
>
0
)
{
else
actuel
=
actuel
.
droit
;
// aller à droite
return
false
;
// élément déjà présent
}
else
{
}
return
false
;
// élément déjà présent
}
// Insertion du nœud
}
if
(
cmp
<
0
)
parent
.
gauche
=
new
Noeud
(
e
);
// Insertion du nœud
else
if
(
cmp
<
0
)
{
parent
.
droit
=
new
Noeud
(
e
);
parent
.
gauche
=
new
Noeud
(
e
);
}
else
{
size
++;
parent
.
droit
=
new
Noeud
(
e
);
return
true
;
}
}
/**
taille
++;
* Recherche d'un nœud contenant la clé donnée
return
true
;
*/
}
private
Noeud
findNode
(
E
e
)
{
Noeud
cur
=
racine
;
/**
* Recherche d'un nœud contenant la clé donnée
while
(
cur
!=
null
)
{
*/
int
cmp
=
e
.
compareTo
(
cur
.
cle
);
private
Noeud
findNode
(
E
e
)
{
Noeud
actuel
=
racine
;
if
(
cmp
==
0
)
return
cur
;
while
(
actuel
!=
null
)
{
if
(
cmp
<
0
)
int
cmp
=
e
.
compareTo
(
actuel
.
cle
);
cur
=
cur
.
gauche
;
else
if
(
cmp
==
0
)
{
cur
=
cur
.
droit
;
return
actuel
;
}
}
return
null
;
if
(
cmp
<
0
)
{
actuel
=
actuel
.
gauche
;
}
else
{
actuel
=
actuel
.
droit
;
}
}
}
return
null
;
}
@Override
@Override
public
boolean
contains
(
Object
o
)
{
public
boolean
contains
(
Object
o
)
{
if
(
o
==
null
)
if
(
o
==
null
)
{
return
false
;
return
false
;
try
{
@SuppressWarnings
(
"unchecked"
)
E
e
=
(
E
)
o
;
return
findNode
(
e
)
!=
null
;
}
catch
(
ClassCastException
ex
)
{
return
false
;
}
}
}
@Override
try
{
public
boolean
remove
(
Object
o
)
{
@SuppressWarnings
(
"unchecked"
)
if
(
o
==
null
)
E
e
=
(
E
)
o
;
return
false
;
return
findNode
(
e
)
!=
null
;
}
catch
(
ClassCastException
ex
)
{
try
{
return
false
;
@SuppressWarnings
(
"unchecked"
)
E
e
=
(
E
)
o
;
}
catch
(
ClassCastException
ex
)
{
return
false
;
}
// Suppression simple (remplacement par successeur)
// (Pour les benchmarks, remove n'est pas essentiel)
E
key
=
(
E
)
o
;
Noeud
parent
=
null
,
cur
=
racine
;
// Recherche du nœud à supprimer
while
(
cur
!=
null
&&
!
cur
.
cle
.
equals
(
key
))
{
parent
=
cur
;
if
(
key
.
compareTo
(
cur
.
cle
)
<
0
)
cur
=
cur
.
gauche
;
else
cur
=
cur
.
droit
;
}
if
(
cur
==
null
)
return
false
;
// Cas où le nœud a deux enfants
if
(
cur
.
gauche
!=
null
&&
cur
.
droit
!=
null
)
{
Noeud
succParent
=
cur
,
succ
=
cur
.
droit
;
// Successeur = minimum du sous-arbre droit
while
(
succ
.
gauche
!=
null
)
{
succParent
=
succ
;
succ
=
succ
.
gauche
;
}
// Remplacer la clé
cur
.
cle
=
succ
.
cle
;
parent
=
succParent
;
cur
=
succ
;
}
// Cas 0 ou 1 enfant
Noeud
child
=
(
cur
.
gauche
!=
null
)
?
cur
.
gauche
:
cur
.
droit
;
if
(
parent
==
null
)
racine
=
child
;
else
if
(
parent
.
gauche
==
cur
)
parent
.
gauche
=
child
;
else
parent
.
droit
=
child
;
size
--;
return
true
;
}
}
}
@Override
@Override
public
Iterator
<
E
>
iterator
()
{
public
boolean
remove
(
Object
o
)
{
if
(
o
==
null
)
{
// Parcours en ordre croissant (in-order)
return
false
;
return
new
Iterator
<
E
>()
{
private
final
Stack
<
Noeud
>
st
=
init
(
racine
);
private
Stack
<
Noeud
>
init
(
Noeud
r
)
{
Stack
<
Noeud
>
s
=
new
Stack
<>();
Noeud
c
=
r
;
while
(
c
!=
null
)
{
s
.
push
(
c
);
c
=
c
.
gauche
;
}
return
s
;
}
@Override
public
boolean
hasNext
()
{
return
!
st
.
isEmpty
();
}
@Override
public
E
next
()
{
Noeud
n
=
st
.
pop
();
E
res
=
n
.
cle
;
Noeud
c
=
n
.
droit
;
while
(
c
!=
null
)
{
st
.
push
(
c
);
c
=
c
.
gauche
;
}
return
res
;
}
};
}
}
@Override
try
{
public
int
size
()
{
@SuppressWarnings
(
"unchecked"
)
return
size
;
E
e
=
(
E
)
o
;
}
catch
(
ClassCastException
ex
)
{
return
false
;
}
}
@Override
// Suppression simple (remplacement par successeur)
public
boolean
isEmpty
()
{
// (Pour les benchmarks, remove n'est pas essentiel)
return
size
==
0
;
E
key
=
(
E
)
o
;
Noeud
parent
=
null
;
Noeud
actuel
=
racine
;
// Recherche du nœud à supprimer
while
(
actuel
!=
null
&&
!
actuel
.
cle
.
equals
(
key
))
{
parent
=
actuel
;
if
(
key
.
compareTo
(
actuel
.
cle
)
<
0
)
{
actuel
=
actuel
.
gauche
;
}
else
{
actuel
=
actuel
.
droit
;
}
}
}
@Override
if
(
actuel
==
null
)
{
public
void
clear
()
{
return
false
;
racine
=
null
;
size
=
0
;
}
}
@Override
// Cas où le nœud a deux enfants
public
Object
[]
toArray
()
{
if
(
actuel
.
gauche
!=
null
&&
actuel
.
droit
!=
null
)
{
Object
[]
arr
=
new
Object
[
size
];
Noeud
succParent
=
actuel
;
int
i
=
0
;
Noeud
suivant
=
actuel
.
droit
;
// Successeur = minimum du sous-arbre droit
while
(
suivant
.
gauche
!=
null
)
{
succParent
=
suivant
;
suivant
=
suivant
.
gauche
;
}
// Remplacer la clé
actuel
.
cle
=
suivant
.
cle
;
parent
=
succParent
;
actuel
=
suivant
;
}
for
(
E
e
:
this
)
// Cas 0 ou 1 enfant
arr
[
i
++]
=
e
;
Noeud
child
=
(
actuel
.
gauche
!=
null
)
?
actuel
.
gauche
:
actuel
.
droit
;
return
arr
;
if
(
parent
==
null
)
{
racine
=
child
;
}
else
if
(
parent
.
gauche
==
actuel
)
{
parent
.
gauche
=
child
;
}
else
{
parent
.
droit
=
child
;
}
}
@Override
taille
--;
public
<
T
>
T
[]
toArray
(
T
[]
a
)
{
return
true
;
return
null
;
// même logique que RBTree ; omis pour brièveté
}
@Override
public
Iterator
<
E
>
iterator
()
{
// Parcours en ordre croissant (in-order)
return
new
Iterator
<
E
>()
{
private
final
Stack
<
Noeud
>
st
=
init
(
racine
);
private
Stack
<
Noeud
>
init
(
Noeud
r
)
{
Stack
<
Noeud
>
s
=
new
Stack
<>();
Noeud
c
=
r
;
while
(
c
!=
null
)
{
s
.
push
(
c
);
c
=
c
.
gauche
;
}
return
s
;
}
@Override
public
boolean
hasNext
()
{
return
!
st
.
isEmpty
();
}
@Override
public
E
next
()
{
Noeud
n
=
st
.
pop
();
E
res
=
n
.
cle
;
Noeud
c
=
n
.
droit
;
while
(
c
!=
null
)
{
st
.
push
(
c
);
c
=
c
.
gauche
;
}
return
res
;
}
};
}
@Override
public
int
size
()
{
return
taille
;
}
@Override
public
boolean
isEmpty
()
{
return
taille
==
0
;
}
@Override
public
void
clear
()
{
racine
=
null
;
taille
=
0
;
}
@Override
public
Object
[]
toArray
()
{
Object
[]
arr
=
new
Object
[
taille
];
int
i
=
0
;
for
(
E
e
:
this
)
{
arr
[
i
++]
=
e
;
}
}
@Override
return
arr
;
public
boolean
containsAll
(
Collection
<?>
c
)
{
}
for
(
Object
o
:
c
)
if
(!
contains
(
o
))
@Override
return
false
;
public
<
T
>
T
[]
toArray
(
T
[]
a
)
{
return
null
;
// même logique que RBTree ; omis pour brièveté
}
return
true
;
@Override
public
boolean
containsAll
(
Collection
<?>
c
)
{
for
(
Object
o
:
c
)
{
if
(!
contains
(
o
))
{
return
false
;
}
}
}
@Override
return
true
;
public
boolean
addAll
(
Collection
<?
extends
E
>
c
)
{
}
boolean
ch
=
false
;
for
(
E
e
:
c
)
@Override
ch
|=
add
(
e
);
public
boolean
addAll
(
Collection
<?
extends
E
>
c
)
{
boolean
ch
=
false
;
return
ch
;
for
(
E
e
:
c
)
{
ch
|=
add
(
e
);
}
}
@Override
return
ch
;
public
boolean
removeAll
(
Collection
<?>
c
)
{
}
boolean
ch
=
false
;
for
(
Object
o
:
c
)
@Override
ch
|=
remove
(
o
);
public
boolean
removeAll
(
Collection
<?>
c
)
{
boolean
ch
=
false
;
return
ch
;
for
(
Object
o
:
c
)
{
ch
|=
remove
(
o
);
}
}
@Override
return
ch
;
public
boolean
retainAll
(
Collection
<?>
c
)
{
}
List
<
E
>
del
=
new
ArrayList
<>();
// Construire la liste des éléments à supprimer
@Override
for
(
E
e
:
this
)
public
boolean
retainAll
(
Collection
<?>
c
)
{
if
(!
c
.
contains
(
e
))
List
<
E
>
del
=
new
ArrayList
<>();
del
.
add
(
e
);
// Supprimer les éléments
// Construire la liste des éléments à supprimer
for
(
E
e
:
del
)
for
(
E
e
:
this
)
{
remove
(
e
);
if
(!
c
.
contains
(
e
))
{
del
.
add
(
e
);
}
}
return
!
del
.
isEmpty
();
// Supprimer les éléments
for
(
E
e
:
del
)
{
remove
(
e
);
}
}
return
!
del
.
isEmpty
();
}
}
}
src/main/java/collection/Benchmark.java
Voir le fichier @
48bfbd49
...
@@ -11,128 +11,136 @@ import java.util.Random;
...
@@ -11,128 +11,136 @@ import java.util.Random;
public
class
Benchmark
{
public
class
Benchmark
{
private
static
final
Random
RNG
=
new
Random
(
12345
);
private
static
final
Random
RNG
=
new
Random
(
12345
);
public
static
void
main
(
final
String
[]
args
)
throws
Exception
{
public
static
void
main
(
final
String
[]
args
)
throws
Exception
{
final
int
[]
N_LIST
=
{
1000
,
2000
,
5000
,
10000
,
20000
,
50000
};
final
int
[]
nList
=
{
1000
,
2000
,
5000
,
10000
,
20000
,
50000
};
final
int
REP
=
5
;
final
int
repetition
=
5
;
// --- Create the 4 CSV writers ---
// --- Creation des 4 CSV avec leur enTete ---
PrintWriter
abrInsert
=
new
PrintWriter
(
new
FileWriter
(
"ABR_insert.csv"
));
PrintWriter
abrInsert
=
new
PrintWriter
(
new
FileWriter
(
"ABR_insert.csv"
));
PrintWriter
abrSearch
=
new
PrintWriter
(
new
FileWriter
(
"ABR_search.csv"
));
writeHeader
(
abrInsert
,
nList
);
PrintWriter
arnInsert
=
new
PrintWriter
(
new
FileWriter
(
"ARN_insert.csv"
));
PrintWriter
arnSearch
=
new
PrintWriter
(
new
FileWriter
(
"ARN_search.csv"
));
// Header line : n,1000,2000,...
PrintWriter
abrSearch
=
new
PrintWriter
(
new
FileWriter
(
"ABR_search.csv"
));
writeHeader
(
abrInsert
,
N_LIST
);
writeHeader
(
abrSearch
,
nList
);
writeHeader
(
abrSearch
,
N_LIST
);
writeHeader
(
arnInsert
,
N_LIST
);
writeHeader
(
arnSearch
,
N_LIST
);
// Scenarios
PrintWriter
arnInsert
=
new
PrintWriter
(
new
FileWriter
(
"ARN_insert.csv"
));
List
<
String
>
scenarios
=
Arrays
.
asList
(
"ASCENDANT"
,
"ALEATOIRE"
);
writeHeader
(
arnInsert
,
nList
);
// Process
each
structure
PrintWriter
arnS
ea
r
ch
=
new
PrintWriter
(
new
FileWriter
(
"ARN_search.csv"
));
for
(
String
structure
:
Arrays
.
asList
(
"ABR"
,
"ARN"
))
{
writeHeader
(
arnSearch
,
nList
);
for
(
String
scenario
:
scenarios
)
{
// Scenarios
List
<
String
>
scenarios
=
Arrays
.
asList
(
"ASCENDANT"
,
"ALEATOIRE"
);
// Buffers for one line of insert & search results
// Process each structure
List
<
Double
>
insertLine
=
new
ArrayList
<>();
for
(
String
structure
:
Arrays
.
asList
(
"ABR"
,
"ARN"
))
{
List
<
Double
>
searchLine
=
new
ArrayList
<>();
for
(
int
n
:
N_LIST
)
{
for
(
String
scenario
:
scenarios
)
{
long
insertSum
=
0
;
// Buffers for one line of insert & search results
long
searchSum
=
0
;
List
<
Double
>
insertLine
=
new
ArrayList
<>();
List
<
Double
>
searchLine
=
new
ArrayList
<>();
for
(
int
r
=
0
;
r
<
REP
;
r
++
)
{
for
(
int
n
:
nList
)
{
List
<
Integer
>
keys
=
new
ArrayList
<>();
long
insertSum
=
0
;
for
(
int
i
=
0
;
i
<
n
;
i
++)
long
searchSum
=
0
;
keys
.
add
(
i
);
if
(
scenario
.
equals
(
"ALEATOIRE"
))
{
for
(
int
r
=
0
;
r
<
repetition
;
r
++)
{
Collections
.
shuffle
(
keys
,
new
Random
(
RNG
.
nextLong
()));
}
long
[]
result
=
structure
.
equals
(
"ABR"
)
?
benchmarkABR
(
keys
,
n
)
:
benchmarkARN
(
keys
,
n
);
List
<
Integer
>
keys
=
new
ArrayList
<>();
for
(
int
i
=
0
;
i
<
n
;
i
++)
{
keys
.
add
(
i
);
}
insertSum
+=
result
[
0
];
if
(
scenario
.
equals
(
"ALEATOIRE"
))
{
searchSum
+=
result
[
1
]
;
Collections
.
shuffle
(
keys
,
new
Random
(
RNG
.
nextLong
()))
;
}
}
insertLine
.
add
(
insertSum
/
(
double
)
REP
);
long
[]
result
=
structure
.
equals
(
"ABR"
)
?
benchmarkAbr
(
keys
,
n
)
:
benchmarkArn
(
keys
,
n
);
searchLine
.
add
(
searchSum
/
(
double
)
REP
);
System
.
out
.
printf
(
"Done %s %s n=%d\n"
,
structure
,
scenario
,
n
);
insertSum
+=
result
[
0
];
}
searchSum
+=
result
[
1
];
}
// Write to correct CSV
insertLine
.
add
(
insertSum
/
(
double
)
repetition
);
if
(
structure
.
equals
(
"ABR"
))
{
searchLine
.
add
(
searchSum
/
(
double
)
repetition
);
writeScenarioLine
(
abrInsert
,
scenario
,
insertLine
);
writeScenarioLine
(
abrSearch
,
scenario
,
searchLine
);
}
else
{
writeScenarioLine
(
arnInsert
,
scenario
,
insertLine
);
writeScenarioLine
(
arnSearch
,
scenario
,
searchLine
);
}
}
}
abrInsert
.
close
();
System
.
out
.
printf
(
"Done %s %s n=%d\n"
,
structure
,
scenario
,
n
);
abrSearch
.
close
();
}
arnInsert
.
close
();
arnSearch
.
close
();
System
.
out
.
println
(
"4 CSV créés au format tableau."
);
// Write to correct CSV
if
(
structure
.
equals
(
"ABR"
))
{
writeScenarioLine
(
abrInsert
,
scenario
,
insertLine
);
writeScenarioLine
(
abrSearch
,
scenario
,
searchLine
);
}
else
{
writeScenarioLine
(
arnInsert
,
scenario
,
insertLine
);
writeScenarioLine
(
arnSearch
,
scenario
,
searchLine
);
}
}
}
}
// -------------------------------------------------------
abrInsert
.
close
();
// Helper: header line
abrSearch
.
close
();
// -------------------------------------------------------
arnInsert
.
close
();
private
static
void
writeHeader
(
PrintWriter
pw
,
int
[]
nList
)
{
arnSearch
.
close
();
pw
.
print
(
"n"
);
for
(
int
n
:
nList
)
System
.
out
.
println
(
"4 CSV créés au format tableau."
);
pw
.
print
(
","
+
n
);
}
pw
.
println
();
// -------------------------------------------------------
// Helper: header line
// -------------------------------------------------------
private
static
void
writeHeader
(
PrintWriter
pw
,
int
[]
nlist
)
{
pw
.
print
(
"n"
);
for
(
int
n
:
nlist
)
{
pw
.
print
(
","
+
n
);
}
}
// -------------------------------------------------------
pw
.
println
();
// Helper: write one scenario line
}
// -------------------------------------------------------
private
static
void
writeScenarioLine
(
PrintWriter
pw
,
String
scenario
,
List
<
Double
>
values
)
{
// -------------------------------------------------------
pw
.
print
(
scenario
);
// Helper: write one scenario line
for
(
double
v
:
values
)
// -------------------------------------------------------
pw
.
printf
(
",%.2f"
,
v
);
private
static
void
writeScenarioLine
(
PrintWriter
pw
,
String
scenario
,
List
<
Double
>
values
)
{
pw
.
println
();
pw
.
print
(
scenario
);
for
(
double
v
:
values
)
{
pw
.
printf
(
",%.2f"
,
v
);
}
}
// -------------------------------------------------------
pw
.
println
();
// Benchmark ABR / ARN
}
// -------------------------------------------------------
private
static
long
[]
benchmarkABR
(
List
<
Integer
>
keys
,
int
n
)
{
// -------------------------------------------------------
Collection
<
Integer
>
tree
=
new
ArbreBinaireRecherche
<>();
// Benchmark ABR / ARN
return
runBenchmark
(
tree
,
keys
,
n
);
// -------------------------------------------------------
}
private
static
long
[]
benchmarkA
RN
(
List
<
Integer
>
keys
,
int
n
)
{
private
static
long
[]
benchmarkA
br
(
List
<
Integer
>
keys
,
int
n
)
{
Collection
<
Integer
>
tree
=
new
RedBlackTre
e
<>();
Collection
<
Integer
>
tree
=
new
ArbreBinaireRecherch
e
<>();
return
runBenchmark
(
tree
,
keys
,
n
);
return
runBenchmark
(
tree
,
keys
,
n
);
}
}
private
static
long
[]
runBenchmark
(
Collection
<
Integer
>
tree
,
List
<
Integer
>
keys
,
int
n
)
{
private
static
long
[]
benchmarkArn
(
List
<
Integer
>
keys
,
int
n
)
{
long
t0
=
System
.
nanoTime
();
Collection
<
Integer
>
tree
=
new
RedBlackTree
<>();
for
(
Integer
k
:
keys
)
return
runBenchmark
(
tree
,
keys
,
n
);
tree
.
add
(
k
);
}
long
t1
=
System
.
nanoTime
();
long
t2
=
System
.
nanoTime
();
private
static
long
[]
runBenchmark
(
Collection
<
Integer
>
tree
,
List
<
Integer
>
keys
,
int
n
)
{
for
(
int
x
=
0
;
x
<
2
*
n
;
x
++)
long
t0
=
System
.
nanoTime
();
tree
.
contains
(
x
);
for
(
Integer
k
:
keys
)
{
long
t3
=
System
.
nanoTime
();
tree
.
add
(
k
);
}
long
t1
=
System
.
nanoTime
();
return
new
long
[]
{
t1
-
t0
,
t3
-
t2
};
long
t2
=
System
.
nanoTime
();
for
(
int
x
=
0
;
x
<
2
*
n
;
x
++)
{
tree
.
contains
(
x
);
}
}
long
t3
=
System
.
nanoTime
();
return
new
long
[]
{
t1
-
t0
,
t3
-
t2
};
}
}
}
src/main/java/collection/RedBlackTree.java
Voir le fichier @
48bfbd49
Ce diff est replié.
Cliquez pour l’agrandir.
src/test/java/collection/ArbreBinaireRechercheTest.java
0 → 100644
Voir le fichier @
48bfbd49
package
collection
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertArrayEquals
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertDoesNotThrow
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertEquals
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertFalse
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertNull
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertTrue
;
import
java.util.Arrays
;
import
java.util.Iterator
;
import
java.util.List
;
import
org.junit.jupiter.api.BeforeEach
;
import
org.junit.jupiter.api.Test
;
public
class
ArbreBinaireRechercheTest
{
private
ArbreBinaireRecherche
<
Integer
>
arbre
;
@BeforeEach
void
setUp
()
{
arbre
=
new
ArbreBinaireRecherche
<>();
}
@Test
void
testAdd
()
{
assertTrue
(
arbre
.
add
(
5
));
assertTrue
(
arbre
.
add
(
3
));
assertTrue
(
arbre
.
add
(
7
));
assertFalse
(
arbre
.
add
(
5
));
// doublon
assertEquals
(
3
,
arbre
.
size
());
}
@Test
void
testContains
()
{
arbre
.
add
(
5
);
arbre
.
add
(
2
);
arbre
.
add
(
8
);
assertTrue
(
arbre
.
contains
(
5
));
assertTrue
(
arbre
.
contains
(
2
));
assertFalse
(
arbre
.
contains
(
10
));
assertFalse
(
arbre
.
contains
(
null
));
}
@Test
void
testRemoveFeuille
()
{
arbre
.
add
(
5
);
arbre
.
add
(
3
);
arbre
.
add
(
8
);
assertTrue
(
arbre
.
remove
(
3
));
assertFalse
(
arbre
.
contains
(
3
));
assertEquals
(
2
,
arbre
.
size
());
}
@Test
void
testRemoveNoeudAvecUnEnfant
()
{
arbre
.
add
(
5
);
arbre
.
add
(
3
);
arbre
.
add
(
2
);
// enfant de 3
assertTrue
(
arbre
.
remove
(
3
));
assertTrue
(
arbre
.
contains
(
2
));
assertFalse
(
arbre
.
contains
(
3
));
assertEquals
(
2
,
arbre
.
size
());
}
@Test
void
testRemoveNoeudDeuxEnfants
()
{
arbre
.
add
(
5
);
arbre
.
add
(
3
);
arbre
.
add
(
7
);
arbre
.
add
(
6
);
arbre
.
add
(
8
);
assertTrue
(
arbre
.
remove
(
7
));
assertFalse
(
arbre
.
contains
(
7
));
assertEquals
(
4
,
arbre
.
size
());
}
@Test
void
testIteratorOrdreCroissant
()
{
arbre
.
add
(
5
);
arbre
.
add
(
2
);
arbre
.
add
(
8
);
arbre
.
add
(
1
);
arbre
.
add
(
3
);
Iterator
<
Integer
>
it
=
arbre
.
iterator
();
assertEquals
(
1
,
it
.
next
());
assertEquals
(
2
,
it
.
next
());
assertEquals
(
3
,
it
.
next
());
assertEquals
(
5
,
it
.
next
());
assertEquals
(
8
,
it
.
next
());
assertFalse
(
it
.
hasNext
());
}
@Test
void
testClear
()
{
arbre
.
add
(
4
);
arbre
.
add
(
1
);
arbre
.
add
(
9
);
arbre
.
clear
();
assertTrue
(
arbre
.
isEmpty
());
assertEquals
(
0
,
arbre
.
size
());
assertFalse
(
arbre
.
contains
(
4
));
}
@Test
void
testToArray
()
{
arbre
.
add
(
3
);
arbre
.
add
(
1
);
arbre
.
add
(
2
);
Object
[]
arr
=
arbre
.
toArray
();
assertEquals
(
3
,
arr
.
length
);
assertArrayEquals
(
new
Object
[]
{
1
,
2
,
3
},
arr
);
}
@Test
void
testAddAll
()
{
List
<
Integer
>
list
=
Arrays
.
asList
(
5
,
2
,
8
);
assertTrue
(
arbre
.
addAll
(
list
));
assertEquals
(
3
,
arbre
.
size
());
assertTrue
(
arbre
.
contains
(
8
));
}
@Test
void
testRemoveAll
()
{
arbre
.
add
(
5
);
arbre
.
add
(
2
);
arbre
.
add
(
8
);
List
<
Integer
>
list
=
Arrays
.
asList
(
2
,
8
);
assertTrue
(
arbre
.
removeAll
(
list
));
assertFalse
(
arbre
.
contains
(
2
));
assertFalse
(
arbre
.
contains
(
8
));
assertTrue
(
arbre
.
contains
(
5
));
}
@Test
void
testRetainAll
()
{
arbre
.
add
(
5
);
arbre
.
add
(
2
);
arbre
.
add
(
8
);
List
<
Integer
>
list
=
Arrays
.
asList
(
5
);
assertTrue
(
arbre
.
retainAll
(
list
));
assertTrue
(
arbre
.
contains
(
5
));
assertFalse
(
arbre
.
contains
(
2
));
assertFalse
(
arbre
.
contains
(
8
));
assertEquals
(
1
,
arbre
.
size
());
}
@Test
void
testContainsAvecTypeIncorrect
()
{
arbre
.
add
(
5
);
arbre
.
add
(
3
);
// Un type incompatible doit entraîner catch(ClassCastException) → false
assertFalse
(
arbre
.
contains
(
"texte"
));
// String ≠ Integer
}
@Test
void
testRemoveNull
()
{
arbre
.
add
(
5
);
assertFalse
(
arbre
.
remove
(
null
));
// ne doit jamais lancer d’exception
assertEquals
(
1
,
arbre
.
size
());
assertTrue
(
arbre
.
contains
(
5
));
}
@Test
void
testRemoveRacineNull
()
{
// racine = null
assertTrue
(
arbre
.
isEmpty
());
assertFalse
(
arbre
.
remove
(
10
));
// retirer un élément dans un arbre vide => false
assertTrue
(
arbre
.
isEmpty
());
}
@Test
void
testRemoveSansException
()
{
arbre
.
add
(
10
);
arbre
.
add
(
5
);
arbre
.
add
(
15
);
// Cas normaux
assertDoesNotThrow
(()
->
arbre
.
remove
(
5
));
assertDoesNotThrow
(()
->
arbre
.
remove
(
15
));
assertDoesNotThrow
(()
->
arbre
.
remove
(
10
));
// Retrait sur arbre vide
assertDoesNotThrow
(()
->
arbre
.
remove
(
999
));
// Retrait d’un null
assertDoesNotThrow
(()
->
arbre
.
remove
(
null
));
}
@Test
void
testRemoveAvecSuccesseurProfond
()
{
arbre
.
add
(
10
);
arbre
.
add
(
5
);
arbre
.
add
(
20
);
arbre
.
add
(
15
);
arbre
.
add
(
13
);
// successeur profond
// Suppression du nœud ayant deux enfants
assertTrue
(
arbre
.
remove
(
10
));
// Le successeur (13) doit avoir remplacé la racine
Iterator
<
Integer
>
it
=
arbre
.
iterator
();
assertEquals
(
5
,
it
.
next
());
assertEquals
(
13
,
it
.
next
());
// remplace 10
assertEquals
(
15
,
it
.
next
());
assertEquals
(
20
,
it
.
next
());
assertFalse
(
it
.
hasNext
());
}
@Test
void
testRemoveRacineAvecUnEnfant
()
{
arbre
.
add
(
10
);
arbre
.
add
(
20
);
// enfant droit unique
assertTrue
(
arbre
.
remove
(
10
));
// La racine doit être remplacée par l’enfant (20)
assertEquals
(
20
,
arbre
.
iterator
().
next
());
assertEquals
(
1
,
arbre
.
size
());
}
@Test
void
testIsEmpty
()
{
ArbreBinaireRecherche
<
Integer
>
a
=
new
ArbreBinaireRecherche
<>();
// L'arbre vide
assertTrue
(
a
.
isEmpty
());
// Après insertion
a
.
add
(
1
);
assertFalse
(
a
.
isEmpty
());
// Après suppression
a
.
remove
(
1
);
assertTrue
(
a
.
isEmpty
());
}
@Test
void
testToArrayComplet
()
{
arbre
.
add
(
4
);
arbre
.
add
(
1
);
arbre
.
add
(
3
);
arbre
.
add
(
2
);
Object
[]
arr
=
arbre
.
toArray
();
assertEquals
(
4
,
arr
.
length
);
assertArrayEquals
(
new
Object
[]
{
1
,
2
,
3
,
4
},
arr
);
// Vérification cohérence avec iterator()
int
index
=
0
;
for
(
int
value
:
arbre
)
{
assertEquals
(
value
,
arr
[
index
++]);
}
}
@Test
void
testContainsAll
()
{
arbre
.
add
(
5
);
arbre
.
add
(
2
);
arbre
.
add
(
8
);
// Tous présents
assertTrue
(
arbre
.
containsAll
(
Arrays
.
asList
(
2
,
5
)));
// Un absent
assertFalse
(
arbre
.
containsAll
(
Arrays
.
asList
(
2
,
10
)));
// Collection vide → doit être true
assertTrue
(
arbre
.
containsAll
(
Arrays
.
asList
()));
// Mauvais type → contains(o) doit retourner false
assertFalse
(
arbre
.
containsAll
(
Arrays
.
asList
(
"test"
)));
}
@Test
void
testToArrayGenericRetourNull
()
{
arbre
.
add
(
5
);
arbre
.
add
(
2
);
arbre
.
add
(
9
);
Integer
[]
cible
=
new
Integer
[
3
];
// L’implémentation actuelle doit renvoyer null
assertNull
(
arbre
.
toArray
(
cible
));
}
}
src/test/java/collection/RedBlackTree.java
0 → 100644
Voir le fichier @
48bfbd49
package
collection
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertArrayEquals
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertEquals
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertFalse
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertTrue
;
import
java.util.Arrays
;
import
java.util.Iterator
;
import
java.util.List
;
import
org.junit.jupiter.api.BeforeEach
;
import
org.junit.jupiter.api.Test
;
class
RedBlackTreeTest
{
private
RedBlackTree
<
Integer
>
tree
;
@BeforeEach
void
setUp
()
{
tree
=
new
RedBlackTree
<>();
}
@Test
void
testAddAndContains
()
{
assertTrue
(
tree
.
add
(
10
));
assertTrue
(
tree
.
contains
(
10
));
assertFalse
(
tree
.
add
(
10
));
// pas de doublons
}
@Test
void
testRemove
()
{
tree
.
add
(
20
);
tree
.
add
(
10
);
tree
.
add
(
30
);
assertTrue
(
tree
.
remove
(
20
));
assertFalse
(
tree
.
contains
(
20
));
assertFalse
(
tree
.
remove
(
40
));
// élément inexistant
}
@Test
void
testSizeAndIsEmpty
()
{
assertTrue
(
tree
.
isEmpty
());
tree
.
add
(
1
);
tree
.
add
(
2
);
tree
.
add
(
3
);
assertEquals
(
3
,
tree
.
size
());
assertFalse
(
tree
.
isEmpty
());
}
@Test
void
testClear
()
{
tree
.
add
(
5
);
tree
.
add
(
15
);
tree
.
clear
();
assertEquals
(
0
,
tree
.
size
());
assertTrue
(
tree
.
isEmpty
());
}
@Test
void
testIterator
()
{
tree
.
add
(
3
);
tree
.
add
(
1
);
tree
.
add
(
4
);
tree
.
add
(
2
);
Iterator
<
Integer
>
it
=
tree
.
iterator
();
int
[]
expectedOrder
=
{
1
,
2
,
3
,
4
};
int
i
=
0
;
while
(
it
.
hasNext
())
{
assertEquals
(
expectedOrder
[
i
++],
it
.
next
());
}
assertEquals
(
expectedOrder
.
length
,
i
);
}
@Test
void
testToArray
()
{
tree
.
add
(
7
);
tree
.
add
(
3
);
tree
.
add
(
9
);
Object
[]
arr
=
tree
.
toArray
();
Arrays
.
sort
(
arr
);
// pour comparaison
assertArrayEquals
(
new
Object
[]
{
3
,
7
,
9
},
arr
);
}
@Test
void
testToArrayWithType
()
{
tree
.
add
(
5
);
tree
.
add
(
1
);
tree
.
add
(
8
);
Integer
[]
arr
=
new
Integer
[
3
];
arr
=
tree
.
toArray
(
arr
);
Arrays
.
sort
(
arr
);
assertArrayEquals
(
new
Integer
[]
{
1
,
5
,
8
},
arr
);
}
@Test
void
testAddAllAndContainsAll
()
{
List
<
Integer
>
list
=
Arrays
.
asList
(
10
,
20
,
30
);
assertTrue
(
tree
.
addAll
(
list
));
assertTrue
(
tree
.
containsAll
(
list
));
}
@Test
void
testRemoveAll
()
{
tree
.
add
(
1
);
tree
.
add
(
2
);
tree
.
add
(
3
);
List
<
Integer
>
toRemove
=
Arrays
.
asList
(
2
,
3
,
4
);
assertTrue
(
tree
.
removeAll
(
toRemove
));
assertFalse
(
tree
.
contains
(
2
));
assertFalse
(
tree
.
contains
(
3
));
assertTrue
(
tree
.
contains
(
1
));
}
@Test
void
testRetainAll
()
{
tree
.
add
(
1
);
tree
.
add
(
2
);
tree
.
add
(
3
);
List
<
Integer
>
toRetain
=
Arrays
.
asList
(
2
,
3
,
4
);
assertTrue
(
tree
.
retainAll
(
toRetain
));
assertFalse
(
tree
.
contains
(
1
));
assertTrue
(
tree
.
contains
(
2
));
assertTrue
(
tree
.
contains
(
3
));
}
}