first commit

This commit is contained in:
eslusarz
2026-05-09 20:15:54 +02:00
commit bdbe04ec0d
1305 changed files with 183150 additions and 0 deletions
View File
+4
View File
@@ -0,0 +1,4 @@
#Sat May 02 22:23:18 CEST 2026
host=eslusarzs-MacBook-Pro.local
process-id=5824
user=eslusarz
+140
View File
@@ -0,0 +1,140 @@
!SESSION 2026-05-02 15:49:09.790 -----------------------------------------------
eclipse.buildId=4.39.0.20260305-0817
java.version=21.0.10
java.vendor=Eclipse Adoptium
BootLoader constants: OS=macosx, ARCH=aarch64, WS=cocoa, NL=it_IT
Framework arguments: -product org.eclipse.epp.package.java.product -keyring /Users/eslusarz/.eclipse_keyring
Command-line arguments: -os macosx -ws cocoa -arch aarch64 -product org.eclipse.epp.package.java.product -keyring /Users/eslusarz/.eclipse_keyring
!ENTRY ch.qos.logback.classic 1 0 2026-05-02 15:49:11.538
!MESSAGE Activated before the state location was initialized. Retry after the state location is initialized.
!ENTRY ch.qos.logback.classic 1 0 2026-05-02 15:49:21.417
!MESSAGE Logback config file: /Users/eslusarz/eclipse-workspace/.metadata/.plugins/org.eclipse.m2e.logback/logback.2.7.101.20251017-1242.xml
!ENTRY org.eclipse.jdt.ui 4 0 2026-05-02 17:06:49.880
!MESSAGE AbortCompilation computing hover information in VettoreOrdinabile.java at offset 1115
!STACK 0
org.eclipse.jdt.internal.compiler.problem.AbortCompilation:
at org.eclipse.jdt.internal.compiler.parser.Parser.parse(Parser.java:11585)
at org.eclipse.jdt.internal.compiler.parser.Parser.parse(Parser.java:11975)
at org.eclipse.jdt.internal.compiler.parser.Parser.parse(Parser.java:11916)
at org.eclipse.jdt.internal.compiler.parser.Parser.dietParse(Parser.java:10308)
at org.eclipse.jdt.core.dom.CompilationUnitResolver.parse(CompilationUnitResolver.java:656)
at org.eclipse.jdt.core.dom.CompilationUnitResolver.toCompilationUnit(CompilationUnitResolver.java:1432)
at org.eclipse.jdt.core.dom.CompilationUnitResolver$ECJCompilationUnitResolver.toCompilationUnit(CompilationUnitResolver.java:109)
at org.eclipse.jdt.core.dom.ASTParser.internalCreateASTCached(ASTParser.java:1412)
at org.eclipse.jdt.core.dom.ASTParser.lambda$1(ASTParser.java:1291)
at org.eclipse.jdt.internal.core.JavaModelManager.cacheZipFiles(JavaModelManager.java:5709)
at org.eclipse.jdt.core.dom.ASTParser.internalCreateAST(ASTParser.java:1291)
at org.eclipse.jdt.core.dom.ASTParser.createAST(ASTParser.java:933)
at org.eclipse.jdt.core.manipulation.internal.javadoc.CoreJavadocContentAccessUtility.createAST(CoreJavadocContentAccessUtility.java:350)
at org.eclipse.jdt.core.manipulation.internal.javadoc.CoreJavadocContentAccessUtility.getJavadocNode(CoreJavadocContentAccessUtility.java:318)
at org.eclipse.jdt.core.manipulation.internal.javadoc.CoreJavadocAccess.javadoc2HTML(CoreJavadocAccess.java:423)
at org.eclipse.jdt.core.manipulation.internal.javadoc.CoreJavadocAccess.getHTMLContentFromSource(CoreJavadocAccess.java:363)
at org.eclipse.jdt.core.manipulation.internal.javadoc.CoreJavadocAccess.getHTMLContent(CoreJavadocAccess.java:229)
at org.eclipse.jdt.internal.ui.text.javadoc.JavadocContentAccess2.getHTMLContent(JavadocContentAccess2.java:49)
at org.eclipse.jdt.internal.ui.text.java.hover.JavadocHover.getHoverInfo(JavadocHover.java:794)
at org.eclipse.jdt.internal.ui.text.java.hover.JavadocHover.internalGetHoverInfo(JavadocHover.java:712)
at org.eclipse.jdt.internal.ui.text.java.hover.JavadocHover.getHoverInfo2(JavadocHover.java:704)
at org.eclipse.jdt.internal.ui.text.java.hover.BestMatchHover.getHoverInfo2(BestMatchHover.java:165)
at org.eclipse.jdt.internal.ui.text.java.hover.BestMatchHover.getHoverInfo2(BestMatchHover.java:131)
at org.eclipse.jdt.internal.ui.text.java.hover.JavaEditorTextHoverProxy.getHoverInfo2(JavaEditorTextHoverProxy.java:89)
at org.eclipse.jface.text.TextViewerHoverManager$1.run(TextViewerHoverManager.java:155)
Suppressed: java.lang.Throwable: Source line 43 :
-----
*/
public Object leggi(int indice) {
if (indice >= 0 && indice < dimensioneCorrente) {
return vettore[indice];
} else return null;
}
/**
* Funzione che restituisce la dimensione corrente
*/
public int |dimensione() {
-----
at org.eclipse.jdt.internal.ui.util.SelectionUtil.logException(SelectionUtil.java:157)
at org.eclipse.jdt.internal.ui.text.java.hover.BestMatchHover.getHoverInfo2(BestMatchHover.java:178)
... 3 more
!SESSION 2026-05-02 18:59:47.521 -----------------------------------------------
eclipse.buildId=4.39.0.20260305-0817
java.version=21.0.10
java.vendor=Eclipse Adoptium
BootLoader constants: OS=macosx, ARCH=aarch64, WS=cocoa, NL=it_IT
Framework arguments: -product org.eclipse.epp.package.java.product -keyring /Users/eslusarz/.eclipse_keyring
Command-line arguments: -os macosx -ws cocoa -arch aarch64 -product org.eclipse.epp.package.java.product -keyring /Users/eslusarz/.eclipse_keyring
!ENTRY ch.qos.logback.classic 1 0 2026-05-02 18:59:49.086
!MESSAGE Activated before the state location was initialized. Retry after the state location is initialized.
!ENTRY org.eclipse.core.resources 2 10035 2026-05-02 19:00:14.060
!MESSAGE The workspace exited with unsaved changes in the previous session; refreshing workspace to recover changes.
!ENTRY ch.qos.logback.classic 1 0 2026-05-02 19:00:14.351
!MESSAGE Logback config file: /Users/eslusarz/eclipse-workspace/.metadata/.plugins/org.eclipse.m2e.logback/logback.2.7.101.20251017-1242.xml
!SESSION 2026-05-02 22:23:14.251 -----------------------------------------------
eclipse.buildId=4.39.0.20260305-0817
java.version=21.0.10
java.vendor=Eclipse Adoptium
BootLoader constants: OS=macosx, ARCH=aarch64, WS=cocoa, NL=it_IT
Framework arguments: -product org.eclipse.epp.package.java.product -keyring /Users/eslusarz/.eclipse_keyring
Command-line arguments: -os macosx -ws cocoa -arch aarch64 -product org.eclipse.epp.package.java.product -keyring /Users/eslusarz/.eclipse_keyring
!ENTRY ch.qos.logback.classic 1 0 2026-05-02 22:23:15.125
!MESSAGE Activated before the state location was initialized. Retry after the state location is initialized.
!ENTRY ch.qos.logback.classic 1 0 2026-05-02 22:23:18.713
!MESSAGE Logback config file: /Users/eslusarz/eclipse-workspace/.metadata/.plugins/org.eclipse.m2e.logback/logback.2.7.101.20251017-1242.xml
!ENTRY org.eclipse.jdt.core 4 4 2026-05-08 17:27:30.428
!MESSAGE Could not retrieve declared methods
!STACK 0
java.lang.NullPointerException: Cannot store to object array because "this.types[this.typeid]" is null
at org.eclipse.jdt.internal.compiler.lookup.TypeSystem.getWildcard(TypeSystem.java:411)
at org.eclipse.jdt.internal.compiler.lookup.AnnotatableTypeSystem.getWildcard(AnnotatableTypeSystem.java:207)
at org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment.getTypeFromVariantTypeSignature(LookupEnvironment.java:2344)
at org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment.getTypeArgumentsFromSignature(LookupEnvironment.java:1986)
at org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment.getTypeFromTypeSignature(LookupEnvironment.java:2274)
at org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding.createMethod(BinaryTypeBinding.java:1005)
at org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding.createMethods(BinaryTypeBinding.java:1165)
at org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding.cachePartsFrom2(BinaryTypeBinding.java:601)
at org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding.cachePartsFrom(BinaryTypeBinding.java:442)
at org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment.createBinaryTypeFrom(LookupEnvironment.java:1148)
at org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment.createBinaryTypeFrom(LookupEnvironment.java:1129)
at org.eclipse.jdt.internal.compiler.Compiler.accept(Compiler.java:183)
at org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment.askForType(LookupEnvironment.java:338)
at org.eclipse.jdt.internal.compiler.lookup.UnresolvedReferenceBinding.resolve(UnresolvedReferenceBinding.java:116)
at org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding.resolveType(BinaryTypeBinding.java:245)
at org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding.resolve(ParameterizedTypeBinding.java:1210)
at org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding.resolveType(BinaryTypeBinding.java:216)
at org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding.resolveTypesFor(BinaryTypeBinding.java:1891)
at org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding.methods(BinaryTypeBinding.java:1802)
at org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding.methods(ParameterizedTypeBinding.java:1128)
at org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding.availableMethods(ReferenceBinding.java:289)
at org.eclipse.jdt.core.dom.TypeBinding.getDeclaredMethods(TypeBinding.java:279)
at org.eclipse.jdt.internal.corext.dom.ScopeAnalyzer.addInherited(ScopeAnalyzer.java:222)
at org.eclipse.jdt.internal.corext.dom.ScopeAnalyzer.addInherited(ScopeAnalyzer.java:206)
at org.eclipse.jdt.internal.corext.dom.ScopeAnalyzer.getDeclarationsInScope(ScopeAnalyzer.java:401)
at org.eclipse.jdt.internal.ui.text.correction.UnresolvedElementsBaseSubProcessor.collectMethodProposals(UnresolvedElementsBaseSubProcessor.java:1455)
at org.eclipse.jdt.internal.ui.text.correction.UnresolvedElementsSubProcessor.getMethodProposals(UnresolvedElementsSubProcessor.java:155)
at org.eclipse.jdt.internal.ui.text.correction.QuickFixProcessor.process(QuickFixProcessor.java:398)
at org.eclipse.jdt.internal.ui.text.correction.QuickFixProcessor.getCorrections(QuickFixProcessor.java:370)
at org.eclipse.jdt.internal.ui.text.correction.JavaCorrectionProcessor$SafeCorrectionCollector.safeRun(JavaCorrectionProcessor.java:381)
at org.eclipse.jdt.internal.ui.text.correction.JavaCorrectionProcessor$SafeCorrectionProcessorAccess.run(JavaCorrectionProcessor.java:341)
at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:47)
at org.eclipse.jdt.internal.ui.text.correction.JavaCorrectionProcessor$SafeCorrectionProcessorAccess.process(JavaCorrectionProcessor.java:336)
at org.eclipse.jdt.internal.ui.text.correction.JavaCorrectionProcessor.collectCorrections(JavaCorrectionProcessor.java:465)
at org.eclipse.jdt.internal.ui.text.java.hover.ProblemHover$ProblemInfo.getJavaAnnotationFixes(ProblemHover.java:115)
at org.eclipse.jdt.internal.ui.text.java.hover.ProblemHover$ProblemInfo.computeCompletionProposals(ProblemHover.java:89)
at org.eclipse.jdt.internal.ui.text.java.hover.ProblemHover$ProblemInfo.<init>(ProblemHover.java:74)
at org.eclipse.jdt.internal.ui.text.java.hover.ProblemHover.createAnnotationInfo(ProblemHover.java:178)
at org.eclipse.jdt.internal.ui.text.java.hover.AbstractAnnotationHover.getHoverInfo2(AbstractAnnotationHover.java:957)
at org.eclipse.jdt.internal.ui.text.java.hover.BestMatchHover.getHoverInfo2(BestMatchHover.java:165)
at org.eclipse.jdt.internal.ui.text.java.hover.BestMatchHover.getHoverInfo2(BestMatchHover.java:131)
at org.eclipse.jdt.internal.ui.text.java.hover.JavaEditorTextHoverProxy.getHoverInfo2(JavaEditorTextHoverProxy.java:89)
at org.eclipse.jface.text.TextViewerHoverManager$1.run(TextViewerHoverManager.java:155)
Suppressed: java.lang.RuntimeException: RuntimeException loading =asdl/\/Users\/eslusarz\/.p2\/pool\/plugins\/org.eclipse.justj.openjdk.hotspot.jre.full.macosx.aarch64_21.0.10.v20260205-0638\/jre\/lib\/jrt-fs.jar`java.base=/javadoc_location=/https:\/\/docs.oracle.com\/en\/java\/javase\/21\/docs\/api\/=/=/module=/true=/|java/util/Comparator.class
at org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding.cachePartsFrom(BinaryTypeBinding.java:446)
... 34 more
Binary file not shown.
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,305 @@
package binary_tree;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Stack;
public class LinkedBinaryTree<E> implements BinaryTree<E>{
// VARIABILI D'INSTANZA
private BinaryNode<E> root;
private int size;
// Metodi costruttori
public LinkedBinaryTree() {
root = null;
size = 0;
}
public LinkedBinaryTree(E data) {
root = new BinaryNode<E>(data);
size = 1;
}
public LinkedBinaryTree(LinkedBinaryTree<E> left, E data, LinkedBinaryTree<E> right) {
root = new BinaryNode<E>(left.root, data, right.root);
size = 1 + left.size + right.size;
}
// METODI
public int size() {
return size;
}
@Override
public boolean isEmpty() {
return root == null;
}
public E getRoot() {
if (isEmpty()) return null;
return root.getData();
}
public BinaryNode<E> getRootNode() {
if (isEmpty()) return null;
return root;
}
public void clear() {
root = null;
size = 0;
}
private int getSize(BinaryNode<E> node) {
if (node == null) return 0;
int nLeft = (node.getLeft() == null) ? 0 : getSize(node.getLeft());
int nRight = (node.getRight() == null) ? 0 : getSize(node.getRight());
return 1 + nLeft + nRight;
}
public LinkedBinaryTree<E> removeLeft() {
LinkedBinaryTree<E> leftTree = null;
if (root.getLeft() == null) return leftTree;
leftTree = new LinkedBinaryTree<E>();
leftTree.root = root.getLeft();
leftTree.size = getSize(root.getLeft());
leftTree.root.setAsRoot();
size = size - leftTree.size;
return leftTree;
}
public LinkedBinaryTree<E> removeRight() {
LinkedBinaryTree<E> rightTree = null;
if (root.getRight() == null) return rightTree;
rightTree = new LinkedBinaryTree<E>();
rightTree.root = root.getRight();
rightTree.size = getSize(root.getRight());
rightTree.root.setAsRoot();
size = size - rightTree.size;
return rightTree;
}
protected BinaryNode<E> find(E targetElement, BinaryNode<E> root) {
if (root == null) return null;
if (root.getData().equals(targetElement)) return root;
BinaryNode<E> resNode;
resNode = find(targetElement, root.getLeft());
if (resNode == null) resNode = find(targetElement, root.getRight());
return resNode;
}
public boolean remove(E targetElement) {
if (targetElement == null) return false;
BinaryNode<E> temp = find(targetElement, root);
if (temp != null) {
temp.setData(null);
return true;
}
return false;
}
public boolean contains(E targetElement) {
return find(targetElement, root) != null;
}
// ITERATORE PREORDER
/*
* Qui si utilizza il metodo del preorder.
* Le regole per il preorder sono queste:
* - Visita prima se stesso
* - Poi visita tutto ciò che si trova sinistra
* - Infine visita tutto ciò che si trova a destra
*/
protected void preorder (BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
if (node.getData() != null) temporaryList.add(node.getData());
preorder(node.getLeft(), temporaryList);
preorder(node.getRight(), temporaryList);
}
public Iterator<E> iteratorPreOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
preorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE INORDER
/*
* Qui si utilizza il metodo del inorder.
* Le regole per l'inorder sono queste:
* - Visita prima tutto ciò che si trova a sinistra
* - Poi visita se stesso
* - Infine visita tutto ciò che si trova a destra
*/
protected void inorder(BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
inorder(node.getLeft(), temporaryList);
if (node.getData() != null) temporaryList.add(node.getData());
inorder(node.getRight(), temporaryList);
}
public Iterator<E> iteratorInOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
inorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE POSTORDER
/*
* Qui si utilizza il metodo postorder.
* Le regole per il postorder sono queste:
* - Visita prima di tutto ciò che si trova a sinistra
* - Poi visita tutto ciò che si trova a destra
* - Infine visita il sestesso
*/
protected void postorder(BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
postorder(node.getLeft(), temporaryList);
postorder(node.getRight(), temporaryList);
if (node.getData() != null) temporaryList.add(node.getData());
}
public Iterator<E> iteratorPostOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
postorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE LEVEL ORDER
/*
* Qui si usa il metodo levelorder.
* Si analizza tutto il livello dell'albero.
* Per chiarire di seguito un esempio:
*
* A
* / \
* B C
* / \ \
* D E F
*
* La lettura avviene quindi in questo modo:
* A - B - C - D - E - F
*
* Si adopera una coda (Queue) di tipo FI-FO (First In - First Out)
*/
protected void levelorder(BinaryNode<E> node, List<E> temporaryList) {
Queue<BinaryNode<E>> queueOfNodes = new LinkedList<BinaryNode<E>>();
BinaryNode<E> current;
queueOfNodes.add(node);
while(!queueOfNodes.isEmpty()) {
current = queueOfNodes.remove();
if (current.getData() != null) temporaryList.add(current.getData());
if (current.getLeft() != null) queueOfNodes.add(current.getLeft());
if (current.getRight() != null) queueOfNodes.add(current.getRight());
}
}
public Iterator<E> iteratorLevelOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
levelorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE
public Iterator<E> iterator() {
return iteratorPreOrder();
}
// ITERATORE PREORDER ITERATIVO (NON RICORSIVO)
/*
* In questo caso stiamo usando un tipo stack.
* Dobbiamo di fatto simulare uno stack se vogliamo
* iterativamente fare questa cosa.
*
* Perchè se prima dobbiamo visitare il nodo centrale,
* poi il nodo a sinistra e poi il nodo a destra inseriamo
* prima quello di destra e poi quello di sinistra?
*
* Lo stack di fatto è una coda LIFO, ovvero last in - first out
* e quindi l'ultimo che entra è il primo che esce.
*
* dal momento che vale questa cosa, se facciamo entrare prima quello
* di destra e poi quello di sinistra, il primo nodo che verrà
* prelevato è ovviamente quello a sinistra.
*/
protected void itpreorder (BinaryNode<E> node, List<E> temporaryList) {
Stack<BinaryNode<E>> queueOfNodes = new Stack<BinaryNode<E>>();
BinaryNode<E> current;
queueOfNodes.add(node);
while (!queueOfNodes.isEmpty()) {
current = queueOfNodes.pop();
if (current.getData() != null) temporaryList.add(current.getData());
// Come già spiegato pushamo prima il nodo di destra
if (current.getRight() != null) queueOfNodes.push(current.getRight());
// Infine aggiungiamo il nodo di sinistra
if (current.getLeft() != null) queueOfNodes.push(current.getLeft());
}
}
public Iterator<E> ititeratorInOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
itpreorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATOR INORDER ITERATIVO (NON RICORSIVO)
/*
* Questo metodo riguarda lo stesso di quello superiore.
* Il metodo inorder richiede che si visiti prima sinistra,
* poi il nodo stesso, infine il nodo di destra.
*
* Possiamo quindi sempre adoperare uno Stack per siumlare la
* ricorsione.
*
* Come detto prima, se il primo nodo ad essere prelevato è
* l'ultimo che si inserisce (coda LIFO, Stack) allora per simulare
* sinistra -> centro -> destra, il primo nodo da inserire è quello di
* destra
*/
private void itinorder(BinaryNode<E> node, List<E> temporaryList) {
Stack<BinaryNode<E>> queueOfNodes = new Stack<BinaryNode<E>>();
BinaryNode<E> current;
queueOfNodes.add(node);
while () {
}
}
}
@@ -0,0 +1,31 @@
package binary_tree;
public class LinkedBinaryTree<E> implements BinaryTree<E>{
// VARIABILI D'INSTANZA
private BinaryNode<E> root;
private int size;
// Metodi costruttori
public LinkedBinaryTree() {
root = null;
size = 0;
}
public LinkedBinaryTree(E data) {
root = new BinaryNode<E>(data);
size = 1;
}
public LinkedBinaryTree(LinkedBinaryTree<E> left, E data, LinkedBinaryTree<E> right) {
root = new BinaryNode<E>();
}
// METODI
@Override
public boolean isEmpty() {
}
}
@@ -0,0 +1,491 @@
package binary_tree;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Stack;
public class LinkedBinaryTree<E> implements BinaryTree<E>{
// VARIABILI D'INSTANZA
private BinaryNode<E> root;
private int size;
// Metodi costruttori
public LinkedBinaryTree() {
root = null;
size = 0;
}
public LinkedBinaryTree(E data) {
root = new BinaryNode<E>(data);
size = 1;
}
public LinkedBinaryTree(LinkedBinaryTree<E> left, E data, LinkedBinaryTree<E> right) {
root = new BinaryNode<E>(left.root, data, right.root);
size = 1 + left.size + right.size;
}
// METODI
public int size() {
return size;
}
@Override
public boolean isEmpty() {
return root == null;
}
public E getRoot() {
if (isEmpty()) return null;
return root.getData();
}
public BinaryNode<E> getRootNode() {
if (isEmpty()) return null;
return root;
}
public void clear() {
root = null;
size = 0;
}
private int getSize(BinaryNode<E> node) {
if (node == null) return 0;
int nLeft = (node.getLeft() == null) ? 0 : getSize(node.getLeft());
int nRight = (node.getRight() == null) ? 0 : getSize(node.getRight());
return 1 + nLeft + nRight;
}
public LinkedBinaryTree<E> removeLeft() {
LinkedBinaryTree<E> leftTree = null;
if (root.getLeft() == null) return leftTree;
leftTree = new LinkedBinaryTree<E>();
leftTree.root = root.getLeft();
leftTree.size = getSize(root.getLeft());
leftTree.root.setAsRoot();
size = size - leftTree.size;
return leftTree;
}
public LinkedBinaryTree<E> removeRight() {
LinkedBinaryTree<E> rightTree = null;
if (root.getRight() == null) return rightTree;
rightTree = new LinkedBinaryTree<E>();
rightTree.root = root.getRight();
rightTree.size = getSize(root.getRight());
rightTree.root.setAsRoot();
size = size - rightTree.size;
return rightTree;
}
protected BinaryNode<E> find(E targetElement, BinaryNode<E> root) {
if (root == null) return null;
if (root.getData().equals(targetElement)) return root;
BinaryNode<E> resNode;
resNode = find(targetElement, root.getLeft());
if (resNode == null) resNode = find(targetElement, root.getRight());
return resNode;
}
public boolean remove(E targetElement) {
if (targetElement == null) return false;
BinaryNode<E> temp = find(targetElement, root);
if (temp != null) {
temp.setData(null);
return true;
}
return false;
}
public boolean contains(E targetElement) {
return find(targetElement, root) != null;
}
// ITERATORE PREORDER
/*
* Qui si utilizza il metodo del preorder.
* Le regole per il preorder sono queste:
* - Visita prima se stesso
* - Poi visita tutto ciò che si trova sinistra
* - Infine visita tutto ciò che si trova a destra
*/
protected void preorder (BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
if (node.getData() != null) temporaryList.add(node.getData());
preorder(node.getLeft(), temporaryList);
preorder(node.getRight(), temporaryList);
}
public Iterator<E> iteratorPreOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
preorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE INORDER
/*
* Qui si utilizza il metodo del inorder.
* Le regole per l'inorder sono queste:
* - Visita prima tutto ciò che si trova a sinistra
* - Poi visita se stesso
* - Infine visita tutto ciò che si trova a destra
*/
protected void inorder(BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
inorder(node.getLeft(), temporaryList);
if (node.getData() != null) temporaryList.add(node.getData());
inorder(node.getRight(), temporaryList);
}
public Iterator<E> iteratorInOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
inorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE POSTORDER
/*
* Qui si utilizza il metodo postorder.
* Le regole per il postorder sono queste:
* - Visita prima di tutto ciò che si trova a sinistra
* - Poi visita tutto ciò che si trova a destra
* - Infine visita il sestesso
*/
protected void postorder(BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
postorder(node.getLeft(), temporaryList);
postorder(node.getRight(), temporaryList);
if (node.getData() != null) temporaryList.add(node.getData());
}
public Iterator<E> iteratorPostOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
postorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE LEVEL ORDER
/*
* Qui si usa il metodo levelorder.
* Si analizza tutto il livello dell'albero.
* Per chiarire di seguito un esempio:
*
* A
* / \
* B C
* / \ \
* D E F
*
* La lettura avviene quindi in questo modo:
* A - B - C - D - E - F
*
* Si adopera una coda (Queue) di tipo FI-FO (First In - First Out)
*/
protected void levelorder(BinaryNode<E> node, List<E> temporaryList) {
Queue<BinaryNode<E>> queueOfNodes = new LinkedList<BinaryNode<E>>();
BinaryNode<E> current;
queueOfNodes.add(node);
while(!queueOfNodes.isEmpty()) {
current = queueOfNodes.remove();
if (current.getData() != null) temporaryList.add(current.getData());
if (current.getLeft() != null) queueOfNodes.add(current.getLeft());
if (current.getRight() != null) queueOfNodes.add(current.getRight());
}
}
public Iterator<E> iteratorLevelOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
levelorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE
public Iterator<E> iterator() {
return iteratorPreOrder();
}
// ITERATORE PREORDER ITERATIVO (NON RICORSIVO)
/*
* In questo caso stiamo usando un tipo stack.
* Dobbiamo di fatto simulare uno stack se vogliamo
* iterativamente fare questa cosa.
*
* Perchè se prima dobbiamo visitare il nodo centrale,
* poi il nodo a sinistra e poi il nodo a destra inseriamo
* prima quello di destra e poi quello di sinistra?
*
* Lo stack di fatto è una coda LIFO, ovvero last in - first out
* e quindi l'ultimo che entra è il primo che esce.
*
* dal momento che vale questa cosa, se facciamo entrare prima quello
* di destra e poi quello di sinistra, il primo nodo che verrà
* prelevato è ovviamente quello a sinistra.
*/
protected void itpreorder (BinaryNode<E> node, List<E> temporaryList) {
Stack<BinaryNode<E>> queueOfNodes = new Stack<BinaryNode<E>>();
BinaryNode<E> current;
queueOfNodes.add(node);
while (!queueOfNodes.isEmpty()) {
current = queueOfNodes.pop();
if (current.getData() != null) temporaryList.add(current.getData());
// Come già spiegato pushamo prima il nodo di destra
if (current.getRight() != null) queueOfNodes.push(current.getRight());
// Infine aggiungiamo il nodo di sinistra
if (current.getLeft() != null) queueOfNodes.push(current.getLeft());
}
}
public Iterator<E> ititeratorPreOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
itpreorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATOR INORDER ITERATIVO (NON RICORSIVO)
/*
* Questo metodo riguarda lo stesso di quello superiore.
* Il metodo inorder richiede che si visiti prima sinistra,
* poi il nodo stesso, infine il nodo di destra.
*
* Possiamo quindi sempre adoperare uno Stack per siumlare la
* ricorsione.
*
* Come detto prima, se il primo nodo ad essere prelevato è
* l'ultimo che si inserisce (coda LIFO, Stack) allora per simulare
* sinistra -> centro -> destra.
*
* Nel metodo sono state inserite delle check con uno stack di
* flag che permette di capire quando il nodo centrale è visitare
* oppure no.
*/
private void itinorder(BinaryNode<E> node, List<E> temporaryList) {
Stack<BinaryNode<E>> queueOfNodes = new Stack<BinaryNode<E>>();
Stack<Boolean> flags = new Stack<Boolean>();
BinaryNode<E> current;
Boolean flag;
queueOfNodes.add(node);
flags.push(false);
while (!queueOfNodes.isEmpty()) {
current = queueOfNodes.pop();
flag = flags.pop();
if (flag) {
// il nodo è da visitare
if (current.getData() != null) temporaryList.add(current.getData());
} else {
// il nodo non è da visitare
// prima si aggiunge il nodo di destra
if (current.getRight() != null) {
queueOfNodes.add(current.getRight());
flags.add(false);
}
queueOfNodes.push(current);
flags.push(true);
if (current.getLeft() != null) {
queueOfNodes.add(current.getLeft());
flags.push(false);
}
}
}
}
public Iterator<E> ititeratorInOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
itinorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATOR POST ORDER ITERATIVO (NON RICORSIVO)
/*
* In questo caso la logica è la seguente. si ha la
* necessità di fare il seguente ciclo: SINISTRA -> DESTRA -> NODO CORRENTE
*
* Per simulare lo stack dobbiamo quindi ripercorrerlo al contrario,
* dunque NODO CORRENTE -> DESTRA -> SINISTRA
*
* Possiamo dunque rifare lo stesso, di ciò che abbiamo fatto sopra.
*/
protected void itpostorder(BinaryNode<E> node, List<E> temporaryList) {
Stack<BinaryNode<E>> queueOfNodes = new Stack<BinaryNode<E>>();
Stack<Boolean> flags = new Stack<Boolean>();
BinaryNode<E> current;
Boolean flag;
queueOfNodes.push(node);
flags.push(false);
while (!queueOfNodes.isEmpty()) {
current = queueOfNodes.pop();
flag = flags.pop();
if (flag) {
// il nodo è da visitare
if (current.getData() != null) temporaryList.add(current.getData());
} else {
// il nodo non è ancora da visitare
// Visitiamo il nodo corrente
queueOfNodes.push(current);
flags.push(true);
// visitiamo il nodo di destra
if (current.getRight() != null) {
queueOfNodes.push(current.getRight());
flags.push(false);
}
// visitiamo il nodo di sinistra infine
if (current.getLeft() != null) {
queueOfNodes.push(current.getLeft());
flags.push(false);
}
}
}
}
public Iterator<E> ititeratorPostOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
itpostorder(root, temporaryList);
return temporaryList.iterator();
}
/*
* II parziale 2022/2023
* Realizzare un metodo costruttore della classe LinkedBinaryTree<E> che
* prende in input una lista di oggetti di tipo E e costruisce una catena
* casuale tale che l'iesimo elemento della lista è posizionato al livello iesimo
* della catena e ogni nodo ha probabilità 1/2 di avere un figlio sinistro/destro.
*/
/*
* Spiegazione intuitiva (visto che la melideo intende complicare la consegna):
* Data ad esempio una lista del genere:
* [A, B, C, D]
*
* Si ottiene quindi una catena del genere:
* A
* \
* B
* /
* C
* \
* D
*/
public LinkedBinaryTree(List<E> objectList) {
if (objectList == null) throw new NullPointerException();
Iterator<E> iterator = objectList.iterator();
if (!iterator.hasNext()) return;
E currentObject = iterator.next();
root = new BinaryNode<E>(currentObject);
BinaryNode<E> currentNode = root;
currentNode.setData(currentObject);
size = 1;
while (iterator.hasNext()) {
currentObject = iterator.next();
int wing = (int) (Math.random() * 2);
BinaryNode<E> newNode = new BinaryNode<E>(currentObject);
if (wing == 0) {
// Left
newNode.setParentAsLeftChild(currentNode);
} else {
// Right
newNode.setParentAsRightChild(currentNode);
}
currentNode = newNode;
size++;
}
}
/*
* II parziale 2022
* Si aggiunga alla classe LinkedBinaryTree<E> un metodo
* che stampa le foglie dall'albero corrente (da sinistra verso destra)
*/
public void printLeaf() {
printLeaf(root);
}
public void printLeaf(BinaryNode<E> node) {
if (node == null) return;
if (node.getLeft() == null && node.getRight() == null) System.out.println(node.getData().toString());
else {
printLeaf(node.getLeft());
printLeaf(node.getRight());
}
}
/*
* Si aggiunga alla classe LinkedBinaryTree<E> un metodo che conta il numero
* di foglie dell'albero corrente
*/
public int numberLeaf() {
Integer number = 0;
numberLeaf(root, number);
return number;
}
public int numberLeaf(BinaryNode<E> node) {
if (node == null) return 0;
int nLeft = (node.getLeft() == null) ? 0 : numberLeaf(node.getLeft());
int nRight = (node.getRight() == null) ? 0 : numberLeaf(node.getRight());
int i;
if ()
return n
}
}
@@ -0,0 +1,327 @@
package binary_tree;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Stack;
public class LinkedBinaryTree<E> implements BinaryTree<E>{
// VARIABILI D'INSTANZA
private BinaryNode<E> root;
private int size;
// Metodi costruttori
public LinkedBinaryTree() {
root = null;
size = 0;
}
public LinkedBinaryTree(E data) {
root = new BinaryNode<E>(data);
size = 1;
}
public LinkedBinaryTree(LinkedBinaryTree<E> left, E data, LinkedBinaryTree<E> right) {
root = new BinaryNode<E>(left.root, data, right.root);
size = 1 + left.size + right.size;
}
// METODI
public int size() {
return size;
}
@Override
public boolean isEmpty() {
return root == null;
}
public E getRoot() {
if (isEmpty()) return null;
return root.getData();
}
public BinaryNode<E> getRootNode() {
if (isEmpty()) return null;
return root;
}
public void clear() {
root = null;
size = 0;
}
private int getSize(BinaryNode<E> node) {
if (node == null) return 0;
int nLeft = (node.getLeft() == null) ? 0 : getSize(node.getLeft());
int nRight = (node.getRight() == null) ? 0 : getSize(node.getRight());
return 1 + nLeft + nRight;
}
public LinkedBinaryTree<E> removeLeft() {
LinkedBinaryTree<E> leftTree = null;
if (root.getLeft() == null) return leftTree;
leftTree = new LinkedBinaryTree<E>();
leftTree.root = root.getLeft();
leftTree.size = getSize(root.getLeft());
leftTree.root.setAsRoot();
size = size - leftTree.size;
return leftTree;
}
public LinkedBinaryTree<E> removeRight() {
LinkedBinaryTree<E> rightTree = null;
if (root.getRight() == null) return rightTree;
rightTree = new LinkedBinaryTree<E>();
rightTree.root = root.getRight();
rightTree.size = getSize(root.getRight());
rightTree.root.setAsRoot();
size = size - rightTree.size;
return rightTree;
}
protected BinaryNode<E> find(E targetElement, BinaryNode<E> root) {
if (root == null) return null;
if (root.getData().equals(targetElement)) return root;
BinaryNode<E> resNode;
resNode = find(targetElement, root.getLeft());
if (resNode == null) resNode = find(targetElement, root.getRight());
return resNode;
}
public boolean remove(E targetElement) {
if (targetElement == null) return false;
BinaryNode<E> temp = find(targetElement, root);
if (temp != null) {
temp.setData(null);
return true;
}
return false;
}
public boolean contains(E targetElement) {
return find(targetElement, root) != null;
}
// ITERATORE PREORDER
/*
* Qui si utilizza il metodo del preorder.
* Le regole per il preorder sono queste:
* - Visita prima se stesso
* - Poi visita tutto ciò che si trova sinistra
* - Infine visita tutto ciò che si trova a destra
*/
protected void preorder (BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
if (node.getData() != null) temporaryList.add(node.getData());
preorder(node.getLeft(), temporaryList);
preorder(node.getRight(), temporaryList);
}
public Iterator<E> iteratorPreOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
preorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE INORDER
/*
* Qui si utilizza il metodo del inorder.
* Le regole per l'inorder sono queste:
* - Visita prima tutto ciò che si trova a sinistra
* - Poi visita se stesso
* - Infine visita tutto ciò che si trova a destra
*/
protected void inorder(BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
inorder(node.getLeft(), temporaryList);
if (node.getData() != null) temporaryList.add(node.getData());
inorder(node.getRight(), temporaryList);
}
public Iterator<E> iteratorInOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
inorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE POSTORDER
/*
* Qui si utilizza il metodo postorder.
* Le regole per il postorder sono queste:
* - Visita prima di tutto ciò che si trova a sinistra
* - Poi visita tutto ciò che si trova a destra
* - Infine visita il sestesso
*/
protected void postorder(BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
postorder(node.getLeft(), temporaryList);
postorder(node.getRight(), temporaryList);
if (node.getData() != null) temporaryList.add(node.getData());
}
public Iterator<E> iteratorPostOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
postorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE LEVEL ORDER
/*
* Qui si usa il metodo levelorder.
* Si analizza tutto il livello dell'albero.
* Per chiarire di seguito un esempio:
*
* A
* / \
* B C
* / \ \
* D E F
*
* La lettura avviene quindi in questo modo:
* A - B - C - D - E - F
*
* Si adopera una coda (Queue) di tipo FI-FO (First In - First Out)
*/
protected void levelorder(BinaryNode<E> node, List<E> temporaryList) {
Queue<BinaryNode<E>> queueOfNodes = new LinkedList<BinaryNode<E>>();
BinaryNode<E> current;
queueOfNodes.add(node);
while(!queueOfNodes.isEmpty()) {
current = queueOfNodes.remove();
if (current.getData() != null) temporaryList.add(current.getData());
if (current.getLeft() != null) queueOfNodes.add(current.getLeft());
if (current.getRight() != null) queueOfNodes.add(current.getRight());
}
}
public Iterator<E> iteratorLevelOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
levelorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE
public Iterator<E> iterator() {
return iteratorPreOrder();
}
// ITERATORE PREORDER ITERATIVO (NON RICORSIVO)
/*
* In questo caso stiamo usando un tipo stack.
* Dobbiamo di fatto simulare uno stack se vogliamo
* iterativamente fare questa cosa.
*
* Perchè se prima dobbiamo visitare il nodo centrale,
* poi il nodo a sinistra e poi il nodo a destra inseriamo
* prima quello di destra e poi quello di sinistra?
*
* Lo stack di fatto è una coda LIFO, ovvero last in - first out
* e quindi l'ultimo che entra è il primo che esce.
*
* dal momento che vale questa cosa, se facciamo entrare prima quello
* di destra e poi quello di sinistra, il primo nodo che verrà
* prelevato è ovviamente quello a sinistra.
*/
protected void itpreorder (BinaryNode<E> node, List<E> temporaryList) {
Stack<BinaryNode<E>> queueOfNodes = new Stack<BinaryNode<E>>();
BinaryNode<E> current;
queueOfNodes.add(node);
while (!queueOfNodes.isEmpty()) {
current = queueOfNodes.pop();
if (current.getData() != null) temporaryList.add(current.getData());
// Come già spiegato pushamo prima il nodo di destra
if (current.getRight() != null) queueOfNodes.push(current.getRight());
// Infine aggiungiamo il nodo di sinistra
if (current.getLeft() != null) queueOfNodes.push(current.getLeft());
}
}
public Iterator<E> ititeratorInOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
itpreorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATOR INORDER ITERATIVO (NON RICORSIVO)
/*
* Questo metodo riguarda lo stesso di quello superiore.
* Il metodo inorder richiede che si visiti prima sinistra,
* poi il nodo stesso, infine il nodo di destra.
*
* Possiamo quindi sempre adoperare uno Stack per siumlare la
* ricorsione.
*
* Come detto prima, se il primo nodo ad essere prelevato è
* l'ultimo che si inserisce (coda LIFO, Stack) allora per simulare
* sinistra -> centro -> destra, il primo nodo da inserire è quello di
* destra
*/
private void itinorder(BinaryNode<E> node, List<E> temporaryList) {
Stack<BinaryNode<E>> queueOfNodes = new Stack<BinaryNode<E>>();
Stack<Boolean> flags = new Stack<Boolean>();
BinaryNode<E> current;
Boolean flag;
queueOfNodes.add(node);
flags.push(false);
while (!queueOfNodes.isEmpty()) {
current = queueOfNodes.pop();
flag = flags.pop();
if (flag) {
// il nodo è da visitare
if (current.getData() != null) temporaryList.add(current.getData());
} else {
// il nodo non è da visitare
// prima si aggiunge il nodo di destra
if (current.getRight() != null) {
queueOfNodes.add(current.getRight());
flags.add(false);
}
}
}
}
}
@@ -0,0 +1,317 @@
package binary_tree;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Stack;
public class LinkedBinaryTree<E> implements BinaryTree<E>{
// VARIABILI D'INSTANZA
private BinaryNode<E> root;
private int size;
// Metodi costruttori
public LinkedBinaryTree() {
root = null;
size = 0;
}
public LinkedBinaryTree(E data) {
root = new BinaryNode<E>(data);
size = 1;
}
public LinkedBinaryTree(LinkedBinaryTree<E> left, E data, LinkedBinaryTree<E> right) {
root = new BinaryNode<E>(left.root, data, right.root);
size = 1 + left.size + right.size;
}
// METODI
public int size() {
return size;
}
@Override
public boolean isEmpty() {
return root == null;
}
public E getRoot() {
if (isEmpty()) return null;
return root.getData();
}
public BinaryNode<E> getRootNode() {
if (isEmpty()) return null;
return root;
}
public void clear() {
root = null;
size = 0;
}
private int getSize(BinaryNode<E> node) {
if (node == null) return 0;
int nLeft = (node.getLeft() == null) ? 0 : getSize(node.getLeft());
int nRight = (node.getRight() == null) ? 0 : getSize(node.getRight());
return 1 + nLeft + nRight;
}
public LinkedBinaryTree<E> removeLeft() {
LinkedBinaryTree<E> leftTree = null;
if (root.getLeft() == null) return leftTree;
leftTree = new LinkedBinaryTree<E>();
leftTree.root = root.getLeft();
leftTree.size = getSize(root.getLeft());
leftTree.root.setAsRoot();
size = size - leftTree.size;
return leftTree;
}
public LinkedBinaryTree<E> removeRight() {
LinkedBinaryTree<E> rightTree = null;
if (root.getRight() == null) return rightTree;
rightTree = new LinkedBinaryTree<E>();
rightTree.root = root.getRight();
rightTree.size = getSize(root.getRight());
rightTree.root.setAsRoot();
size = size - rightTree.size;
return rightTree;
}
protected BinaryNode<E> find(E targetElement, BinaryNode<E> root) {
if (root == null) return null;
if (root.getData().equals(targetElement)) return root;
BinaryNode<E> resNode;
resNode = find(targetElement, root.getLeft());
if (resNode == null) resNode = find(targetElement, root.getRight());
return resNode;
}
public boolean remove(E targetElement) {
if (targetElement == null) return false;
BinaryNode<E> temp = find(targetElement, root);
if (temp != null) {
temp.setData(null);
return true;
}
return false;
}
public boolean contains(E targetElement) {
return find(targetElement, root) != null;
}
// ITERATORE PREORDER
/*
* Qui si utilizza il metodo del preorder.
* Le regole per il preorder sono queste:
* - Visita prima se stesso
* - Poi visita tutto ciò che si trova sinistra
* - Infine visita tutto ciò che si trova a destra
*/
protected void preorder (BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
if (node.getData() != null) temporaryList.add(node.getData());
preorder(node.getLeft(), temporaryList);
preorder(node.getRight(), temporaryList);
}
public Iterator<E> iteratorPreOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
preorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE INORDER
/*
* Qui si utilizza il metodo del inorder.
* Le regole per l'inorder sono queste:
* - Visita prima tutto ciò che si trova a sinistra
* - Poi visita se stesso
* - Infine visita tutto ciò che si trova a destra
*/
protected void inorder(BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
inorder(node.getLeft(), temporaryList);
if (node.getData() != null) temporaryList.add(node.getData());
inorder(node.getRight(), temporaryList);
}
public Iterator<E> iteratorInOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
inorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE POSTORDER
/*
* Qui si utilizza il metodo postorder.
* Le regole per il postorder sono queste:
* - Visita prima di tutto ciò che si trova a sinistra
* - Poi visita tutto ciò che si trova a destra
* - Infine visita il sestesso
*/
protected void postorder(BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
postorder(node.getLeft(), temporaryList);
postorder(node.getRight(), temporaryList);
if (node.getData() != null) temporaryList.add(node.getData());
}
public Iterator<E> iteratorPostOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
postorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE LEVEL ORDER
/*
* Qui si usa il metodo levelorder.
* Si analizza tutto il livello dell'albero.
* Per chiarire di seguito un esempio:
*
* A
* / \
* B C
* / \ \
* D E F
*
* La lettura avviene quindi in questo modo:
* A - B - C - D - E - F
*
* Si adopera una coda (Queue) di tipo FI-FO (First In - First Out)
*/
protected void levelorder(BinaryNode<E> node, List<E> temporaryList) {
Queue<BinaryNode<E>> queueOfNodes = new LinkedList<BinaryNode<E>>();
BinaryNode<E> current;
queueOfNodes.add(node);
while(!queueOfNodes.isEmpty()) {
current = queueOfNodes.remove();
if (current.getData() != null) temporaryList.add(current.getData());
if (current.getLeft() != null) queueOfNodes.add(current.getLeft());
if (current.getRight() != null) queueOfNodes.add(current.getRight());
}
}
public Iterator<E> iteratorLevelOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
levelorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE
public Iterator<E> iterator() {
return iteratorPreOrder();
}
// ITERATORE PREORDER ITERATIVO (NON RICORSIVO)
/*
* In questo caso stiamo usando un tipo stack.
* Dobbiamo di fatto simulare uno stack se vogliamo
* iterativamente fare questa cosa.
*
* Perchè se prima dobbiamo visitare il nodo centrale,
* poi il nodo a sinistra e poi il nodo a destra inseriamo
* prima quello di destra e poi quello di sinistra?
*
* Lo stack di fatto è una coda LIFO, ovvero last in - first out
* e quindi l'ultimo che entra è il primo che esce.
*
* dal momento che vale questa cosa, se facciamo entrare prima quello
* di destra e poi quello di sinistra, il primo nodo che verrà
* prelevato è ovviamente quello a sinistra.
*/
protected void itpreorder (BinaryNode<E> node, List<E> temporaryList) {
Stack<BinaryNode<E>> queueOfNodes = new Stack<BinaryNode<E>>();
BinaryNode<E> current;
queueOfNodes.add(node);
while (!queueOfNodes.isEmpty()) {
current = queueOfNodes.pop();
if (current.getData() != null) temporaryList.add(current.getData());
// Come già spiegato pushamo prima il nodo di destra
if (current.getRight() != null) queueOfNodes.push(current.getRight());
// Infine aggiungiamo il nodo di sinistra
if (current.getLeft() != null) queueOfNodes.push(current.getLeft());
}
}
public Iterator<E> ititeratorInOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
itpreorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATOR INORDER ITERATIVO (NON RICORSIVO)
/*
* Questo metodo riguarda lo stesso di quello superiore.
* Il metodo inorder richiede che si visiti prima sinistra,
* poi il nodo stesso, infine il nodo di destra.
*
* Possiamo quindi sempre adoperare uno Stack per siumlare la
* ricorsione.
*
* Come detto prima, se il primo nodo ad essere prelevato è
* l'ultimo che si inserisce (coda LIFO, Stack) allora per simulare
* sinistra -> centro -> destra, il primo nodo da inserire è quello di
* destra
*/
private void itinorder(BinaryNode<E> node, List<E> temporaryList) {
Stack<BinaryNode<E>> queueOfNodes = new Stack<BinaryNode<E>>();
Stack<Boolean> flags = new Stack<Boolean>();
BinaryNode<E> current;
Boolean flag;
queueOfNodes.add(node);
flags.push(false);
while (!queueOfNodes.isEmpty()) {
current = queueOfNodes.pop();
flag = flags.pop();
if (flag) {
// il nodo è da visitare
} else {
// il nodo non è da visitare
}
}
}
}
@@ -0,0 +1,92 @@
package binary_tree;
public class LinkedBinaryTree<E> implements BinaryTree<E>{
// VARIABILI D'INSTANZA
private BinaryNode<E> root;
private int size;
// Metodi costruttori
public LinkedBinaryTree() {
root = null;
size = 0;
}
public LinkedBinaryTree(E data) {
root = new BinaryNode<E>(data);
size = 1;
}
public LinkedBinaryTree(LinkedBinaryTree<E> left, E data, LinkedBinaryTree<E> right) {
root = new BinaryNode<E>(left.root, data, right.root);
size = 1 + left.size + right.size;
}
// METODI
public int size() {
return size;
}
@Override
public boolean isEmpty() {
return root == null;
}
public E getRoot() {
if (isEmpty()) return null;
return root.getData();
}
public BinaryNode<E> getRootNode() {
if (isEmpty()) return null;
return root;
}
public void clear() {
root = null;
size = 0;
}
private int getSize(BinaryNode<E> node) {
if (node == null) return 0;
int nLeft = (node.getLeft() == null) ? 0 : getSize(node.getLeft());
int nRight = (node.getRight() == null) ? 0 : getSize(node.getRight());
return 1 + nLeft + nRight;
}
public LinkedBinaryTree<E> removeLeft() {
LinkedBinaryTree<E> leftTree = null;
if (root.getLeft() == null) return leftTree;
leftTree = new LinkedBinaryTree<E>();
leftTree.root = root.getLeft();
leftTree.size = getSize(root.getLeft());
leftTree.root.setAsRoot();
size = size - leftTree.size;
return leftTree;
}
public LinkedBinaryTree<E> removeRight() {
LinkedBinaryTree<E> rightTree = null;
if (root.getRight() == null) return rightTree;
rightTree = new LinkedBinaryTree<E>();
rightTree.root = root.getRight();
rightTree.size = getSize(root.getRight());
rightTree.root.setAsRoot();
size = size - rightTree.size;
return rightTree;
}
protected BinaryNode<E> find(E targetElement, BinaryNode<E> root) {
if (root == null) return null;
}
}
@@ -0,0 +1,40 @@
package binary_tree;
public class LinkedBinaryTree<E> implements BinaryTree<E>{
// VARIABILI D'INSTANZA
private BinaryNode<E> root;
private int size;
// Metodi costruttori
public LinkedBinaryTree() {
root = null;
size = 0;
}
public LinkedBinaryTree(E data) {
root = new BinaryNode<E>(data);
size = 1;
}
public LinkedBinaryTree(LinkedBinaryTree<E> left, E data, LinkedBinaryTree<E> right) {
root = new BinaryNode<E>(left.root, data, right.root);
size = 1 + left.size + right.size;
}
// METODI
public int size() {
return size;
}
@Override
public boolean isEmpty() {
return root == null;
}
public E getRoot() {
}
}
@@ -0,0 +1,16 @@
package binary_tree;
public class LinkedBinaryTree<E> implements BinaryTree<E>{
// VARIABILI D'INSTANZA
private BinaryNode<E> root;
// METODI
@Override
public boolean isEmpty() {
}
}
@@ -0,0 +1,468 @@
package binary_tree;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Stack;
public class LinkedBinaryTree<E> implements BinaryTree<E>{
// VARIABILI D'INSTANZA
private BinaryNode<E> root;
private int size;
// Metodi costruttori
public LinkedBinaryTree() {
root = null;
size = 0;
}
public LinkedBinaryTree(E data) {
root = new BinaryNode<E>(data);
size = 1;
}
public LinkedBinaryTree(LinkedBinaryTree<E> left, E data, LinkedBinaryTree<E> right) {
root = new BinaryNode<E>(left.root, data, right.root);
size = 1 + left.size + right.size;
}
// METODI
public int size() {
return size;
}
@Override
public boolean isEmpty() {
return root == null;
}
public E getRoot() {
if (isEmpty()) return null;
return root.getData();
}
public BinaryNode<E> getRootNode() {
if (isEmpty()) return null;
return root;
}
public void clear() {
root = null;
size = 0;
}
private int getSize(BinaryNode<E> node) {
if (node == null) return 0;
int nLeft = (node.getLeft() == null) ? 0 : getSize(node.getLeft());
int nRight = (node.getRight() == null) ? 0 : getSize(node.getRight());
return 1 + nLeft + nRight;
}
public LinkedBinaryTree<E> removeLeft() {
LinkedBinaryTree<E> leftTree = null;
if (root.getLeft() == null) return leftTree;
leftTree = new LinkedBinaryTree<E>();
leftTree.root = root.getLeft();
leftTree.size = getSize(root.getLeft());
leftTree.root.setAsRoot();
size = size - leftTree.size;
return leftTree;
}
public LinkedBinaryTree<E> removeRight() {
LinkedBinaryTree<E> rightTree = null;
if (root.getRight() == null) return rightTree;
rightTree = new LinkedBinaryTree<E>();
rightTree.root = root.getRight();
rightTree.size = getSize(root.getRight());
rightTree.root.setAsRoot();
size = size - rightTree.size;
return rightTree;
}
protected BinaryNode<E> find(E targetElement, BinaryNode<E> root) {
if (root == null) return null;
if (root.getData().equals(targetElement)) return root;
BinaryNode<E> resNode;
resNode = find(targetElement, root.getLeft());
if (resNode == null) resNode = find(targetElement, root.getRight());
return resNode;
}
public boolean remove(E targetElement) {
if (targetElement == null) return false;
BinaryNode<E> temp = find(targetElement, root);
if (temp != null) {
temp.setData(null);
return true;
}
return false;
}
public boolean contains(E targetElement) {
return find(targetElement, root) != null;
}
// ITERATORE PREORDER
/*
* Qui si utilizza il metodo del preorder.
* Le regole per il preorder sono queste:
* - Visita prima se stesso
* - Poi visita tutto ciò che si trova sinistra
* - Infine visita tutto ciò che si trova a destra
*/
protected void preorder (BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
if (node.getData() != null) temporaryList.add(node.getData());
preorder(node.getLeft(), temporaryList);
preorder(node.getRight(), temporaryList);
}
public Iterator<E> iteratorPreOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
preorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE INORDER
/*
* Qui si utilizza il metodo del inorder.
* Le regole per l'inorder sono queste:
* - Visita prima tutto ciò che si trova a sinistra
* - Poi visita se stesso
* - Infine visita tutto ciò che si trova a destra
*/
protected void inorder(BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
inorder(node.getLeft(), temporaryList);
if (node.getData() != null) temporaryList.add(node.getData());
inorder(node.getRight(), temporaryList);
}
public Iterator<E> iteratorInOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
inorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE POSTORDER
/*
* Qui si utilizza il metodo postorder.
* Le regole per il postorder sono queste:
* - Visita prima di tutto ciò che si trova a sinistra
* - Poi visita tutto ciò che si trova a destra
* - Infine visita il sestesso
*/
protected void postorder(BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
postorder(node.getLeft(), temporaryList);
postorder(node.getRight(), temporaryList);
if (node.getData() != null) temporaryList.add(node.getData());
}
public Iterator<E> iteratorPostOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
postorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE LEVEL ORDER
/*
* Qui si usa il metodo levelorder.
* Si analizza tutto il livello dell'albero.
* Per chiarire di seguito un esempio:
*
* A
* / \
* B C
* / \ \
* D E F
*
* La lettura avviene quindi in questo modo:
* A - B - C - D - E - F
*
* Si adopera una coda (Queue) di tipo FI-FO (First In - First Out)
*/
protected void levelorder(BinaryNode<E> node, List<E> temporaryList) {
Queue<BinaryNode<E>> queueOfNodes = new LinkedList<BinaryNode<E>>();
BinaryNode<E> current;
queueOfNodes.add(node);
while(!queueOfNodes.isEmpty()) {
current = queueOfNodes.remove();
if (current.getData() != null) temporaryList.add(current.getData());
if (current.getLeft() != null) queueOfNodes.add(current.getLeft());
if (current.getRight() != null) queueOfNodes.add(current.getRight());
}
}
public Iterator<E> iteratorLevelOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
levelorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE
public Iterator<E> iterator() {
return iteratorPreOrder();
}
// ITERATORE PREORDER ITERATIVO (NON RICORSIVO)
/*
* In questo caso stiamo usando un tipo stack.
* Dobbiamo di fatto simulare uno stack se vogliamo
* iterativamente fare questa cosa.
*
* Perchè se prima dobbiamo visitare il nodo centrale,
* poi il nodo a sinistra e poi il nodo a destra inseriamo
* prima quello di destra e poi quello di sinistra?
*
* Lo stack di fatto è una coda LIFO, ovvero last in - first out
* e quindi l'ultimo che entra è il primo che esce.
*
* dal momento che vale questa cosa, se facciamo entrare prima quello
* di destra e poi quello di sinistra, il primo nodo che verrà
* prelevato è ovviamente quello a sinistra.
*/
protected void itpreorder (BinaryNode<E> node, List<E> temporaryList) {
Stack<BinaryNode<E>> queueOfNodes = new Stack<BinaryNode<E>>();
BinaryNode<E> current;
queueOfNodes.add(node);
while (!queueOfNodes.isEmpty()) {
current = queueOfNodes.pop();
if (current.getData() != null) temporaryList.add(current.getData());
// Come già spiegato pushamo prima il nodo di destra
if (current.getRight() != null) queueOfNodes.push(current.getRight());
// Infine aggiungiamo il nodo di sinistra
if (current.getLeft() != null) queueOfNodes.push(current.getLeft());
}
}
public Iterator<E> ititeratorPreOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
itpreorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATOR INORDER ITERATIVO (NON RICORSIVO)
/*
* Questo metodo riguarda lo stesso di quello superiore.
* Il metodo inorder richiede che si visiti prima sinistra,
* poi il nodo stesso, infine il nodo di destra.
*
* Possiamo quindi sempre adoperare uno Stack per siumlare la
* ricorsione.
*
* Come detto prima, se il primo nodo ad essere prelevato è
* l'ultimo che si inserisce (coda LIFO, Stack) allora per simulare
* sinistra -> centro -> destra.
*
* Nel metodo sono state inserite delle check con uno stack di
* flag che permette di capire quando il nodo centrale è visitare
* oppure no.
*/
private void itinorder(BinaryNode<E> node, List<E> temporaryList) {
Stack<BinaryNode<E>> queueOfNodes = new Stack<BinaryNode<E>>();
Stack<Boolean> flags = new Stack<Boolean>();
BinaryNode<E> current;
Boolean flag;
queueOfNodes.add(node);
flags.push(false);
while (!queueOfNodes.isEmpty()) {
current = queueOfNodes.pop();
flag = flags.pop();
if (flag) {
// il nodo è da visitare
if (current.getData() != null) temporaryList.add(current.getData());
} else {
// il nodo non è da visitare
// prima si aggiunge il nodo di destra
if (current.getRight() != null) {
queueOfNodes.add(current.getRight());
flags.add(false);
}
queueOfNodes.push(current);
flags.push(true);
if (current.getLeft() != null) {
queueOfNodes.add(current.getLeft());
flags.push(false);
}
}
}
}
public Iterator<E> ititeratorInOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
itinorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATOR POST ORDER ITERATIVO (NON RICORSIVO)
/*
* In questo caso la logica è la seguente. si ha la
* necessità di fare il seguente ciclo: SINISTRA -> DESTRA -> NODO CORRENTE
*
* Per simulare lo stack dobbiamo quindi ripercorrerlo al contrario,
* dunque NODO CORRENTE -> DESTRA -> SINISTRA
*
* Possiamo dunque rifare lo stesso, di ciò che abbiamo fatto sopra.
*/
protected void itpostorder(BinaryNode<E> node, List<E> temporaryList) {
Stack<BinaryNode<E>> queueOfNodes = new Stack<BinaryNode<E>>();
Stack<Boolean> flags = new Stack<Boolean>();
BinaryNode<E> current;
Boolean flag;
queueOfNodes.push(node);
flags.push(false);
while (!queueOfNodes.isEmpty()) {
current = queueOfNodes.pop();
flag = flags.pop();
if (flag) {
// il nodo è da visitare
if (current.getData() != null) temporaryList.add(current.getData());
} else {
// il nodo non è ancora da visitare
// Visitiamo il nodo corrente
queueOfNodes.push(current);
flags.push(true);
// visitiamo il nodo di destra
if (current.getRight() != null) {
queueOfNodes.push(current.getRight());
flags.push(false);
}
// visitiamo il nodo di sinistra infine
if (current.getLeft() != null) {
queueOfNodes.push(current.getLeft());
flags.push(false);
}
}
}
}
public Iterator<E> ititeratorPostOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
itpostorder(root, temporaryList);
return temporaryList.iterator();
}
/*
* II parziale 2022/2023
* Realizzare un metodo costruttore della classe LinkedBinaryTree<E> che
* prende in input una lista di oggetti di tipo E e costruisce una catena
* casuale tale che l'iesimo elemento della lista è posizionato al livello iesimo
* della catena e ogni nodo ha probabilità 1/2 di avere un figlio sinistro/destro.
*/
/*
* Spiegazione intuitiva (visto che la melideo intende complicare la consegna):
* Data ad esempio una lista del genere:
* [A, B, C, D]
*
* Si ottiene quindi una catena del genere:
* A
* \
* B
* /
* C
* \
* D
*/
public LinkedBinaryTree(List<E> objectList) {
if (objectList == null) throw new NullPointerException();
Iterator<E> iterator = objectList.iterator();
if (!iterator.hasNext()) return;
E currentObject = iterator.next();
root = new BinaryNode<E>(currentObject);
BinaryNode<E> currentNode = root;
currentNode.setData(currentObject);
size = 1;
while (iterator.hasNext()) {
currentObject = iterator.next();
int wing = (int) (Math.random() * 2);
BinaryNode<E> newNode = new BinaryNode<E>(currentObject);
if (wing == 0) {
// Left
newNode.setParentAsLeftChild(currentNode);
} else {
// Right
newNode.setParentAsRightChild(currentNode);
}
currentNode = newNode;
size++;
}
}
/*
* II parziale 2022
* Si aggiunga alla classe LinkedBinaryTree<E> un metodo
* che stampa le foglie dall'albero corrente (da sinistra verso destra)
*/
public void printLeaf() {
}
public void printLeaf(BinaryNode<E> node) {
if (node == null) return;
if (node.getLeft() == null && node.getRight() == null) System.out.println(node.getData().toString());
else {
printLeaf(node.getLeft());
}
}
}
@@ -0,0 +1,35 @@
package jcf_set.example;
import java.util.HashSet;
import java.util.Random;
import java.util.Set;
public class InteriRipetuti {
public static void main(String[] Args) {
new InteriRipetuti().run();
}
public void run() {
int N = 20;
int MAX_INT = 50;
// HASHSET
Set<Integer> hashset = new HashSet<Integer>();
// Genero i numeri casuali inserendoli in nel set di hashset
Random generator = new Random();
for (int i = 0; i < N; i++) {
Integer x = generator.nextInt(MAX_INT + 1);
if (!hashset.add(x)) {
System.out.println("[NON INSERITO] Causa: Intero ripetuto: " + x);
} else System.out.println("Intero inserito: " + x);
}
// Stampa di hashset
System.out.println("Hashset");
for (Integer x : hashset) System.out.println(x + " ");
System.out.println(); System.out.println(hashset);
}
}
@@ -0,0 +1,51 @@
package binary_tree;
public class LinkedBinaryTree<E> implements BinaryTree<E>{
// VARIABILI D'INSTANZA
private BinaryNode<E> root;
private int size;
// Metodi costruttori
public LinkedBinaryTree() {
root = null;
size = 0;
}
public LinkedBinaryTree(E data) {
root = new BinaryNode<E>(data);
size = 1;
}
public LinkedBinaryTree(LinkedBinaryTree<E> left, E data, LinkedBinaryTree<E> right) {
root = new BinaryNode<E>(left.root, data, right.root);
size = 1 + left.size + right.size;
}
// METODI
public int size() {
return size;
}
@Override
public boolean isEmpty() {
return root == null;
}
public E getRoot() {
if (isEmpty()) return null;
return root.getData();
}
public BinaryNode<E> getRootNode() {
if (isEmpty()) return null;
return root;
}
public void clear() {
root = null;
size = 0;
}
}
@@ -0,0 +1,129 @@
package binary_tree;
import java.util.List;
public class LinkedBinaryTree<E> implements BinaryTree<E>{
// VARIABILI D'INSTANZA
private BinaryNode<E> root;
private int size;
// Metodi costruttori
public LinkedBinaryTree() {
root = null;
size = 0;
}
public LinkedBinaryTree(E data) {
root = new BinaryNode<E>(data);
size = 1;
}
public LinkedBinaryTree(LinkedBinaryTree<E> left, E data, LinkedBinaryTree<E> right) {
root = new BinaryNode<E>(left.root, data, right.root);
size = 1 + left.size + right.size;
}
// METODI
public int size() {
return size;
}
@Override
public boolean isEmpty() {
return root == null;
}
public E getRoot() {
if (isEmpty()) return null;
return root.getData();
}
public BinaryNode<E> getRootNode() {
if (isEmpty()) return null;
return root;
}
public void clear() {
root = null;
size = 0;
}
private int getSize(BinaryNode<E> node) {
if (node == null) return 0;
int nLeft = (node.getLeft() == null) ? 0 : getSize(node.getLeft());
int nRight = (node.getRight() == null) ? 0 : getSize(node.getRight());
return 1 + nLeft + nRight;
}
public LinkedBinaryTree<E> removeLeft() {
LinkedBinaryTree<E> leftTree = null;
if (root.getLeft() == null) return leftTree;
leftTree = new LinkedBinaryTree<E>();
leftTree.root = root.getLeft();
leftTree.size = getSize(root.getLeft());
leftTree.root.setAsRoot();
size = size - leftTree.size;
return leftTree;
}
public LinkedBinaryTree<E> removeRight() {
LinkedBinaryTree<E> rightTree = null;
if (root.getRight() == null) return rightTree;
rightTree = new LinkedBinaryTree<E>();
rightTree.root = root.getRight();
rightTree.size = getSize(root.getRight());
rightTree.root.setAsRoot();
size = size - rightTree.size;
return rightTree;
}
protected BinaryNode<E> find(E targetElement, BinaryNode<E> root) {
if (root == null) return null;
if (root.getData().equals(targetElement)) return root;
BinaryNode<E> resNode;
resNode = find(targetElement, root.getLeft());
if (resNode == null) resNode = find(targetElement, root.getRight());
return resNode;
}
public boolean remove(E targetElement) {
if (targetElement == null) return false;
BinaryNode<E> temp = find(targetElement, root);
if (temp != null) {
temp.setData(null);
return true;
}
return false;
}
public boolean contains(E targetElement) {
return find(targetElement, root) != null;
}
// ITERATORE PREORDER
/*
* Qui si utilizza il metodo del preorder.
* Le regole per il preorder sono queste:
* - Visita prima se stesso
* - Poi visita tutto ciò che si trova sinistra
* - Infine visita tutto ciò che si trova a destra
*/
protected void preorder (BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
if (node.getData != null)
}
}
@@ -0,0 +1,78 @@
package binary_tree;
public class BinaryNode<E> {
// VARIABILI
private BinaryNode<E> left, right, parent;
private E data;
// COSTRUTTORI
public BinaryNode(E data) {
this.data = data;
left = right = parent = null;
}
public BinaryNode(BinaryNode<E> left, E data, BinaryNode<E> right) {
this.data = data;
this.left = left;
this.right = right;
this.parent = null;
if (this.left != null) this.left.parent = this;
if (this.right != null) this.right.parent = this;
}
// METODI
public E getData() {
return data;
}
public BinaryNode<E> getLeft() {
return left;
}
public BinaryNode<E> getRight() {
return right;
}
public BinaryNode<E> getParent() {
return parent;
}
public boolean isRoot() {
return parent == null;
}
public boolean isLeftChild() {
return parent != null && parent.getLeft() == this;
}
public boolean isRightChild() {
return parent != null && parent.getRight() == this;
}
public void setData(E data) {
this.data = data;
}
public void setLeft(BinaryNode<E> left) {
this.left = left;
if (this.left != null) this.left.parent = this;
}
public void setRight(BinaryNode<E> right) {
this.right = right;
if (this.right != null) this.right.parent = this;
}
public BinaryNode<E> setParentAsLeftChild(BinaryNode<E> parent) {
}
}
@@ -0,0 +1,5 @@
package vettore_ordinabile;
public class VettoriIntero {
}
@@ -0,0 +1,307 @@
package binary_tree;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Stack;
public class LinkedBinaryTree<E> implements BinaryTree<E>{
// VARIABILI D'INSTANZA
private BinaryNode<E> root;
private int size;
// Metodi costruttori
public LinkedBinaryTree() {
root = null;
size = 0;
}
public LinkedBinaryTree(E data) {
root = new BinaryNode<E>(data);
size = 1;
}
public LinkedBinaryTree(LinkedBinaryTree<E> left, E data, LinkedBinaryTree<E> right) {
root = new BinaryNode<E>(left.root, data, right.root);
size = 1 + left.size + right.size;
}
// METODI
public int size() {
return size;
}
@Override
public boolean isEmpty() {
return root == null;
}
public E getRoot() {
if (isEmpty()) return null;
return root.getData();
}
public BinaryNode<E> getRootNode() {
if (isEmpty()) return null;
return root;
}
public void clear() {
root = null;
size = 0;
}
private int getSize(BinaryNode<E> node) {
if (node == null) return 0;
int nLeft = (node.getLeft() == null) ? 0 : getSize(node.getLeft());
int nRight = (node.getRight() == null) ? 0 : getSize(node.getRight());
return 1 + nLeft + nRight;
}
public LinkedBinaryTree<E> removeLeft() {
LinkedBinaryTree<E> leftTree = null;
if (root.getLeft() == null) return leftTree;
leftTree = new LinkedBinaryTree<E>();
leftTree.root = root.getLeft();
leftTree.size = getSize(root.getLeft());
leftTree.root.setAsRoot();
size = size - leftTree.size;
return leftTree;
}
public LinkedBinaryTree<E> removeRight() {
LinkedBinaryTree<E> rightTree = null;
if (root.getRight() == null) return rightTree;
rightTree = new LinkedBinaryTree<E>();
rightTree.root = root.getRight();
rightTree.size = getSize(root.getRight());
rightTree.root.setAsRoot();
size = size - rightTree.size;
return rightTree;
}
protected BinaryNode<E> find(E targetElement, BinaryNode<E> root) {
if (root == null) return null;
if (root.getData().equals(targetElement)) return root;
BinaryNode<E> resNode;
resNode = find(targetElement, root.getLeft());
if (resNode == null) resNode = find(targetElement, root.getRight());
return resNode;
}
public boolean remove(E targetElement) {
if (targetElement == null) return false;
BinaryNode<E> temp = find(targetElement, root);
if (temp != null) {
temp.setData(null);
return true;
}
return false;
}
public boolean contains(E targetElement) {
return find(targetElement, root) != null;
}
// ITERATORE PREORDER
/*
* Qui si utilizza il metodo del preorder.
* Le regole per il preorder sono queste:
* - Visita prima se stesso
* - Poi visita tutto ciò che si trova sinistra
* - Infine visita tutto ciò che si trova a destra
*/
protected void preorder (BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
if (node.getData() != null) temporaryList.add(node.getData());
preorder(node.getLeft(), temporaryList);
preorder(node.getRight(), temporaryList);
}
public Iterator<E> iteratorPreOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
preorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE INORDER
/*
* Qui si utilizza il metodo del inorder.
* Le regole per l'inorder sono queste:
* - Visita prima tutto ciò che si trova a sinistra
* - Poi visita se stesso
* - Infine visita tutto ciò che si trova a destra
*/
protected void inorder(BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
inorder(node.getLeft(), temporaryList);
if (node.getData() != null) temporaryList.add(node.getData());
inorder(node.getRight(), temporaryList);
}
public Iterator<E> iteratorInOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
inorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE POSTORDER
/*
* Qui si utilizza il metodo postorder.
* Le regole per il postorder sono queste:
* - Visita prima di tutto ciò che si trova a sinistra
* - Poi visita tutto ciò che si trova a destra
* - Infine visita il sestesso
*/
protected void postorder(BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
postorder(node.getLeft(), temporaryList);
postorder(node.getRight(), temporaryList);
if (node.getData() != null) temporaryList.add(node.getData());
}
public Iterator<E> iteratorPostOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
postorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE LEVEL ORDER
/*
* Qui si usa il metodo levelorder.
* Si analizza tutto il livello dell'albero.
* Per chiarire di seguito un esempio:
*
* A
* / \
* B C
* / \ \
* D E F
*
* La lettura avviene quindi in questo modo:
* A - B - C - D - E - F
*
* Si adopera una coda (Queue) di tipo FI-FO (First In - First Out)
*/
protected void levelorder(BinaryNode<E> node, List<E> temporaryList) {
Queue<BinaryNode<E>> queueOfNodes = new LinkedList<BinaryNode<E>>();
BinaryNode<E> current;
queueOfNodes.add(node);
while(!queueOfNodes.isEmpty()) {
current = queueOfNodes.remove();
if (current.getData() != null) temporaryList.add(current.getData());
if (current.getLeft() != null) queueOfNodes.add(current.getLeft());
if (current.getRight() != null) queueOfNodes.add(current.getRight());
}
}
public Iterator<E> iteratorLevelOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
levelorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE
public Iterator<E> iterator() {
return iteratorPreOrder();
}
// ITERATORE PREORDER ITERATIVO (NON RICORSIVO)
/*
* In questo caso stiamo usando un tipo stack.
* Dobbiamo di fatto simulare uno stack se vogliamo
* iterativamente fare questa cosa.
*
* Perchè se prima dobbiamo visitare il nodo centrale,
* poi il nodo a sinistra e poi il nodo a destra inseriamo
* prima quello di destra e poi quello di sinistra?
*
* Lo stack di fatto è una coda LIFO, ovvero last in - first out
* e quindi l'ultimo che entra è il primo che esce.
*
* dal momento che vale questa cosa, se facciamo entrare prima quello
* di destra e poi quello di sinistra, il primo nodo che verrà
* prelevato è ovviamente quello a sinistra.
*/
protected void itpreorder (BinaryNode<E> node, List<E> temporaryList) {
Stack<BinaryNode<E>> queueOfNodes = new Stack<BinaryNode<E>>();
BinaryNode<E> current;
queueOfNodes.add(node);
while (!queueOfNodes.isEmpty()) {
current = queueOfNodes.pop();
if (current.getData() != null) temporaryList.add(current.getData());
// Come già spiegato pushamo prima il nodo di destra
if (current.getRight() != null) queueOfNodes.push(current.getRight());
// Infine aggiungiamo il nodo di sinistra
if (current.getLeft() != null) queueOfNodes.push(current.getLeft());
}
}
public Iterator<E> ititeratorInOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
itpreorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATOR INORDER ITERATIVO (NON RICORSIVO)
/*
* Questo metodo riguarda lo stesso di quello superiore.
* Il metodo inorder richiede che si visiti prima sinistra,
* poi il nodo stesso, infine il nodo di destra.
*
* Possiamo quindi sempre adoperare uno Stack per siumlare la
* ricorsione.
*
* Come detto prima, se il primo nodo ad essere prelevato è
* l'ultimo che si inserisce (coda LIFO, Stack) allora per simulare
* sinistra -> centro -> destra, il primo nodo da inserire è quello di
* destra
*/
private void itinorder(BinaryNode<E> node, List<E> temporaryList) {
Stack<BinaryNode<E>> queueOfNodes = new Stack<BinaryNode<E>>();
BinaryNode<E> current;
queueOfNodes.add(node);
while (!queueOfNodes.isEmpty()) {
current = queueOfNodes.pop();
if ()
}
}
}
@@ -0,0 +1,439 @@
package binary_tree;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Stack;
public class LinkedBinaryTree<E> implements BinaryTree<E>{
// VARIABILI D'INSTANZA
private BinaryNode<E> root;
private int size;
// Metodi costruttori
public LinkedBinaryTree() {
root = null;
size = 0;
}
public LinkedBinaryTree(E data) {
root = new BinaryNode<E>(data);
size = 1;
}
public LinkedBinaryTree(LinkedBinaryTree<E> left, E data, LinkedBinaryTree<E> right) {
root = new BinaryNode<E>(left.root, data, right.root);
size = 1 + left.size + right.size;
}
// METODI
public int size() {
return size;
}
@Override
public boolean isEmpty() {
return root == null;
}
public E getRoot() {
if (isEmpty()) return null;
return root.getData();
}
public BinaryNode<E> getRootNode() {
if (isEmpty()) return null;
return root;
}
public void clear() {
root = null;
size = 0;
}
private int getSize(BinaryNode<E> node) {
if (node == null) return 0;
int nLeft = (node.getLeft() == null) ? 0 : getSize(node.getLeft());
int nRight = (node.getRight() == null) ? 0 : getSize(node.getRight());
return 1 + nLeft + nRight;
}
public LinkedBinaryTree<E> removeLeft() {
LinkedBinaryTree<E> leftTree = null;
if (root.getLeft() == null) return leftTree;
leftTree = new LinkedBinaryTree<E>();
leftTree.root = root.getLeft();
leftTree.size = getSize(root.getLeft());
leftTree.root.setAsRoot();
size = size - leftTree.size;
return leftTree;
}
public LinkedBinaryTree<E> removeRight() {
LinkedBinaryTree<E> rightTree = null;
if (root.getRight() == null) return rightTree;
rightTree = new LinkedBinaryTree<E>();
rightTree.root = root.getRight();
rightTree.size = getSize(root.getRight());
rightTree.root.setAsRoot();
size = size - rightTree.size;
return rightTree;
}
protected BinaryNode<E> find(E targetElement, BinaryNode<E> root) {
if (root == null) return null;
if (root.getData().equals(targetElement)) return root;
BinaryNode<E> resNode;
resNode = find(targetElement, root.getLeft());
if (resNode == null) resNode = find(targetElement, root.getRight());
return resNode;
}
public boolean remove(E targetElement) {
if (targetElement == null) return false;
BinaryNode<E> temp = find(targetElement, root);
if (temp != null) {
temp.setData(null);
return true;
}
return false;
}
public boolean contains(E targetElement) {
return find(targetElement, root) != null;
}
// ITERATORE PREORDER
/*
* Qui si utilizza il metodo del preorder.
* Le regole per il preorder sono queste:
* - Visita prima se stesso
* - Poi visita tutto ciò che si trova sinistra
* - Infine visita tutto ciò che si trova a destra
*/
protected void preorder (BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
if (node.getData() != null) temporaryList.add(node.getData());
preorder(node.getLeft(), temporaryList);
preorder(node.getRight(), temporaryList);
}
public Iterator<E> iteratorPreOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
preorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE INORDER
/*
* Qui si utilizza il metodo del inorder.
* Le regole per l'inorder sono queste:
* - Visita prima tutto ciò che si trova a sinistra
* - Poi visita se stesso
* - Infine visita tutto ciò che si trova a destra
*/
protected void inorder(BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
inorder(node.getLeft(), temporaryList);
if (node.getData() != null) temporaryList.add(node.getData());
inorder(node.getRight(), temporaryList);
}
public Iterator<E> iteratorInOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
inorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE POSTORDER
/*
* Qui si utilizza il metodo postorder.
* Le regole per il postorder sono queste:
* - Visita prima di tutto ciò che si trova a sinistra
* - Poi visita tutto ciò che si trova a destra
* - Infine visita il sestesso
*/
protected void postorder(BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
postorder(node.getLeft(), temporaryList);
postorder(node.getRight(), temporaryList);
if (node.getData() != null) temporaryList.add(node.getData());
}
public Iterator<E> iteratorPostOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
postorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE LEVEL ORDER
/*
* Qui si usa il metodo levelorder.
* Si analizza tutto il livello dell'albero.
* Per chiarire di seguito un esempio:
*
* A
* / \
* B C
* / \ \
* D E F
*
* La lettura avviene quindi in questo modo:
* A - B - C - D - E - F
*
* Si adopera una coda (Queue) di tipo FI-FO (First In - First Out)
*/
protected void levelorder(BinaryNode<E> node, List<E> temporaryList) {
Queue<BinaryNode<E>> queueOfNodes = new LinkedList<BinaryNode<E>>();
BinaryNode<E> current;
queueOfNodes.add(node);
while(!queueOfNodes.isEmpty()) {
current = queueOfNodes.remove();
if (current.getData() != null) temporaryList.add(current.getData());
if (current.getLeft() != null) queueOfNodes.add(current.getLeft());
if (current.getRight() != null) queueOfNodes.add(current.getRight());
}
}
public Iterator<E> iteratorLevelOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
levelorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE
public Iterator<E> iterator() {
return iteratorPreOrder();
}
// ITERATORE PREORDER ITERATIVO (NON RICORSIVO)
/*
* In questo caso stiamo usando un tipo stack.
* Dobbiamo di fatto simulare uno stack se vogliamo
* iterativamente fare questa cosa.
*
* Perchè se prima dobbiamo visitare il nodo centrale,
* poi il nodo a sinistra e poi il nodo a destra inseriamo
* prima quello di destra e poi quello di sinistra?
*
* Lo stack di fatto è una coda LIFO, ovvero last in - first out
* e quindi l'ultimo che entra è il primo che esce.
*
* dal momento che vale questa cosa, se facciamo entrare prima quello
* di destra e poi quello di sinistra, il primo nodo che verrà
* prelevato è ovviamente quello a sinistra.
*/
protected void itpreorder (BinaryNode<E> node, List<E> temporaryList) {
Stack<BinaryNode<E>> queueOfNodes = new Stack<BinaryNode<E>>();
BinaryNode<E> current;
queueOfNodes.add(node);
while (!queueOfNodes.isEmpty()) {
current = queueOfNodes.pop();
if (current.getData() != null) temporaryList.add(current.getData());
// Come già spiegato pushamo prima il nodo di destra
if (current.getRight() != null) queueOfNodes.push(current.getRight());
// Infine aggiungiamo il nodo di sinistra
if (current.getLeft() != null) queueOfNodes.push(current.getLeft());
}
}
public Iterator<E> ititeratorPreOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
itpreorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATOR INORDER ITERATIVO (NON RICORSIVO)
/*
* Questo metodo riguarda lo stesso di quello superiore.
* Il metodo inorder richiede che si visiti prima sinistra,
* poi il nodo stesso, infine il nodo di destra.
*
* Possiamo quindi sempre adoperare uno Stack per siumlare la
* ricorsione.
*
* Come detto prima, se il primo nodo ad essere prelevato è
* l'ultimo che si inserisce (coda LIFO, Stack) allora per simulare
* sinistra -> centro -> destra.
*
* Nel metodo sono state inserite delle check con uno stack di
* flag che permette di capire quando il nodo centrale è visitare
* oppure no.
*/
private void itinorder(BinaryNode<E> node, List<E> temporaryList) {
Stack<BinaryNode<E>> queueOfNodes = new Stack<BinaryNode<E>>();
Stack<Boolean> flags = new Stack<Boolean>();
BinaryNode<E> current;
Boolean flag;
queueOfNodes.add(node);
flags.push(false);
while (!queueOfNodes.isEmpty()) {
current = queueOfNodes.pop();
flag = flags.pop();
if (flag) {
// il nodo è da visitare
if (current.getData() != null) temporaryList.add(current.getData());
} else {
// il nodo non è da visitare
// prima si aggiunge il nodo di destra
if (current.getRight() != null) {
queueOfNodes.add(current.getRight());
flags.add(false);
}
queueOfNodes.push(current);
flags.push(true);
if (current.getLeft() != null) {
queueOfNodes.add(current.getLeft());
flags.push(false);
}
}
}
}
public Iterator<E> ititeratorInOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
itinorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATOR POST ORDER ITERATIVO (NON RICORSIVO)
/*
* In questo caso la logica è la seguente. si ha la
* necessità di fare il seguente ciclo: SINISTRA -> DESTRA -> NODO CORRENTE
*
* Per simulare lo stack dobbiamo quindi ripercorrerlo al contrario,
* dunque NODO CORRENTE -> DESTRA -> SINISTRA
*
* Possiamo dunque rifare lo stesso, di ciò che abbiamo fatto sopra.
*/
protected void itpostorder(BinaryNode<E> node, List<E> temporaryList) {
Stack<BinaryNode<E>> queueOfNodes = new Stack<BinaryNode<E>>();
Stack<Boolean> flags = new Stack<Boolean>();
BinaryNode<E> current;
Boolean flag;
queueOfNodes.push(node);
flags.push(false);
while (!queueOfNodes.isEmpty()) {
current = queueOfNodes.pop();
flag = flags.pop();
if (flag) {
// il nodo è da visitare
if (current.getData() != null) temporaryList.add(current.getData());
} else {
// il nodo non è ancora da visitare
// Visitiamo il nodo corrente
queueOfNodes.push(current);
flags.push(true);
// visitiamo il nodo di destra
if (current.getRight() != null) {
queueOfNodes.push(current.getRight());
flags.push(false);
}
// visitiamo il nodo di sinistra infine
if (current.getLeft() != null) {
queueOfNodes.push(current.getLeft());
flags.push(false);
}
}
}
}
public Iterator<E> ititeratorPostOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
itpostorder(root, temporaryList);
return temporaryList.iterator();
}
/*
* II parziale 2022/2023
* Realizzare un metodo costruttore della classe LinkedBinaryTree<E> che
* prende in input una lista di oggetti di tipo E e costruisce una catena
* casuale tale che l'iesimo elemento della lista è posizionato al livello iesimo
* della catena e ogni nodo ha probabilità 1/2 di avere un figlio sinistro/destro.
*/
/*
* Spiegazione intuitiva (visto che la melideo intende complicare la consegna):
* Data ad esempio una lista del genere:
* [A, B, C, D]
*
* Si ottiene quindi una catena del genere:
* A
* \
* B
* /
* C
* \
* D
*/
public LinkedBinaryTree(List<E> objectList) {
if (objectList == null) throw new NullPointerException();
Iterator<E> iterator = objectList.iterator();
BinaryNode<E> currentNode = root;
while (iterator.hasNext()) {
E currentObject = iterator.next();
int wing = (int) (Math.random() * 2);
currentNode.setData(currentObject);
if (wing == 0) {
} else {
}
}
}
}
@@ -0,0 +1,22 @@
package stack;
public interface MyStack<T> {
/**
* Aggiunge un elemento al top dello stack.
* @param Elemento che deve essere aggiunto nello stack.
*/
void push(T item);
/**
* Rimuove l'elemento al top dello stack.
* @return Elemento appena rimosso dallo stack;
*/
T pop();
T peek();
int size();
boolean isEmpty();
}
@@ -0,0 +1,26 @@
package stack;
public class StackExample {
public static void main(String[] Args) {
MyStack<Character> stack = new ArrayListStack<Character>();
Character a = 'a';
Character b = 'b';
Character c = 'c';
Character d = 'd';
stack.push(a);
stack.push(b);
stack.push(c);
stack.push(d);
// Svuotiamo lo stack
for (int i = stack.size(); i < stack.size(); i++) {
Character current = stack.pop();
System.out.println(current);
}
}
}
@@ -0,0 +1,492 @@
package binary_tree;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Stack;
public class LinkedBinaryTree<E> implements BinaryTree<E>{
// VARIABILI D'INSTANZA
private BinaryNode<E> root;
private int size;
// Metodi costruttori
public LinkedBinaryTree() {
root = null;
size = 0;
}
public LinkedBinaryTree(E data) {
root = new BinaryNode<E>(data);
size = 1;
}
public LinkedBinaryTree(LinkedBinaryTree<E> left, E data, LinkedBinaryTree<E> right) {
root = new BinaryNode<E>(left.root, data, right.root);
size = 1 + left.size + right.size;
}
// METODI
public int size() {
return size;
}
@Override
public boolean isEmpty() {
return root == null;
}
public E getRoot() {
if (isEmpty()) return null;
return root.getData();
}
public BinaryNode<E> getRootNode() {
if (isEmpty()) return null;
return root;
}
public void clear() {
root = null;
size = 0;
}
private int getSize(BinaryNode<E> node) {
if (node == null) return 0;
int nLeft = (node.getLeft() == null) ? 0 : getSize(node.getLeft());
int nRight = (node.getRight() == null) ? 0 : getSize(node.getRight());
return 1 + nLeft + nRight;
}
public LinkedBinaryTree<E> removeLeft() {
LinkedBinaryTree<E> leftTree = null;
if (root.getLeft() == null) return leftTree;
leftTree = new LinkedBinaryTree<E>();
leftTree.root = root.getLeft();
leftTree.size = getSize(root.getLeft());
leftTree.root.setAsRoot();
size = size - leftTree.size;
return leftTree;
}
public LinkedBinaryTree<E> removeRight() {
LinkedBinaryTree<E> rightTree = null;
if (root.getRight() == null) return rightTree;
rightTree = new LinkedBinaryTree<E>();
rightTree.root = root.getRight();
rightTree.size = getSize(root.getRight());
rightTree.root.setAsRoot();
size = size - rightTree.size;
return rightTree;
}
protected BinaryNode<E> find(E targetElement, BinaryNode<E> root) {
if (root == null) return null;
if (root.getData().equals(targetElement)) return root;
BinaryNode<E> resNode;
resNode = find(targetElement, root.getLeft());
if (resNode == null) resNode = find(targetElement, root.getRight());
return resNode;
}
public boolean remove(E targetElement) {
if (targetElement == null) return false;
BinaryNode<E> temp = find(targetElement, root);
if (temp != null) {
temp.setData(null);
return true;
}
return false;
}
public boolean contains(E targetElement) {
return find(targetElement, root) != null;
}
// ITERATORE PREORDER
/*
* Qui si utilizza il metodo del preorder.
* Le regole per il preorder sono queste:
* - Visita prima se stesso
* - Poi visita tutto ciò che si trova sinistra
* - Infine visita tutto ciò che si trova a destra
*/
protected void preorder (BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
if (node.getData() != null) temporaryList.add(node.getData());
preorder(node.getLeft(), temporaryList);
preorder(node.getRight(), temporaryList);
}
public Iterator<E> iteratorPreOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
preorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE INORDER
/*
* Qui si utilizza il metodo del inorder.
* Le regole per l'inorder sono queste:
* - Visita prima tutto ciò che si trova a sinistra
* - Poi visita se stesso
* - Infine visita tutto ciò che si trova a destra
*/
protected void inorder(BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
inorder(node.getLeft(), temporaryList);
if (node.getData() != null) temporaryList.add(node.getData());
inorder(node.getRight(), temporaryList);
}
public Iterator<E> iteratorInOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
inorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE POSTORDER
/*
* Qui si utilizza il metodo postorder.
* Le regole per il postorder sono queste:
* - Visita prima di tutto ciò che si trova a sinistra
* - Poi visita tutto ciò che si trova a destra
* - Infine visita il sestesso
*/
protected void postorder(BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
postorder(node.getLeft(), temporaryList);
postorder(node.getRight(), temporaryList);
if (node.getData() != null) temporaryList.add(node.getData());
}
public Iterator<E> iteratorPostOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
postorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE LEVEL ORDER
/*
* Qui si usa il metodo levelorder.
* Si analizza tutto il livello dell'albero.
* Per chiarire di seguito un esempio:
*
* A
* / \
* B C
* / \ \
* D E F
*
* La lettura avviene quindi in questo modo:
* A - B - C - D - E - F
*
* Si adopera una coda (Queue) di tipo FI-FO (First In - First Out)
*/
protected void levelorder(BinaryNode<E> node, List<E> temporaryList) {
Queue<BinaryNode<E>> queueOfNodes = new LinkedList<BinaryNode<E>>();
BinaryNode<E> current;
queueOfNodes.add(node);
while(!queueOfNodes.isEmpty()) {
current = queueOfNodes.remove();
if (current.getData() != null) temporaryList.add(current.getData());
if (current.getLeft() != null) queueOfNodes.add(current.getLeft());
if (current.getRight() != null) queueOfNodes.add(current.getRight());
}
}
public Iterator<E> iteratorLevelOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
levelorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE
public Iterator<E> iterator() {
return iteratorPreOrder();
}
// ITERATORE PREORDER ITERATIVO (NON RICORSIVO)
/*
* In questo caso stiamo usando un tipo stack.
* Dobbiamo di fatto simulare uno stack se vogliamo
* iterativamente fare questa cosa.
*
* Perchè se prima dobbiamo visitare il nodo centrale,
* poi il nodo a sinistra e poi il nodo a destra inseriamo
* prima quello di destra e poi quello di sinistra?
*
* Lo stack di fatto è una coda LIFO, ovvero last in - first out
* e quindi l'ultimo che entra è il primo che esce.
*
* dal momento che vale questa cosa, se facciamo entrare prima quello
* di destra e poi quello di sinistra, il primo nodo che verrà
* prelevato è ovviamente quello a sinistra.
*/
protected void itpreorder (BinaryNode<E> node, List<E> temporaryList) {
Stack<BinaryNode<E>> queueOfNodes = new Stack<BinaryNode<E>>();
BinaryNode<E> current;
queueOfNodes.add(node);
while (!queueOfNodes.isEmpty()) {
current = queueOfNodes.pop();
if (current.getData() != null) temporaryList.add(current.getData());
// Come già spiegato pushamo prima il nodo di destra
if (current.getRight() != null) queueOfNodes.push(current.getRight());
// Infine aggiungiamo il nodo di sinistra
if (current.getLeft() != null) queueOfNodes.push(current.getLeft());
}
}
public Iterator<E> ititeratorPreOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
itpreorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATOR INORDER ITERATIVO (NON RICORSIVO)
/*
* Questo metodo riguarda lo stesso di quello superiore.
* Il metodo inorder richiede che si visiti prima sinistra,
* poi il nodo stesso, infine il nodo di destra.
*
* Possiamo quindi sempre adoperare uno Stack per siumlare la
* ricorsione.
*
* Come detto prima, se il primo nodo ad essere prelevato è
* l'ultimo che si inserisce (coda LIFO, Stack) allora per simulare
* sinistra -> centro -> destra.
*
* Nel metodo sono state inserite delle check con uno stack di
* flag che permette di capire quando il nodo centrale è visitare
* oppure no.
*/
private void itinorder(BinaryNode<E> node, List<E> temporaryList) {
Stack<BinaryNode<E>> queueOfNodes = new Stack<BinaryNode<E>>();
Stack<Boolean> flags = new Stack<Boolean>();
BinaryNode<E> current;
Boolean flag;
queueOfNodes.add(node);
flags.push(false);
while (!queueOfNodes.isEmpty()) {
current = queueOfNodes.pop();
flag = flags.pop();
if (flag) {
// il nodo è da visitare
if (current.getData() != null) temporaryList.add(current.getData());
} else {
// il nodo non è da visitare
// prima si aggiunge il nodo di destra
if (current.getRight() != null) {
queueOfNodes.add(current.getRight());
flags.add(false);
}
queueOfNodes.push(current);
flags.push(true);
if (current.getLeft() != null) {
queueOfNodes.add(current.getLeft());
flags.push(false);
}
}
}
}
public Iterator<E> ititeratorInOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
itinorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATOR POST ORDER ITERATIVO (NON RICORSIVO)
/*
* In questo caso la logica è la seguente. si ha la
* necessità di fare il seguente ciclo: SINISTRA -> DESTRA -> NODO CORRENTE
*
* Per simulare lo stack dobbiamo quindi ripercorrerlo al contrario,
* dunque NODO CORRENTE -> DESTRA -> SINISTRA
*
* Possiamo dunque rifare lo stesso, di ciò che abbiamo fatto sopra.
*/
protected void itpostorder(BinaryNode<E> node, List<E> temporaryList) {
Stack<BinaryNode<E>> queueOfNodes = new Stack<BinaryNode<E>>();
Stack<Boolean> flags = new Stack<Boolean>();
BinaryNode<E> current;
Boolean flag;
queueOfNodes.push(node);
flags.push(false);
while (!queueOfNodes.isEmpty()) {
current = queueOfNodes.pop();
flag = flags.pop();
if (flag) {
// il nodo è da visitare
if (current.getData() != null) temporaryList.add(current.getData());
} else {
// il nodo non è ancora da visitare
// Visitiamo il nodo corrente
queueOfNodes.push(current);
flags.push(true);
// visitiamo il nodo di destra
if (current.getRight() != null) {
queueOfNodes.push(current.getRight());
flags.push(false);
}
// visitiamo il nodo di sinistra infine
if (current.getLeft() != null) {
queueOfNodes.push(current.getLeft());
flags.push(false);
}
}
}
}
public Iterator<E> ititeratorPostOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
itpostorder(root, temporaryList);
return temporaryList.iterator();
}
/*
* II parziale 2022/2023
* Realizzare un metodo costruttore della classe LinkedBinaryTree<E> che
* prende in input una lista di oggetti di tipo E e costruisce una catena
* casuale tale che l'iesimo elemento della lista è posizionato al livello iesimo
* della catena e ogni nodo ha probabilità 1/2 di avere un figlio sinistro/destro.
*/
/*
* Spiegazione intuitiva (visto che la melideo intende complicare la consegna):
* Data ad esempio una lista del genere:
* [A, B, C, D]
*
* Si ottiene quindi una catena del genere:
* A
* \
* B
* /
* C
* \
* D
*/
public LinkedBinaryTree(List<E> objectList) {
if (objectList == null) throw new NullPointerException();
Iterator<E> iterator = objectList.iterator();
if (!iterator.hasNext()) return;
E currentObject = iterator.next();
root = new BinaryNode<E>(currentObject);
BinaryNode<E> currentNode = root;
currentNode.setData(currentObject);
size = 1;
while (iterator.hasNext()) {
currentObject = iterator.next();
int wing = (int) (Math.random() * 2);
BinaryNode<E> newNode = new BinaryNode<E>(currentObject);
if (wing == 0) {
// Left
newNode.setParentAsLeftChild(currentNode);
} else {
// Right
newNode.setParentAsRightChild(currentNode);
}
currentNode = newNode;
size++;
}
}
/*
* II parziale 2022
* Si aggiunga alla classe LinkedBinaryTree<E> un metodo
* che stampa le foglie dall'albero corrente (da sinistra verso destra)
*/
public void printLeaf() {
printLeaf(root);
}
public void printLeaf(BinaryNode<E> node) {
if (node == null) return;
if (node.getLeft() == null && node.getRight() == null) System.out.println(node.getData().toString());
else {
printLeaf(node.getLeft());
printLeaf(node.getRight());
}
}
/*
* Si aggiunga alla classe LinkedBinaryTree<E> un metodo che conta il numero
* di foglie dell'albero corrente
*/
public int numberLeaf() {
Integer number = 0;
numberLeaf(root, number);
return number;
}
public int numberLeaf(BinaryNode<E> node) {
if (node == null) return 0;
int nLeft = (node.getLeft() == null) ? 0 : numberLeaf(node.getLeft());
int nRight = (node.getRight() == null) ? 0 : numberLeaf(node.getRight());
int i;
if ()
return n
}
}
@@ -0,0 +1,30 @@
package parziale.p251110;
public class Paziente {
private String id;
private int annoNascita;
public Paziente(
String id,
int annoNascita) {
this.id = id;
this.annoNascita = annoNascita;
}
public String getId() {
return id;
}
public int getAnnoNascita() {
return annoNascita;
}
@Override
public boolean equals(Object o) {
if (o == null) return false;
if (this == o) return true;
if (!(o instanceof Paziente))
}
}
@@ -0,0 +1,91 @@
package binary_tree;
public class BinaryNode<E> {
// VARIABILI
private BinaryNode<E> left, right, parent;
private E data;
// COSTRUTTORI
public BinaryNode(E data) {
this.data = data;
left = right = parent = null;
}
public BinaryNode(BinaryNode<E> left, E data, BinaryNode<E> right) {
this.data = data;
this.left = left;
this.right = right;
this.parent = null;
if (this.left != null) this.left.parent = this;
if (this.right != null) this.right.parent = this;
}
// METODI
public E getData() {
return data;
}
public BinaryNode<E> getLeft() {
return left;
}
public BinaryNode<E> getRight() {
return right;
}
public BinaryNode<E> getParent() {
return parent;
}
public boolean isRoot() {
return parent == null;
}
public boolean isLeftChild() {
return parent != null && parent.getLeft() == this;
}
public boolean isRightChild() {
return parent != null && parent.getRight() == this;
}
public void setData(E data) {
this.data = data;
}
public void setLeft(BinaryNode<E> left) {
this.left = left;
if (this.left != null) this.left.parent = this;
}
public void setRight(BinaryNode<E> right) {
this.right = right;
if (this.right != null) this.right.parent = this;
}
public BinaryNode<E> setParentAsLeftChild(BinaryNode<E> parent) {
if (parent == null) return null;
this.parent = parent;
BinaryNode<E> oldLeft = this.parent.left;
this.parent.left = this;
return oldLeft;
}
public BinaryNode<E> setParentAsRightChild(BinaryNode<E> parent) {
if (parent == null) return null;
this.parent = parent;
BinaryNode<E> oldRight = this.parent.right;
}
}
@@ -0,0 +1,30 @@
package comparatori.videogioco;
public class Videogioco implements Comparable<Videogioco>{
// Campi di istanza
private String titolo;
private String piattaforma;
private Integer annoUscita;
private Double prezzo;
private Integer voto;
// Costruttore
private Videogioco() {}
public Videogioco(
String titolo,
String piattaforma,
Integer annoUscita,
Double prezzo,
Integer voto) {
this.titolo = (titolo == null) ? "" : titolo.trim();
this.piattaforma = (piattaforma == null) ? "" : piattaforma.trim();
this.annoUscita = (annoUscita == null) ? 0 : annoUscita;
this.prezzo = (prezzo == null) ? 0.0 : prezzo;
this.voto = (voto == null) ? 0 : voto;
}
}
@@ -0,0 +1,68 @@
package binary_tree;
public class LinkedBinaryTree<E> implements BinaryTree<E>{
// VARIABILI D'INSTANZA
private BinaryNode<E> root;
private int size;
// Metodi costruttori
public LinkedBinaryTree() {
root = null;
size = 0;
}
public LinkedBinaryTree(E data) {
root = new BinaryNode<E>(data);
size = 1;
}
public LinkedBinaryTree(LinkedBinaryTree<E> left, E data, LinkedBinaryTree<E> right) {
root = new BinaryNode<E>(left.root, data, right.root);
size = 1 + left.size + right.size;
}
// METODI
public int size() {
return size;
}
@Override
public boolean isEmpty() {
return root == null;
}
public E getRoot() {
if (isEmpty()) return null;
return root.getData();
}
public BinaryNode<E> getRootNode() {
if (isEmpty()) return null;
return root;
}
public void clear() {
root = null;
size = 0;
}
private int getSize(BinaryNode<E> node) {
if (node == null) return 0;
int nLeft = (node.getLeft() == null) ? 0 : getSize(node.getLeft());
int nRight = (node.getRight() == null) ? 0 : getSize(node.getRight());
return 1 + nLeft + nRight;
}
public LinkedBinaryTree<E> removeLeft() {
LinkedBinaryTree<E> leftTree = null;
if (root.getLeft() == null) return leftTree;
leftTree.root = root.getLeft();
return leftTree;
}
}
@@ -0,0 +1,17 @@
package binary_tree;
public class ExerciseBinaryTree {
/*
* Esercizio 1 II parziale 10.01.2018
* Un albero binario di interi si dice pari se tutti i nodi contengono
* un intero positivo pari. Realizzare il metodo statico
* public static boolean IsEvenBtree (BinaryTree<Integer> btree)
* che verifica se l'albero binario dato btree e' pari.
*/
public static boolean isEvenBtree(BinaryTree<Integer> btree) {
boolean even = true;
}
}
@@ -0,0 +1,74 @@
package binary_tree;
public class LinkedBinaryTree<E> implements BinaryTree<E>{
// VARIABILI D'INSTANZA
private BinaryNode<E> root;
private int size;
// Metodi costruttori
public LinkedBinaryTree() {
root = null;
size = 0;
}
public LinkedBinaryTree(E data) {
root = new BinaryNode<E>(data);
size = 1;
}
public LinkedBinaryTree(LinkedBinaryTree<E> left, E data, LinkedBinaryTree<E> right) {
root = new BinaryNode<E>(left.root, data, right.root);
size = 1 + left.size + right.size;
}
// METODI
public int size() {
return size;
}
@Override
public boolean isEmpty() {
return root == null;
}
public E getRoot() {
if (isEmpty()) return null;
return root.getData();
}
public BinaryNode<E> getRootNode() {
if (isEmpty()) return null;
return root;
}
public void clear() {
root = null;
size = 0;
}
private int getSize(BinaryNode<E> node) {
if (node == null) return 0;
int nLeft = (node.getLeft() == null) ? 0 : getSize(node.getLeft());
int nRight = (node.getRight() == null) ? 0 : getSize(node.getRight());
return 1 + nLeft + nRight;
}
public LinkedBinaryTree<E> removeLeft() {
LinkedBinaryTree<E> leftTree = null;
if (root.getLeft() == null) return leftTree;
leftTree = new LinkedBinaryTree<E>();
leftTree.root = root.getLeft();
leftTree.size = getSize(root.getLeft());
leftTree.root.setAsRoot();
size = size - leftTree.size;
return leftTree;
}
}
@@ -0,0 +1,488 @@
package binary_tree;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Stack;
public class LinkedBinaryTree<E> implements BinaryTree<E>{
// VARIABILI D'INSTANZA
private BinaryNode<E> root;
private int size;
// Metodi costruttori
public LinkedBinaryTree() {
root = null;
size = 0;
}
public LinkedBinaryTree(E data) {
root = new BinaryNode<E>(data);
size = 1;
}
public LinkedBinaryTree(LinkedBinaryTree<E> left, E data, LinkedBinaryTree<E> right) {
root = new BinaryNode<E>(left.root, data, right.root);
size = 1 + left.size + right.size;
}
// METODI
public int size() {
return size;
}
@Override
public boolean isEmpty() {
return root == null;
}
public E getRoot() {
if (isEmpty()) return null;
return root.getData();
}
public BinaryNode<E> getRootNode() {
if (isEmpty()) return null;
return root;
}
public void clear() {
root = null;
size = 0;
}
private int getSize(BinaryNode<E> node) {
if (node == null) return 0;
int nLeft = (node.getLeft() == null) ? 0 : getSize(node.getLeft());
int nRight = (node.getRight() == null) ? 0 : getSize(node.getRight());
return 1 + nLeft + nRight;
}
public LinkedBinaryTree<E> removeLeft() {
LinkedBinaryTree<E> leftTree = null;
if (root.getLeft() == null) return leftTree;
leftTree = new LinkedBinaryTree<E>();
leftTree.root = root.getLeft();
leftTree.size = getSize(root.getLeft());
leftTree.root.setAsRoot();
size = size - leftTree.size;
return leftTree;
}
public LinkedBinaryTree<E> removeRight() {
LinkedBinaryTree<E> rightTree = null;
if (root.getRight() == null) return rightTree;
rightTree = new LinkedBinaryTree<E>();
rightTree.root = root.getRight();
rightTree.size = getSize(root.getRight());
rightTree.root.setAsRoot();
size = size - rightTree.size;
return rightTree;
}
protected BinaryNode<E> find(E targetElement, BinaryNode<E> root) {
if (root == null) return null;
if (root.getData().equals(targetElement)) return root;
BinaryNode<E> resNode;
resNode = find(targetElement, root.getLeft());
if (resNode == null) resNode = find(targetElement, root.getRight());
return resNode;
}
public boolean remove(E targetElement) {
if (targetElement == null) return false;
BinaryNode<E> temp = find(targetElement, root);
if (temp != null) {
temp.setData(null);
return true;
}
return false;
}
public boolean contains(E targetElement) {
return find(targetElement, root) != null;
}
// ITERATORE PREORDER
/*
* Qui si utilizza il metodo del preorder.
* Le regole per il preorder sono queste:
* - Visita prima se stesso
* - Poi visita tutto ciò che si trova sinistra
* - Infine visita tutto ciò che si trova a destra
*/
protected void preorder (BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
if (node.getData() != null) temporaryList.add(node.getData());
preorder(node.getLeft(), temporaryList);
preorder(node.getRight(), temporaryList);
}
public Iterator<E> iteratorPreOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
preorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE INORDER
/*
* Qui si utilizza il metodo del inorder.
* Le regole per l'inorder sono queste:
* - Visita prima tutto ciò che si trova a sinistra
* - Poi visita se stesso
* - Infine visita tutto ciò che si trova a destra
*/
protected void inorder(BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
inorder(node.getLeft(), temporaryList);
if (node.getData() != null) temporaryList.add(node.getData());
inorder(node.getRight(), temporaryList);
}
public Iterator<E> iteratorInOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
inorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE POSTORDER
/*
* Qui si utilizza il metodo postorder.
* Le regole per il postorder sono queste:
* - Visita prima di tutto ciò che si trova a sinistra
* - Poi visita tutto ciò che si trova a destra
* - Infine visita il sestesso
*/
protected void postorder(BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
postorder(node.getLeft(), temporaryList);
postorder(node.getRight(), temporaryList);
if (node.getData() != null) temporaryList.add(node.getData());
}
public Iterator<E> iteratorPostOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
postorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE LEVEL ORDER
/*
* Qui si usa il metodo levelorder.
* Si analizza tutto il livello dell'albero.
* Per chiarire di seguito un esempio:
*
* A
* / \
* B C
* / \ \
* D E F
*
* La lettura avviene quindi in questo modo:
* A - B - C - D - E - F
*
* Si adopera una coda (Queue) di tipo FI-FO (First In - First Out)
*/
protected void levelorder(BinaryNode<E> node, List<E> temporaryList) {
Queue<BinaryNode<E>> queueOfNodes = new LinkedList<BinaryNode<E>>();
BinaryNode<E> current;
queueOfNodes.add(node);
while(!queueOfNodes.isEmpty()) {
current = queueOfNodes.remove();
if (current.getData() != null) temporaryList.add(current.getData());
if (current.getLeft() != null) queueOfNodes.add(current.getLeft());
if (current.getRight() != null) queueOfNodes.add(current.getRight());
}
}
public Iterator<E> iteratorLevelOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
levelorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE
public Iterator<E> iterator() {
return iteratorPreOrder();
}
// ITERATORE PREORDER ITERATIVO (NON RICORSIVO)
/*
* In questo caso stiamo usando un tipo stack.
* Dobbiamo di fatto simulare uno stack se vogliamo
* iterativamente fare questa cosa.
*
* Perchè se prima dobbiamo visitare il nodo centrale,
* poi il nodo a sinistra e poi il nodo a destra inseriamo
* prima quello di destra e poi quello di sinistra?
*
* Lo stack di fatto è una coda LIFO, ovvero last in - first out
* e quindi l'ultimo che entra è il primo che esce.
*
* dal momento che vale questa cosa, se facciamo entrare prima quello
* di destra e poi quello di sinistra, il primo nodo che verrà
* prelevato è ovviamente quello a sinistra.
*/
protected void itpreorder (BinaryNode<E> node, List<E> temporaryList) {
Stack<BinaryNode<E>> queueOfNodes = new Stack<BinaryNode<E>>();
BinaryNode<E> current;
queueOfNodes.add(node);
while (!queueOfNodes.isEmpty()) {
current = queueOfNodes.pop();
if (current.getData() != null) temporaryList.add(current.getData());
// Come già spiegato pushamo prima il nodo di destra
if (current.getRight() != null) queueOfNodes.push(current.getRight());
// Infine aggiungiamo il nodo di sinistra
if (current.getLeft() != null) queueOfNodes.push(current.getLeft());
}
}
public Iterator<E> ititeratorPreOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
itpreorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATOR INORDER ITERATIVO (NON RICORSIVO)
/*
* Questo metodo riguarda lo stesso di quello superiore.
* Il metodo inorder richiede che si visiti prima sinistra,
* poi il nodo stesso, infine il nodo di destra.
*
* Possiamo quindi sempre adoperare uno Stack per siumlare la
* ricorsione.
*
* Come detto prima, se il primo nodo ad essere prelevato è
* l'ultimo che si inserisce (coda LIFO, Stack) allora per simulare
* sinistra -> centro -> destra.
*
* Nel metodo sono state inserite delle check con uno stack di
* flag che permette di capire quando il nodo centrale è visitare
* oppure no.
*/
private void itinorder(BinaryNode<E> node, List<E> temporaryList) {
Stack<BinaryNode<E>> queueOfNodes = new Stack<BinaryNode<E>>();
Stack<Boolean> flags = new Stack<Boolean>();
BinaryNode<E> current;
Boolean flag;
queueOfNodes.add(node);
flags.push(false);
while (!queueOfNodes.isEmpty()) {
current = queueOfNodes.pop();
flag = flags.pop();
if (flag) {
// il nodo è da visitare
if (current.getData() != null) temporaryList.add(current.getData());
} else {
// il nodo non è da visitare
// prima si aggiunge il nodo di destra
if (current.getRight() != null) {
queueOfNodes.add(current.getRight());
flags.add(false);
}
queueOfNodes.push(current);
flags.push(true);
if (current.getLeft() != null) {
queueOfNodes.add(current.getLeft());
flags.push(false);
}
}
}
}
public Iterator<E> ititeratorInOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
itinorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATOR POST ORDER ITERATIVO (NON RICORSIVO)
/*
* In questo caso la logica è la seguente. si ha la
* necessità di fare il seguente ciclo: SINISTRA -> DESTRA -> NODO CORRENTE
*
* Per simulare lo stack dobbiamo quindi ripercorrerlo al contrario,
* dunque NODO CORRENTE -> DESTRA -> SINISTRA
*
* Possiamo dunque rifare lo stesso, di ciò che abbiamo fatto sopra.
*/
protected void itpostorder(BinaryNode<E> node, List<E> temporaryList) {
Stack<BinaryNode<E>> queueOfNodes = new Stack<BinaryNode<E>>();
Stack<Boolean> flags = new Stack<Boolean>();
BinaryNode<E> current;
Boolean flag;
queueOfNodes.push(node);
flags.push(false);
while (!queueOfNodes.isEmpty()) {
current = queueOfNodes.pop();
flag = flags.pop();
if (flag) {
// il nodo è da visitare
if (current.getData() != null) temporaryList.add(current.getData());
} else {
// il nodo non è ancora da visitare
// Visitiamo il nodo corrente
queueOfNodes.push(current);
flags.push(true);
// visitiamo il nodo di destra
if (current.getRight() != null) {
queueOfNodes.push(current.getRight());
flags.push(false);
}
// visitiamo il nodo di sinistra infine
if (current.getLeft() != null) {
queueOfNodes.push(current.getLeft());
flags.push(false);
}
}
}
}
public Iterator<E> ititeratorPostOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
itpostorder(root, temporaryList);
return temporaryList.iterator();
}
/*
* II parziale 2022/2023
* Realizzare un metodo costruttore della classe LinkedBinaryTree<E> che
* prende in input una lista di oggetti di tipo E e costruisce una catena
* casuale tale che l'iesimo elemento della lista è posizionato al livello iesimo
* della catena e ogni nodo ha probabilità 1/2 di avere un figlio sinistro/destro.
*/
/*
* Spiegazione intuitiva (visto che la melideo intende complicare la consegna):
* Data ad esempio una lista del genere:
* [A, B, C, D]
*
* Si ottiene quindi una catena del genere:
* A
* \
* B
* /
* C
* \
* D
*/
public LinkedBinaryTree(List<E> objectList) {
if (objectList == null) throw new NullPointerException();
Iterator<E> iterator = objectList.iterator();
if (!iterator.hasNext()) return;
E currentObject = iterator.next();
root = new BinaryNode<E>(currentObject);
BinaryNode<E> currentNode = root;
currentNode.setData(currentObject);
size = 1;
while (iterator.hasNext()) {
currentObject = iterator.next();
int wing = (int) (Math.random() * 2);
BinaryNode<E> newNode = new BinaryNode<E>(currentObject);
if (wing == 0) {
// Left
newNode.setParentAsLeftChild(currentNode);
} else {
// Right
newNode.setParentAsRightChild(currentNode);
}
currentNode = newNode;
size++;
}
}
/*
* II parziale 2022
* Si aggiunga alla classe LinkedBinaryTree<E> un metodo
* che stampa le foglie dall'albero corrente (da sinistra verso destra)
*/
public void printLeaf() {
printLeaf(root);
}
public void printLeaf(BinaryNode<E> node) {
if (node == null) return;
if (node.getLeft() == null && node.getRight() == null) System.out.println(node.getData().toString());
else {
printLeaf(node.getLeft());
printLeaf(node.getRight());
}
}
/*
* Si aggiunga alla classe LinkedBinaryTree<E> un metodo che conta il numero
* di foglie dell'albero corrente
*/
public void numberLeaf() {
Integer number = 0;
numberLeaf(root, number);
}
public void numberLeaf(BinaryNode<E> node, Integer number) {
if (node == null) return;
if (node.getLeft() == null && node.getRight() == null) number++;
else {
numberLeaf(node.getLeft(), number);
numberLeaf(node.getRight(), number);
}
}
}
@@ -0,0 +1,39 @@
package comparatori.videogioco;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Main {
public static void main(String[] Args) {
ArrayList<Videogioco> giochi = new ArrayList<Videogioco>();
giochi.add(new Videogioco("The Last of Us Part II", "PS5", 2020, 39.99, 9));
giochi.add(new Videogioco("Cyberpunk 2077", "PC", 2020, 29.99, 8));
giochi.add(new Videogioco("Minecraft", "PC", 2011, 19.99, 10));
giochi.add(new Videogioco("Ghost of Tsushima", "PS5", 2020, 49.99, 9));
giochi.add(new Videogioco("Resident Evil 4 Remake", "PS5", 2023, 44.99, 9));
giochi.add(new Videogioco("GTA V", "PC", 2013, 14.99, 8));
giochi.add(new Videogioco("God of War Ragnarok", "PS5", 2022, 59.99, 10));
giochi.add(new Videogioco("Fortnite", "PC", 2017, 0.0, 7));
// Per adoperare il comparable
Collections.sort(giochi);
}
private <T> void printList(List<T> lista) {
System.out.print("{");
for (int i = 0; i < lista.size(); i++) {
System.out.print(" [");
System.out.print(lista.get(i).toString());
System.out.print("] ");
}
System.out.print("}");
}
}
@@ -0,0 +1,20 @@
package queue;
import java.util.ArrayList;
import java.util.List;
public class ArrayListQueue<T> implements MyQueue<T> {
private List<T> queue = new ArrayList<T>();
@Override
public boolean offer(T item) {
return queue.add(item);
}
@Override
public T remove() {
return queue.removeFirst():
}
}
@@ -0,0 +1,483 @@
package binary_tree;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Stack;
public class LinkedBinaryTree<E> implements BinaryTree<E>{
// VARIABILI D'INSTANZA
private BinaryNode<E> root;
private int size;
// Metodi costruttori
public LinkedBinaryTree() {
root = null;
size = 0;
}
public LinkedBinaryTree(E data) {
root = new BinaryNode<E>(data);
size = 1;
}
public LinkedBinaryTree(LinkedBinaryTree<E> left, E data, LinkedBinaryTree<E> right) {
root = new BinaryNode<E>(left.root, data, right.root);
size = 1 + left.size + right.size;
}
// METODI
public int size() {
return size;
}
@Override
public boolean isEmpty() {
return root == null;
}
public E getRoot() {
if (isEmpty()) return null;
return root.getData();
}
public BinaryNode<E> getRootNode() {
if (isEmpty()) return null;
return root;
}
public void clear() {
root = null;
size = 0;
}
private int getSize(BinaryNode<E> node) {
if (node == null) return 0;
int nLeft = (node.getLeft() == null) ? 0 : getSize(node.getLeft());
int nRight = (node.getRight() == null) ? 0 : getSize(node.getRight());
return 1 + nLeft + nRight;
}
public LinkedBinaryTree<E> removeLeft() {
LinkedBinaryTree<E> leftTree = null;
if (root.getLeft() == null) return leftTree;
leftTree = new LinkedBinaryTree<E>();
leftTree.root = root.getLeft();
leftTree.size = getSize(root.getLeft());
leftTree.root.setAsRoot();
size = size - leftTree.size;
return leftTree;
}
public LinkedBinaryTree<E> removeRight() {
LinkedBinaryTree<E> rightTree = null;
if (root.getRight() == null) return rightTree;
rightTree = new LinkedBinaryTree<E>();
rightTree.root = root.getRight();
rightTree.size = getSize(root.getRight());
rightTree.root.setAsRoot();
size = size - rightTree.size;
return rightTree;
}
protected BinaryNode<E> find(E targetElement, BinaryNode<E> root) {
if (root == null) return null;
if (root.getData().equals(targetElement)) return root;
BinaryNode<E> resNode;
resNode = find(targetElement, root.getLeft());
if (resNode == null) resNode = find(targetElement, root.getRight());
return resNode;
}
public boolean remove(E targetElement) {
if (targetElement == null) return false;
BinaryNode<E> temp = find(targetElement, root);
if (temp != null) {
temp.setData(null);
return true;
}
return false;
}
public boolean contains(E targetElement) {
return find(targetElement, root) != null;
}
// ITERATORE PREORDER
/*
* Qui si utilizza il metodo del preorder.
* Le regole per il preorder sono queste:
* - Visita prima se stesso
* - Poi visita tutto ciò che si trova sinistra
* - Infine visita tutto ciò che si trova a destra
*/
protected void preorder (BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
if (node.getData() != null) temporaryList.add(node.getData());
preorder(node.getLeft(), temporaryList);
preorder(node.getRight(), temporaryList);
}
public Iterator<E> iteratorPreOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
preorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE INORDER
/*
* Qui si utilizza il metodo del inorder.
* Le regole per l'inorder sono queste:
* - Visita prima tutto ciò che si trova a sinistra
* - Poi visita se stesso
* - Infine visita tutto ciò che si trova a destra
*/
protected void inorder(BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
inorder(node.getLeft(), temporaryList);
if (node.getData() != null) temporaryList.add(node.getData());
inorder(node.getRight(), temporaryList);
}
public Iterator<E> iteratorInOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
inorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE POSTORDER
/*
* Qui si utilizza il metodo postorder.
* Le regole per il postorder sono queste:
* - Visita prima di tutto ciò che si trova a sinistra
* - Poi visita tutto ciò che si trova a destra
* - Infine visita il sestesso
*/
protected void postorder(BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
postorder(node.getLeft(), temporaryList);
postorder(node.getRight(), temporaryList);
if (node.getData() != null) temporaryList.add(node.getData());
}
public Iterator<E> iteratorPostOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
postorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE LEVEL ORDER
/*
* Qui si usa il metodo levelorder.
* Si analizza tutto il livello dell'albero.
* Per chiarire di seguito un esempio:
*
* A
* / \
* B C
* / \ \
* D E F
*
* La lettura avviene quindi in questo modo:
* A - B - C - D - E - F
*
* Si adopera una coda (Queue) di tipo FI-FO (First In - First Out)
*/
protected void levelorder(BinaryNode<E> node, List<E> temporaryList) {
Queue<BinaryNode<E>> queueOfNodes = new LinkedList<BinaryNode<E>>();
BinaryNode<E> current;
queueOfNodes.add(node);
while(!queueOfNodes.isEmpty()) {
current = queueOfNodes.remove();
if (current.getData() != null) temporaryList.add(current.getData());
if (current.getLeft() != null) queueOfNodes.add(current.getLeft());
if (current.getRight() != null) queueOfNodes.add(current.getRight());
}
}
public Iterator<E> iteratorLevelOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
levelorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE
public Iterator<E> iterator() {
return iteratorPreOrder();
}
// ITERATORE PREORDER ITERATIVO (NON RICORSIVO)
/*
* In questo caso stiamo usando un tipo stack.
* Dobbiamo di fatto simulare uno stack se vogliamo
* iterativamente fare questa cosa.
*
* Perchè se prima dobbiamo visitare il nodo centrale,
* poi il nodo a sinistra e poi il nodo a destra inseriamo
* prima quello di destra e poi quello di sinistra?
*
* Lo stack di fatto è una coda LIFO, ovvero last in - first out
* e quindi l'ultimo che entra è il primo che esce.
*
* dal momento che vale questa cosa, se facciamo entrare prima quello
* di destra e poi quello di sinistra, il primo nodo che verrà
* prelevato è ovviamente quello a sinistra.
*/
protected void itpreorder (BinaryNode<E> node, List<E> temporaryList) {
Stack<BinaryNode<E>> queueOfNodes = new Stack<BinaryNode<E>>();
BinaryNode<E> current;
queueOfNodes.add(node);
while (!queueOfNodes.isEmpty()) {
current = queueOfNodes.pop();
if (current.getData() != null) temporaryList.add(current.getData());
// Come già spiegato pushamo prima il nodo di destra
if (current.getRight() != null) queueOfNodes.push(current.getRight());
// Infine aggiungiamo il nodo di sinistra
if (current.getLeft() != null) queueOfNodes.push(current.getLeft());
}
}
public Iterator<E> ititeratorPreOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
itpreorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATOR INORDER ITERATIVO (NON RICORSIVO)
/*
* Questo metodo riguarda lo stesso di quello superiore.
* Il metodo inorder richiede che si visiti prima sinistra,
* poi il nodo stesso, infine il nodo di destra.
*
* Possiamo quindi sempre adoperare uno Stack per siumlare la
* ricorsione.
*
* Come detto prima, se il primo nodo ad essere prelevato è
* l'ultimo che si inserisce (coda LIFO, Stack) allora per simulare
* sinistra -> centro -> destra.
*
* Nel metodo sono state inserite delle check con uno stack di
* flag che permette di capire quando il nodo centrale è visitare
* oppure no.
*/
private void itinorder(BinaryNode<E> node, List<E> temporaryList) {
Stack<BinaryNode<E>> queueOfNodes = new Stack<BinaryNode<E>>();
Stack<Boolean> flags = new Stack<Boolean>();
BinaryNode<E> current;
Boolean flag;
queueOfNodes.add(node);
flags.push(false);
while (!queueOfNodes.isEmpty()) {
current = queueOfNodes.pop();
flag = flags.pop();
if (flag) {
// il nodo è da visitare
if (current.getData() != null) temporaryList.add(current.getData());
} else {
// il nodo non è da visitare
// prima si aggiunge il nodo di destra
if (current.getRight() != null) {
queueOfNodes.add(current.getRight());
flags.add(false);
}
queueOfNodes.push(current);
flags.push(true);
if (current.getLeft() != null) {
queueOfNodes.add(current.getLeft());
flags.push(false);
}
}
}
}
public Iterator<E> ititeratorInOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
itinorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATOR POST ORDER ITERATIVO (NON RICORSIVO)
/*
* In questo caso la logica è la seguente. si ha la
* necessità di fare il seguente ciclo: SINISTRA -> DESTRA -> NODO CORRENTE
*
* Per simulare lo stack dobbiamo quindi ripercorrerlo al contrario,
* dunque NODO CORRENTE -> DESTRA -> SINISTRA
*
* Possiamo dunque rifare lo stesso, di ciò che abbiamo fatto sopra.
*/
protected void itpostorder(BinaryNode<E> node, List<E> temporaryList) {
Stack<BinaryNode<E>> queueOfNodes = new Stack<BinaryNode<E>>();
Stack<Boolean> flags = new Stack<Boolean>();
BinaryNode<E> current;
Boolean flag;
queueOfNodes.push(node);
flags.push(false);
while (!queueOfNodes.isEmpty()) {
current = queueOfNodes.pop();
flag = flags.pop();
if (flag) {
// il nodo è da visitare
if (current.getData() != null) temporaryList.add(current.getData());
} else {
// il nodo non è ancora da visitare
// Visitiamo il nodo corrente
queueOfNodes.push(current);
flags.push(true);
// visitiamo il nodo di destra
if (current.getRight() != null) {
queueOfNodes.push(current.getRight());
flags.push(false);
}
// visitiamo il nodo di sinistra infine
if (current.getLeft() != null) {
queueOfNodes.push(current.getLeft());
flags.push(false);
}
}
}
}
public Iterator<E> ititeratorPostOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
itpostorder(root, temporaryList);
return temporaryList.iterator();
}
/*
* II parziale 2022/2023
* Realizzare un metodo costruttore della classe LinkedBinaryTree<E> che
* prende in input una lista di oggetti di tipo E e costruisce una catena
* casuale tale che l'iesimo elemento della lista è posizionato al livello iesimo
* della catena e ogni nodo ha probabilità 1/2 di avere un figlio sinistro/destro.
*/
/*
* Spiegazione intuitiva (visto che la melideo intende complicare la consegna):
* Data ad esempio una lista del genere:
* [A, B, C, D]
*
* Si ottiene quindi una catena del genere:
* A
* \
* B
* /
* C
* \
* D
*/
public LinkedBinaryTree(List<E> objectList) {
if (objectList == null) throw new NullPointerException();
Iterator<E> iterator = objectList.iterator();
if (!iterator.hasNext()) return;
E currentObject = iterator.next();
root = new BinaryNode<E>(currentObject);
BinaryNode<E> currentNode = root;
currentNode.setData(currentObject);
size = 1;
while (iterator.hasNext()) {
currentObject = iterator.next();
int wing = (int) (Math.random() * 2);
BinaryNode<E> newNode = new BinaryNode<E>(currentObject);
if (wing == 0) {
// Left
newNode.setParentAsLeftChild(currentNode);
} else {
// Right
newNode.setParentAsRightChild(currentNode);
}
currentNode = newNode;
size++;
}
}
/*
* II parziale 2022
* Si aggiunga alla classe LinkedBinaryTree<E> un metodo
* che stampa le foglie dall'albero corrente (da sinistra verso destra)
*/
public void printLeaf() {
printLeaf(root);
}
public void printLeaf(BinaryNode<E> node) {
if (node == null) return;
if (node.getLeft() == null && node.getRight() == null) System.out.println(node.getData().toString());
else {
printLeaf(node.getLeft());
printLeaf(node.getRight());
}
}
/*
* Si aggiunga alla classe LinkedBinaryTree<E> un metodo che conta il numero
* di foglie dell'albero corrente
*/
public int numberLeaf() {
Integer number = 0;
numberLeaf(root, number);
return number;
}
public int numberLeaf(BinaryNode<E> node) {
}
}
@@ -0,0 +1,79 @@
package binary_tree;
public class BinaryNode<E> {
// VARIABILI
private BinaryNode<E> left, right, parent;
private E data;
// COSTRUTTORI
public BinaryNode(E data) {
this.data = data;
left = right = parent = null;
}
public BinaryNode(BinaryNode<E> left, E data, BinaryNode<E> right) {
this.data = data;
this.left = left;
this.right = right;
this.parent = null;
if (this.left != null) this.left.parent = this;
if (this.right != null) this.right.parent = this;
}
// METODI
public E getData() {
return data;
}
public BinaryNode<E> getLeft() {
return left;
}
public BinaryNode<E> getRight() {
return right;
}
public BinaryNode<E> getParent() {
return parent;
}
public boolean isRoot() {
return parent == null;
}
public boolean isLeftChild() {
return parent != null && parent.getLeft() == this;
}
public boolean isRightChild() {
return parent != null && parent.getRight() == this;
}
public void setData(E data) {
this.data = data;
}
public void setLeft(BinaryNode<E> left) {
this.left = left;
if (this.left != null) this.left.parent = this;
}
public void setRight(BinaryNode<E> right) {
this.right = right;
if (this.right != null) this.right.parent = this;
}
public BinaryNode<E> setParentAsLeftChild(BinaryNode<E> parent) {
if (this.parent == null) return null;
this.parent = parent;
}
}
@@ -0,0 +1,73 @@
package binary_tree;
public class BinaryNode<E> {
// VARIABILI
private BinaryNode<E> left, right, parent;
private E data;
// COSTRUTTORI
public BinaryNode(E data) {
this.data = data;
left = right = parent = null;
}
public BinaryNode(BinaryNode<E> left, E data, BinaryNode<E> right) {
this.data = data;
this.left = left;
this.right = right;
this.parent = null;
if (this.left != null) this.left.parent = this;
if (this.right != null) this.right.parent = this;
}
// METODI
public E getData() {
return data;
}
public BinaryNode<E> getLeft() {
return left;
}
public BinaryNode<E> getRight() {
return right;
}
public BinaryNode<E> getParent() {
return parent;
}
public boolean isRoot() {
return parent == null;
}
public boolean isLeftChild() {
return parent != null && parent.getLeft() == this;
}
public boolean isRightChild() {
return parent != null && parent.getRight() == this;
}
public void setData(E data) {
this.data = data;
}
public void setLeft(BinaryNode<E> left) {
this.left = left;
if (this.left != null) this.left.parent = this;
}
public void setRight() {
}
}
@@ -0,0 +1,14 @@
package stack;
public interface MyStack<T> {
void push(T item);
T pop();
T peek();
int size();
boolean isEmpty();
}
@@ -0,0 +1,327 @@
package binary_tree;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Stack;
public class LinkedBinaryTree<E> implements BinaryTree<E>{
// VARIABILI D'INSTANZA
private BinaryNode<E> root;
private int size;
// Metodi costruttori
public LinkedBinaryTree() {
root = null;
size = 0;
}
public LinkedBinaryTree(E data) {
root = new BinaryNode<E>(data);
size = 1;
}
public LinkedBinaryTree(LinkedBinaryTree<E> left, E data, LinkedBinaryTree<E> right) {
root = new BinaryNode<E>(left.root, data, right.root);
size = 1 + left.size + right.size;
}
// METODI
public int size() {
return size;
}
@Override
public boolean isEmpty() {
return root == null;
}
public E getRoot() {
if (isEmpty()) return null;
return root.getData();
}
public BinaryNode<E> getRootNode() {
if (isEmpty()) return null;
return root;
}
public void clear() {
root = null;
size = 0;
}
private int getSize(BinaryNode<E> node) {
if (node == null) return 0;
int nLeft = (node.getLeft() == null) ? 0 : getSize(node.getLeft());
int nRight = (node.getRight() == null) ? 0 : getSize(node.getRight());
return 1 + nLeft + nRight;
}
public LinkedBinaryTree<E> removeLeft() {
LinkedBinaryTree<E> leftTree = null;
if (root.getLeft() == null) return leftTree;
leftTree = new LinkedBinaryTree<E>();
leftTree.root = root.getLeft();
leftTree.size = getSize(root.getLeft());
leftTree.root.setAsRoot();
size = size - leftTree.size;
return leftTree;
}
public LinkedBinaryTree<E> removeRight() {
LinkedBinaryTree<E> rightTree = null;
if (root.getRight() == null) return rightTree;
rightTree = new LinkedBinaryTree<E>();
rightTree.root = root.getRight();
rightTree.size = getSize(root.getRight());
rightTree.root.setAsRoot();
size = size - rightTree.size;
return rightTree;
}
protected BinaryNode<E> find(E targetElement, BinaryNode<E> root) {
if (root == null) return null;
if (root.getData().equals(targetElement)) return root;
BinaryNode<E> resNode;
resNode = find(targetElement, root.getLeft());
if (resNode == null) resNode = find(targetElement, root.getRight());
return resNode;
}
public boolean remove(E targetElement) {
if (targetElement == null) return false;
BinaryNode<E> temp = find(targetElement, root);
if (temp != null) {
temp.setData(null);
return true;
}
return false;
}
public boolean contains(E targetElement) {
return find(targetElement, root) != null;
}
// ITERATORE PREORDER
/*
* Qui si utilizza il metodo del preorder.
* Le regole per il preorder sono queste:
* - Visita prima se stesso
* - Poi visita tutto ciò che si trova sinistra
* - Infine visita tutto ciò che si trova a destra
*/
protected void preorder (BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
if (node.getData() != null) temporaryList.add(node.getData());
preorder(node.getLeft(), temporaryList);
preorder(node.getRight(), temporaryList);
}
public Iterator<E> iteratorPreOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
preorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE INORDER
/*
* Qui si utilizza il metodo del inorder.
* Le regole per l'inorder sono queste:
* - Visita prima tutto ciò che si trova a sinistra
* - Poi visita se stesso
* - Infine visita tutto ciò che si trova a destra
*/
protected void inorder(BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
inorder(node.getLeft(), temporaryList);
if (node.getData() != null) temporaryList.add(node.getData());
inorder(node.getRight(), temporaryList);
}
public Iterator<E> iteratorInOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
inorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE POSTORDER
/*
* Qui si utilizza il metodo postorder.
* Le regole per il postorder sono queste:
* - Visita prima di tutto ciò che si trova a sinistra
* - Poi visita tutto ciò che si trova a destra
* - Infine visita il sestesso
*/
protected void postorder(BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
postorder(node.getLeft(), temporaryList);
postorder(node.getRight(), temporaryList);
if (node.getData() != null) temporaryList.add(node.getData());
}
public Iterator<E> iteratorPostOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
postorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE LEVEL ORDER
/*
* Qui si usa il metodo levelorder.
* Si analizza tutto il livello dell'albero.
* Per chiarire di seguito un esempio:
*
* A
* / \
* B C
* / \ \
* D E F
*
* La lettura avviene quindi in questo modo:
* A - B - C - D - E - F
*
* Si adopera una coda (Queue) di tipo FI-FO (First In - First Out)
*/
protected void levelorder(BinaryNode<E> node, List<E> temporaryList) {
Queue<BinaryNode<E>> queueOfNodes = new LinkedList<BinaryNode<E>>();
BinaryNode<E> current;
queueOfNodes.add(node);
while(!queueOfNodes.isEmpty()) {
current = queueOfNodes.remove();
if (current.getData() != null) temporaryList.add(current.getData());
if (current.getLeft() != null) queueOfNodes.add(current.getLeft());
if (current.getRight() != null) queueOfNodes.add(current.getRight());
}
}
public Iterator<E> iteratorLevelOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
levelorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE
public Iterator<E> iterator() {
return iteratorPreOrder();
}
// ITERATORE PREORDER ITERATIVO (NON RICORSIVO)
/*
* In questo caso stiamo usando un tipo stack.
* Dobbiamo di fatto simulare uno stack se vogliamo
* iterativamente fare questa cosa.
*
* Perchè se prima dobbiamo visitare il nodo centrale,
* poi il nodo a sinistra e poi il nodo a destra inseriamo
* prima quello di destra e poi quello di sinistra?
*
* Lo stack di fatto è una coda LIFO, ovvero last in - first out
* e quindi l'ultimo che entra è il primo che esce.
*
* dal momento che vale questa cosa, se facciamo entrare prima quello
* di destra e poi quello di sinistra, il primo nodo che verrà
* prelevato è ovviamente quello a sinistra.
*/
protected void itpreorder (BinaryNode<E> node, List<E> temporaryList) {
Stack<BinaryNode<E>> queueOfNodes = new Stack<BinaryNode<E>>();
BinaryNode<E> current;
queueOfNodes.add(node);
while (!queueOfNodes.isEmpty()) {
current = queueOfNodes.pop();
if (current.getData() != null) temporaryList.add(current.getData());
// Come già spiegato pushamo prima il nodo di destra
if (current.getRight() != null) queueOfNodes.push(current.getRight());
// Infine aggiungiamo il nodo di sinistra
if (current.getLeft() != null) queueOfNodes.push(current.getLeft());
}
}
public Iterator<E> ititeratorInOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
itpreorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATOR INORDER ITERATIVO (NON RICORSIVO)
/*
* Questo metodo riguarda lo stesso di quello superiore.
* Il metodo inorder richiede che si visiti prima sinistra,
* poi il nodo stesso, infine il nodo di destra.
*
* Possiamo quindi sempre adoperare uno Stack per siumlare la
* ricorsione.
*
* Come detto prima, se il primo nodo ad essere prelevato è
* l'ultimo che si inserisce (coda LIFO, Stack) allora per simulare
* sinistra -> centro -> destra, il primo nodo da inserire è quello di
* destra
*/
private void itinorder(BinaryNode<E> node, List<E> temporaryList) {
Stack<BinaryNode<E>> queueOfNodes = new Stack<BinaryNode<E>>();
Stack<Boolean> flags = new Stack<Boolean>();
BinaryNode<E> current;
Boolean flag;
queueOfNodes.add(node);
flags.push(false);
while (!queueOfNodes.isEmpty()) {
current = queueOfNodes.pop();
flag = flags.pop();
if (flag) {
// il nodo è da visitare
if (current.getData() != null) temporaryList.add(current.getData());
} else {
// il nodo non è da visitare
// prima si aggiunge il nodo di destra
if (current.getRight() != null) {
queueOfNodes.add(current.getRight());
flags.add(false);
}
stackOfNodes.push(current);
}
}
}
}
@@ -0,0 +1,138 @@
package binary_tree;
import java.util.ArrayList;
import java.util.List;
public class LinkedBinaryTree<E> implements BinaryTree<E>{
// VARIABILI D'INSTANZA
private BinaryNode<E> root;
private int size;
// Metodi costruttori
public LinkedBinaryTree() {
root = null;
size = 0;
}
public LinkedBinaryTree(E data) {
root = new BinaryNode<E>(data);
size = 1;
}
public LinkedBinaryTree(LinkedBinaryTree<E> left, E data, LinkedBinaryTree<E> right) {
root = new BinaryNode<E>(left.root, data, right.root);
size = 1 + left.size + right.size;
}
// METODI
public int size() {
return size;
}
@Override
public boolean isEmpty() {
return root == null;
}
public E getRoot() {
if (isEmpty()) return null;
return root.getData();
}
public BinaryNode<E> getRootNode() {
if (isEmpty()) return null;
return root;
}
public void clear() {
root = null;
size = 0;
}
private int getSize(BinaryNode<E> node) {
if (node == null) return 0;
int nLeft = (node.getLeft() == null) ? 0 : getSize(node.getLeft());
int nRight = (node.getRight() == null) ? 0 : getSize(node.getRight());
return 1 + nLeft + nRight;
}
public LinkedBinaryTree<E> removeLeft() {
LinkedBinaryTree<E> leftTree = null;
if (root.getLeft() == null) return leftTree;
leftTree = new LinkedBinaryTree<E>();
leftTree.root = root.getLeft();
leftTree.size = getSize(root.getLeft());
leftTree.root.setAsRoot();
size = size - leftTree.size;
return leftTree;
}
public LinkedBinaryTree<E> removeRight() {
LinkedBinaryTree<E> rightTree = null;
if (root.getRight() == null) return rightTree;
rightTree = new LinkedBinaryTree<E>();
rightTree.root = root.getRight();
rightTree.size = getSize(root.getRight());
rightTree.root.setAsRoot();
size = size - rightTree.size;
return rightTree;
}
protected BinaryNode<E> find(E targetElement, BinaryNode<E> root) {
if (root == null) return null;
if (root.getData().equals(targetElement)) return root;
BinaryNode<E> resNode;
resNode = find(targetElement, root.getLeft());
if (resNode == null) resNode = find(targetElement, root.getRight());
return resNode;
}
public boolean remove(E targetElement) {
if (targetElement == null) return false;
BinaryNode<E> temp = find(targetElement, root);
if (temp != null) {
temp.setData(null);
return true;
}
return false;
}
public boolean contains(E targetElement) {
return find(targetElement, root) != null;
}
// ITERATORE PREORDER
/*
* Qui si utilizza il metodo del preorder.
* Le regole per il preorder sono queste:
* - Visita prima se stesso
* - Poi visita tutto ciò che si trova sinistra
* - Infine visita tutto ciò che si trova a destra
*/
protected void preorder (BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
if (node.getData() != null) temporaryList.add(node.getData());
preorder(node.getLeft(), temporaryList);
preorder(node.getRight(), temporaryList);
}
public Iterator<E> iteratorPreOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
preorder();
}
}
@@ -0,0 +1,41 @@
package parziale.p251110;
public class Paziente implements Comparable<Paziente> {
private String id;
private int annoNascita;
public Paziente(
String id,
int annoNascita) {
this.id = id;
this.annoNascita = annoNascita;
}
public String getId() {
return id;
}
public int getAnnoNascita() {
return annoNascita;
}
@Override
public boolean equals(Object o) {
if (o == null) return false;
if (this == o) return true;
if (!(o instanceof Paziente)) return false;
Paziente p = (Paziente) o;
return id.equals(p.id);
}
@Override
public int compareTo(Paziente p) {
if (annoNascita < p.annoNascita) return -1;
if (annoNascita > p.annoNascita) return 1;
return id.compareTo(p.id);
}
}
@@ -0,0 +1,84 @@
package binary_tree;
public class BinaryNode<E> {
// VARIABILI
private BinaryNode<E> left, right, parent;
private E data;
// COSTRUTTORI
public BinaryNode(E data) {
this.data = data;
left = right = parent = null;
}
public BinaryNode(BinaryNode<E> left, E data, BinaryNode<E> right) {
this.data = data;
this.left = left;
this.right = right;
this.parent = null;
if (this.left != null) this.left.parent = this;
if (this.right != null) this.right.parent = this;
}
// METODI
public E getData() {
return data;
}
public BinaryNode<E> getLeft() {
return left;
}
public BinaryNode<E> getRight() {
return right;
}
public BinaryNode<E> getParent() {
return parent;
}
public boolean isRoot() {
return parent == null;
}
public boolean isLeftChild() {
return parent != null && parent.getLeft() == this;
}
public boolean isRightChild() {
return parent != null && parent.getRight() == this;
}
public void setData(E data) {
this.data = data;
}
public void setLeft(BinaryNode<E> left) {
this.left = left;
if (this.left != null) this.left.parent = this;
}
public void setRight(BinaryNode<E> right) {
this.right = right;
if (this.right != null) this.right.parent = this;
}
public BinaryNode<E> setParentAsLeftChild(BinaryNode<E> parent) {
if (parent == null) return null;
this.parent = parent;
BinaryNode<E> oldLeft = this.parent.left;
this.parent.left = this;
return oldLeft;
}
}
@@ -0,0 +1,248 @@
package binary_tree;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
public class LinkedBinaryTree<E> implements BinaryTree<E>{
// VARIABILI D'INSTANZA
private BinaryNode<E> root;
private int size;
// Metodi costruttori
public LinkedBinaryTree() {
root = null;
size = 0;
}
public LinkedBinaryTree(E data) {
root = new BinaryNode<E>(data);
size = 1;
}
public LinkedBinaryTree(LinkedBinaryTree<E> left, E data, LinkedBinaryTree<E> right) {
root = new BinaryNode<E>(left.root, data, right.root);
size = 1 + left.size + right.size;
}
// METODI
public int size() {
return size;
}
@Override
public boolean isEmpty() {
return root == null;
}
public E getRoot() {
if (isEmpty()) return null;
return root.getData();
}
public BinaryNode<E> getRootNode() {
if (isEmpty()) return null;
return root;
}
public void clear() {
root = null;
size = 0;
}
private int getSize(BinaryNode<E> node) {
if (node == null) return 0;
int nLeft = (node.getLeft() == null) ? 0 : getSize(node.getLeft());
int nRight = (node.getRight() == null) ? 0 : getSize(node.getRight());
return 1 + nLeft + nRight;
}
public LinkedBinaryTree<E> removeLeft() {
LinkedBinaryTree<E> leftTree = null;
if (root.getLeft() == null) return leftTree;
leftTree = new LinkedBinaryTree<E>();
leftTree.root = root.getLeft();
leftTree.size = getSize(root.getLeft());
leftTree.root.setAsRoot();
size = size - leftTree.size;
return leftTree;
}
public LinkedBinaryTree<E> removeRight() {
LinkedBinaryTree<E> rightTree = null;
if (root.getRight() == null) return rightTree;
rightTree = new LinkedBinaryTree<E>();
rightTree.root = root.getRight();
rightTree.size = getSize(root.getRight());
rightTree.root.setAsRoot();
size = size - rightTree.size;
return rightTree;
}
protected BinaryNode<E> find(E targetElement, BinaryNode<E> root) {
if (root == null) return null;
if (root.getData().equals(targetElement)) return root;
BinaryNode<E> resNode;
resNode = find(targetElement, root.getLeft());
if (resNode == null) resNode = find(targetElement, root.getRight());
return resNode;
}
public boolean remove(E targetElement) {
if (targetElement == null) return false;
BinaryNode<E> temp = find(targetElement, root);
if (temp != null) {
temp.setData(null);
return true;
}
return false;
}
public boolean contains(E targetElement) {
return find(targetElement, root) != null;
}
// ITERATORE PREORDER
/*
* Qui si utilizza il metodo del preorder.
* Le regole per il preorder sono queste:
* - Visita prima se stesso
* - Poi visita tutto ciò che si trova sinistra
* - Infine visita tutto ciò che si trova a destra
*/
protected void preorder (BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
if (node.getData() != null) temporaryList.add(node.getData());
preorder(node.getLeft(), temporaryList);
preorder(node.getRight(), temporaryList);
}
public Iterator<E> iteratorPreOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
preorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE INORDER
/*
* Qui si utilizza il metodo del inorder.
* Le regole per l'inorder sono queste:
* - Visita prima tutto ciò che si trova a sinistra
* - Poi visita se stesso
* - Infine visita tutto ciò che si trova a destra
*/
protected void inorder(BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
inorder(node.getLeft(), temporaryList);
if (node.getData() != null) temporaryList.add(node.getData());
inorder(node.getRight(), temporaryList);
}
public Iterator<E> iteratorInOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
inorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE POSTORDER
/*
* Qui si utilizza il metodo postorder.
* Le regole per il postorder sono queste:
* - Visita prima di tutto ciò che si trova a sinistra
* - Poi visita tutto ciò che si trova a destra
* - Infine visita il sestesso
*/
protected void postorder(BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
postorder(node.getLeft(), temporaryList);
postorder(node.getRight(), temporaryList);
if (node.getData() != null) temporaryList.add(node.getData());
}
public Iterator<E> iteratorPostOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
postorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE LEVEL ORDER
/*
* Qui si usa il metodo levelorder.
* Si analizza tutto il livello dell'albero.
* Per chiarire di seguito un esempio:
*
* A
* / \
* B C
* / \ \
* D E F
*
* La lettura avviene quindi in questo modo:
* A - B - C - D - E - F
*
* Si adopera una coda (Queue) di tipo FI-FO (First In - First Out)
*/
protected void levelorder(BinaryNode<E> node, List<E> temporaryList) {
Queue<BinaryNode<E>> queueOfNodes = new LinkedList<BinaryNode<E>>();
BinaryNode<E> current;
queueOfNodes.add(node);
while(!queueOfNodes.isEmpty()) {
current = queueOfNodes.remove();
if (current.getData() != null) temporaryList.add(current.getData());
if (current.getLeft() != null) queueOfNodes.add(current.getLeft());
if (current.getRight() != null) queueOfNodes.add(current.getRight());
}
}
public Iterator<E> iteratorLevelOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
levelorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE
public Iterator<E> iterator() {
return iteratorPreOrder();
}
// ITERATORE PREORDER ITERATIVO (NON RICORSIVO)
protected void itpreorder(BinaryNode<E> node, List<E> temporaryList) {
Queue<BinaryNode<E>> queueOfNodes = new LinkedList<BinaryNode<E>>();
BinaryNode<E> current;
queueOfNodes.add(node);
}
}
@@ -0,0 +1,30 @@
package jcf_set.example;
import java.util.HashSet;
import java.util.Random;
import java.util.Set;
public class InteriRipetuti {
public static void main(String[] Args) {
}
public void run() {
int N = 20;
int MAX_INT = 50;
// HASHSET
Set<Integer> hashset = new HashSet<Integer>();
// Genero i numeri casuali inserendoli in nel set di hashset
Random generator = new Random();
for (int i = 0; i < N; i++) {
Integer x = generator.nextInt(MAX_INT + 1);
if (!hashset.add(x)) {
Syste
}
}
}
}
@@ -0,0 +1,62 @@
package binary_tree;
public class BinaryNode<E> {
// VARIABILI
private BinaryNode<E> left, right, parent;
private E data;
// COSTRUTTORI
public BinaryNode(E data) {
this.data = data;
left = right = parent = null;
}
public BinaryNode(BinaryNode<E> left, E data, BinaryNode<E> right) {
this.data = data;
this.left = left;
this.right = right;
this.parent = null;
if (this.left != null) this.left.parent = this;
if (this.right != null) this.right.parent = this;
}
// METODI
public E getData() {
return data;
}
public BinaryNode<E> getLeft() {
return left;
}
public BinaryNode<E> getRight() {
return right;
}
public BinaryNode<E> getParent() {
return parent;
}
public boolean isRoot() {
return parent == null;
}
public boolean isLeftChild() {
return parent != null && parent.getLeft() == this;
}
public boolean isRightChild() {
return parent != null && parent.getRight() == this;
}
}
@@ -0,0 +1,9 @@
package test;
public class Main {
public static void main (String[] Args) {
}
}
@@ -0,0 +1,106 @@
package binary_tree;
public class LinkedBinaryTree<E> implements BinaryTree<E>{
// VARIABILI D'INSTANZA
private BinaryNode<E> root;
private int size;
// Metodi costruttori
public LinkedBinaryTree() {
root = null;
size = 0;
}
public LinkedBinaryTree(E data) {
root = new BinaryNode<E>(data);
size = 1;
}
public LinkedBinaryTree(LinkedBinaryTree<E> left, E data, LinkedBinaryTree<E> right) {
root = new BinaryNode<E>(left.root, data, right.root);
size = 1 + left.size + right.size;
}
// METODI
public int size() {
return size;
}
@Override
public boolean isEmpty() {
return root == null;
}
public E getRoot() {
if (isEmpty()) return null;
return root.getData();
}
public BinaryNode<E> getRootNode() {
if (isEmpty()) return null;
return root;
}
public void clear() {
root = null;
size = 0;
}
private int getSize(BinaryNode<E> node) {
if (node == null) return 0;
int nLeft = (node.getLeft() == null) ? 0 : getSize(node.getLeft());
int nRight = (node.getRight() == null) ? 0 : getSize(node.getRight());
return 1 + nLeft + nRight;
}
public LinkedBinaryTree<E> removeLeft() {
LinkedBinaryTree<E> leftTree = null;
if (root.getLeft() == null) return leftTree;
leftTree = new LinkedBinaryTree<E>();
leftTree.root = root.getLeft();
leftTree.size = getSize(root.getLeft());
leftTree.root.setAsRoot();
size = size - leftTree.size;
return leftTree;
}
public LinkedBinaryTree<E> removeRight() {
LinkedBinaryTree<E> rightTree = null;
if (root.getRight() == null) return rightTree;
rightTree = new LinkedBinaryTree<E>();
rightTree.root = root.getRight();
rightTree.size = getSize(root.getRight());
rightTree.root.setAsRoot();
size = size - rightTree.size;
return rightTree;
}
protected BinaryNode<E> find(E targetElement, BinaryNode<E> root) {
if (root == null) return null;
if (root.getData().equals(targetElement)) return root;
BinaryNode<E> resNode;
resNode = find(targetElement, root.getLeft());
if (resNode == null) resNode = find(targetElement, root.getRight());
return resNode;
}
public boolean remove(E targetElement) {
if (targetElement == null) return false;
BinaryNode<E> temp = find(targetElement, root);
if (temp != null) {
}
return false;
}
}
@@ -0,0 +1,128 @@
package binary_tree;
public class BinaryNode<E> {
// VARIABILI
private BinaryNode<E> left, right, parent;
private E data;
// COSTRUTTORI
public BinaryNode(E data) {
this.data = data;
left = right = parent = null;
}
public BinaryNode(BinaryNode<E> left, E data, BinaryNode<E> right) {
this.data = data;
this.left = left;
this.right = right;
this.parent = null;
if (this.left != null) this.left.parent = this;
if (this.right != null) this.right.parent = this;
}
// METODI
public E getData() {
return data;
}
public BinaryNode<E> getLeft() {
return left;
}
public BinaryNode<E> getRight() {
return right;
}
public BinaryNode<E> getParent() {
return parent;
}
public boolean isRoot() {
return parent == null;
}
public boolean isLeftChild() {
return parent != null && parent.getLeft() == this;
}
public boolean isRightChild() {
return parent != null && parent.getRight() == this;
}
public void setData(E data) {
this.data = data;
}
public void setLeft(BinaryNode<E> left) {
this.left = left;
if (this.left != null) this.left.parent = this;
}
public void setRight(BinaryNode<E> right) {
this.right = right;
if (this.right != null) this.right.parent = this;
}
public BinaryNode<E> setParentAsLeftChild(BinaryNode<E> parent) {
if (parent == null) return null;
this.parent = parent;
BinaryNode<E> oldLeft = this.parent.left;
this.parent.left = this;
return oldLeft;
}
public BinaryNode<E> setParentAsRightChild(BinaryNode<E> parent) {
if (parent == null) return null;
this.parent = parent;
BinaryNode<E> oldRight = this.parent.right;
this.parent.right = this;
return oldRight;
}
public BinaryNode<E> setAsRoot() {
if (parent == null) return null;
BinaryNode<E> oldParent = parent;
parent = null;
if (oldParent.left == this) oldParent.left = null;
else oldParent.right = null;
return oldParent;
}
public boolean hasLeft() {
return left != null;
}
public boolean hasRight() {
return right != null;
}
@Override
public boolean equals(Object other) {
if (other == null) return false;
if (other == this) return true;
if (!(other instanceof BinaryNode<?>)) return false;
BinaryNode<?> otherType = (BinaryNode<?>)other;
return this.left.equals(otherType.left)
&& this.right.equals(otherType.right)
&& this.parent.equals(otherType.parent)
&& this.data.equals(otherType.data);
}
}
@@ -0,0 +1,281 @@
package binary_tree;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Stack;
public class LinkedBinaryTree<E> implements BinaryTree<E>{
// VARIABILI D'INSTANZA
private BinaryNode<E> root;
private int size;
// Metodi costruttori
public LinkedBinaryTree() {
root = null;
size = 0;
}
public LinkedBinaryTree(E data) {
root = new BinaryNode<E>(data);
size = 1;
}
public LinkedBinaryTree(LinkedBinaryTree<E> left, E data, LinkedBinaryTree<E> right) {
root = new BinaryNode<E>(left.root, data, right.root);
size = 1 + left.size + right.size;
}
// METODI
public int size() {
return size;
}
@Override
public boolean isEmpty() {
return root == null;
}
public E getRoot() {
if (isEmpty()) return null;
return root.getData();
}
public BinaryNode<E> getRootNode() {
if (isEmpty()) return null;
return root;
}
public void clear() {
root = null;
size = 0;
}
private int getSize(BinaryNode<E> node) {
if (node == null) return 0;
int nLeft = (node.getLeft() == null) ? 0 : getSize(node.getLeft());
int nRight = (node.getRight() == null) ? 0 : getSize(node.getRight());
return 1 + nLeft + nRight;
}
public LinkedBinaryTree<E> removeLeft() {
LinkedBinaryTree<E> leftTree = null;
if (root.getLeft() == null) return leftTree;
leftTree = new LinkedBinaryTree<E>();
leftTree.root = root.getLeft();
leftTree.size = getSize(root.getLeft());
leftTree.root.setAsRoot();
size = size - leftTree.size;
return leftTree;
}
public LinkedBinaryTree<E> removeRight() {
LinkedBinaryTree<E> rightTree = null;
if (root.getRight() == null) return rightTree;
rightTree = new LinkedBinaryTree<E>();
rightTree.root = root.getRight();
rightTree.size = getSize(root.getRight());
rightTree.root.setAsRoot();
size = size - rightTree.size;
return rightTree;
}
protected BinaryNode<E> find(E targetElement, BinaryNode<E> root) {
if (root == null) return null;
if (root.getData().equals(targetElement)) return root;
BinaryNode<E> resNode;
resNode = find(targetElement, root.getLeft());
if (resNode == null) resNode = find(targetElement, root.getRight());
return resNode;
}
public boolean remove(E targetElement) {
if (targetElement == null) return false;
BinaryNode<E> temp = find(targetElement, root);
if (temp != null) {
temp.setData(null);
return true;
}
return false;
}
public boolean contains(E targetElement) {
return find(targetElement, root) != null;
}
// ITERATORE PREORDER
/*
* Qui si utilizza il metodo del preorder.
* Le regole per il preorder sono queste:
* - Visita prima se stesso
* - Poi visita tutto ciò che si trova sinistra
* - Infine visita tutto ciò che si trova a destra
*/
protected void preorder (BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
if (node.getData() != null) temporaryList.add(node.getData());
preorder(node.getLeft(), temporaryList);
preorder(node.getRight(), temporaryList);
}
public Iterator<E> iteratorPreOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
preorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE INORDER
/*
* Qui si utilizza il metodo del inorder.
* Le regole per l'inorder sono queste:
* - Visita prima tutto ciò che si trova a sinistra
* - Poi visita se stesso
* - Infine visita tutto ciò che si trova a destra
*/
protected void inorder(BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
inorder(node.getLeft(), temporaryList);
if (node.getData() != null) temporaryList.add(node.getData());
inorder(node.getRight(), temporaryList);
}
public Iterator<E> iteratorInOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
inorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE POSTORDER
/*
* Qui si utilizza il metodo postorder.
* Le regole per il postorder sono queste:
* - Visita prima di tutto ciò che si trova a sinistra
* - Poi visita tutto ciò che si trova a destra
* - Infine visita il sestesso
*/
protected void postorder(BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
postorder(node.getLeft(), temporaryList);
postorder(node.getRight(), temporaryList);
if (node.getData() != null) temporaryList.add(node.getData());
}
public Iterator<E> iteratorPostOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
postorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE LEVEL ORDER
/*
* Qui si usa il metodo levelorder.
* Si analizza tutto il livello dell'albero.
* Per chiarire di seguito un esempio:
*
* A
* / \
* B C
* / \ \
* D E F
*
* La lettura avviene quindi in questo modo:
* A - B - C - D - E - F
*
* Si adopera una coda (Queue) di tipo FI-FO (First In - First Out)
*/
protected void levelorder(BinaryNode<E> node, List<E> temporaryList) {
Queue<BinaryNode<E>> queueOfNodes = new LinkedList<BinaryNode<E>>();
BinaryNode<E> current;
queueOfNodes.add(node);
while(!queueOfNodes.isEmpty()) {
current = queueOfNodes.remove();
if (current.getData() != null) temporaryList.add(current.getData());
if (current.getLeft() != null) queueOfNodes.add(current.getLeft());
if (current.getRight() != null) queueOfNodes.add(current.getRight());
}
}
public Iterator<E> iteratorLevelOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
levelorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE
public Iterator<E> iterator() {
return iteratorPreOrder();
}
// ITERATORE PREORDER ITERATIVO (NON RICORSIVO)
/*
* In questo caso stiamo usando un tipo stack.
* Dobbiamo di fatto simulare uno stack se vogliamo
* iterativamente fare questa cosa.
*
* Perchè se prima dobbiamo visitare il nodo centrale,
* poi il nodo a sinistra e poi il nodo a destra inseriamo
* prima quello di destra e poi quello di sinistra?
*
* Lo stack di fatto è una coda LIFO, ovvero last in - first out
* e quindi l'ultimo che entra è il primo che esce.
*
* dal momento che vale questa cosa, se facciamo entrare prima quello
* di destra e poi quello di sinistra, il primo nodo che verrà
* prelevato è ovviamente quello a sinistra.
*/
protected void itpreorder(BinaryNode<E> node, List<E> temporaryList) {
Stack<BinaryNode<E>> queueOfNodes = new Stack<BinaryNode<E>>();
BinaryNode<E> current;
queueOfNodes.add(node);
while (!queueOfNodes.isEmpty()) {
current = queueOfNodes.pop();
if (current.getData() != null) temporaryList.add(current.getData());
// Come già spiegato pushamo prima il nodo di destra
if (current.getRight() != null) queueOfNodes.push(current.getRight());
// Infine aggiungiamo il nodo di sinistra
if (current.getLeft() != null) queueOfNodes.push(current.getLeft());
}
}
public Iterator<E> iteratorInOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
itpreorder(root, temporaryList);
}
// ITERATOR
}
@@ -0,0 +1,41 @@
package parziale.p251110;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.ListIterator;
public class Clinica {
ArrayList<Paziente> pazienti = new ArrayList<Paziente>();
// 1. Numero di pazienti Ricoverati
public int pazientiRicoverati() {
return pazienti.size();
}
// 2. Inserimento del paziente
/*
* Dal momento che non ci è permesso adoperare
* TreeSet per l'ordine e per l'unicità
*/
public boolean ricoveraPaziente(Paziente paziente) {
// Se il paziente è nullo, nulla verrà aggiunto
if (paziente == null) return false;
// Controllo se il paziente è già presente nella lista ricoveri
Iterator<Paziente> it = pazienti.iterator();
while (it.hasNext()) {
Paziente current = it.next();
if (paziente.equals(current)) return false; // Se è già presente un paziente con id uguale allora non viene aggiunto e ritorna false
}
// Aggiunta del paziente
ListIterator<Paziente> it = pazienti.iterator();
while (it.hasNext()) {
Paziente current = it.next();
int cmp = current.compareTo(paziente);
if (cmp > 1)
}
}
}
@@ -0,0 +1,96 @@
package binary_tree;
public class LinkedBinaryTree<E> implements BinaryTree<E>{
// VARIABILI D'INSTANZA
private BinaryNode<E> root;
private int size;
// Metodi costruttori
public LinkedBinaryTree() {
root = null;
size = 0;
}
public LinkedBinaryTree(E data) {
root = new BinaryNode<E>(data);
size = 1;
}
public LinkedBinaryTree(LinkedBinaryTree<E> left, E data, LinkedBinaryTree<E> right) {
root = new BinaryNode<E>(left.root, data, right.root);
size = 1 + left.size + right.size;
}
// METODI
public int size() {
return size;
}
@Override
public boolean isEmpty() {
return root == null;
}
public E getRoot() {
if (isEmpty()) return null;
return root.getData();
}
public BinaryNode<E> getRootNode() {
if (isEmpty()) return null;
return root;
}
public void clear() {
root = null;
size = 0;
}
private int getSize(BinaryNode<E> node) {
if (node == null) return 0;
int nLeft = (node.getLeft() == null) ? 0 : getSize(node.getLeft());
int nRight = (node.getRight() == null) ? 0 : getSize(node.getRight());
return 1 + nLeft + nRight;
}
public LinkedBinaryTree<E> removeLeft() {
LinkedBinaryTree<E> leftTree = null;
if (root.getLeft() == null) return leftTree;
leftTree = new LinkedBinaryTree<E>();
leftTree.root = root.getLeft();
leftTree.size = getSize(root.getLeft());
leftTree.root.setAsRoot();
size = size - leftTree.size;
return leftTree;
}
public LinkedBinaryTree<E> removeRight() {
LinkedBinaryTree<E> rightTree = null;
if (root.getRight() == null) return rightTree;
rightTree = new LinkedBinaryTree<E>();
rightTree.root = root.getRight();
rightTree.size = getSize(root.getRight());
rightTree.root.setAsRoot();
size = size - rightTree.size;
return rightTree;
}
protected BinaryNode<E> find(E targetElement, BinaryNode<E> root) {
if (root == null) return null;
if (root.getData().equals(targetElement)) return root;
BinaryNode<E> resNode;
resNode = find(targetElement, root.getLeft());
if (resNode == null)
}
}
@@ -0,0 +1,132 @@
package binary_tree;
import java.util.List;
public class LinkedBinaryTree<E> implements BinaryTree<E>{
// VARIABILI D'INSTANZA
private BinaryNode<E> root;
private int size;
// Metodi costruttori
public LinkedBinaryTree() {
root = null;
size = 0;
}
public LinkedBinaryTree(E data) {
root = new BinaryNode<E>(data);
size = 1;
}
public LinkedBinaryTree(LinkedBinaryTree<E> left, E data, LinkedBinaryTree<E> right) {
root = new BinaryNode<E>(left.root, data, right.root);
size = 1 + left.size + right.size;
}
// METODI
public int size() {
return size;
}
@Override
public boolean isEmpty() {
return root == null;
}
public E getRoot() {
if (isEmpty()) return null;
return root.getData();
}
public BinaryNode<E> getRootNode() {
if (isEmpty()) return null;
return root;
}
public void clear() {
root = null;
size = 0;
}
private int getSize(BinaryNode<E> node) {
if (node == null) return 0;
int nLeft = (node.getLeft() == null) ? 0 : getSize(node.getLeft());
int nRight = (node.getRight() == null) ? 0 : getSize(node.getRight());
return 1 + nLeft + nRight;
}
public LinkedBinaryTree<E> removeLeft() {
LinkedBinaryTree<E> leftTree = null;
if (root.getLeft() == null) return leftTree;
leftTree = new LinkedBinaryTree<E>();
leftTree.root = root.getLeft();
leftTree.size = getSize(root.getLeft());
leftTree.root.setAsRoot();
size = size - leftTree.size;
return leftTree;
}
public LinkedBinaryTree<E> removeRight() {
LinkedBinaryTree<E> rightTree = null;
if (root.getRight() == null) return rightTree;
rightTree = new LinkedBinaryTree<E>();
rightTree.root = root.getRight();
rightTree.size = getSize(root.getRight());
rightTree.root.setAsRoot();
size = size - rightTree.size;
return rightTree;
}
protected BinaryNode<E> find(E targetElement, BinaryNode<E> root) {
if (root == null) return null;
if (root.getData().equals(targetElement)) return root;
BinaryNode<E> resNode;
resNode = find(targetElement, root.getLeft());
if (resNode == null) resNode = find(targetElement, root.getRight());
return resNode;
}
public boolean remove(E targetElement) {
if (targetElement == null) return false;
BinaryNode<E> temp = find(targetElement, root);
if (temp != null) {
temp.setData(null);
return true;
}
return false;
}
public boolean contains(E targetElement) {
return find(targetElement, root) != null;
}
// ITERATORE PREORDER
/*
* Qui si utilizza il metodo del preorder.
* Le regole per il preorder sono queste:
* - Visita prima se stesso
* - Poi visita tutto ciò che si trova sinistra
* - Infine visita tutto ciò che si trova a destra
*/
protected void preorder (BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
if (node.getData() != null) temporaryList.add(node.getData());
preorder(node.getLeft(), temporaryList);
preorder(node.getRight(), temporaryList);
}
}
@@ -0,0 +1,494 @@
package binary_tree;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Stack;
public class LinkedBinaryTree<E> implements BinaryTree<E>{
// VARIABILI D'INSTANZA
private BinaryNode<E> root;
private int size;
// Metodi costruttori
public LinkedBinaryTree() {
root = null;
size = 0;
}
public LinkedBinaryTree(E data) {
root = new BinaryNode<E>(data);
size = 1;
}
public LinkedBinaryTree(LinkedBinaryTree<E> left, E data, LinkedBinaryTree<E> right) {
root = new BinaryNode<E>(left.root, data, right.root);
size = 1 + left.size + right.size;
}
// METODI
public int size() {
return size;
}
@Override
public boolean isEmpty() {
return root == null;
}
public E getRoot() {
if (isEmpty()) return null;
return root.getData();
}
public BinaryNode<E> getRootNode() {
if (isEmpty()) return null;
return root;
}
public void clear() {
root = null;
size = 0;
}
private int getSize(BinaryNode<E> node) {
if (node == null) return 0;
int nLeft = (node.getLeft() == null) ? 0 : getSize(node.getLeft());
int nRight = (node.getRight() == null) ? 0 : getSize(node.getRight());
return 1 + nLeft + nRight;
}
public LinkedBinaryTree<E> removeLeft() {
LinkedBinaryTree<E> leftTree = null;
if (root.getLeft() == null) return leftTree;
leftTree = new LinkedBinaryTree<E>();
leftTree.root = root.getLeft();
leftTree.size = getSize(root.getLeft());
leftTree.root.setAsRoot();
size = size - leftTree.size;
return leftTree;
}
public LinkedBinaryTree<E> removeRight() {
LinkedBinaryTree<E> rightTree = null;
if (root.getRight() == null) return rightTree;
rightTree = new LinkedBinaryTree<E>();
rightTree.root = root.getRight();
rightTree.size = getSize(root.getRight());
rightTree.root.setAsRoot();
size = size - rightTree.size;
return rightTree;
}
protected BinaryNode<E> find(E targetElement, BinaryNode<E> root) {
if (root == null) return null;
if (root.getData().equals(targetElement)) return root;
BinaryNode<E> resNode;
resNode = find(targetElement, root.getLeft());
if (resNode == null) resNode = find(targetElement, root.getRight());
return resNode;
}
public boolean remove(E targetElement) {
if (targetElement == null) return false;
BinaryNode<E> temp = find(targetElement, root);
if (temp != null) {
temp.setData(null);
return true;
}
return false;
}
public boolean contains(E targetElement) {
return find(targetElement, root) != null;
}
// ITERATORE PREORDER
/*
* Qui si utilizza il metodo del preorder.
* Le regole per il preorder sono queste:
* - Visita prima se stesso
* - Poi visita tutto ciò che si trova sinistra
* - Infine visita tutto ciò che si trova a destra
*/
protected void preorder (BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
if (node.getData() != null) temporaryList.add(node.getData());
preorder(node.getLeft(), temporaryList);
preorder(node.getRight(), temporaryList);
}
public Iterator<E> iteratorPreOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
preorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE INORDER
/*
* Qui si utilizza il metodo del inorder.
* Le regole per l'inorder sono queste:
* - Visita prima tutto ciò che si trova a sinistra
* - Poi visita se stesso
* - Infine visita tutto ciò che si trova a destra
*/
protected void inorder(BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
inorder(node.getLeft(), temporaryList);
if (node.getData() != null) temporaryList.add(node.getData());
inorder(node.getRight(), temporaryList);
}
public Iterator<E> iteratorInOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
inorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE POSTORDER
/*
* Qui si utilizza il metodo postorder.
* Le regole per il postorder sono queste:
* - Visita prima di tutto ciò che si trova a sinistra
* - Poi visita tutto ciò che si trova a destra
* - Infine visita il sestesso
*/
protected void postorder(BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
postorder(node.getLeft(), temporaryList);
postorder(node.getRight(), temporaryList);
if (node.getData() != null) temporaryList.add(node.getData());
}
public Iterator<E> iteratorPostOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
postorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE LEVEL ORDER
/*
* Qui si usa il metodo levelorder.
* Si analizza tutto il livello dell'albero.
* Per chiarire di seguito un esempio:
*
* A
* / \
* B C
* / \ \
* D E F
*
* La lettura avviene quindi in questo modo:
* A - B - C - D - E - F
*
* Si adopera una coda (Queue) di tipo FI-FO (First In - First Out)
*/
protected void levelorder(BinaryNode<E> node, List<E> temporaryList) {
Queue<BinaryNode<E>> queueOfNodes = new LinkedList<BinaryNode<E>>();
BinaryNode<E> current;
queueOfNodes.add(node);
while(!queueOfNodes.isEmpty()) {
current = queueOfNodes.remove();
if (current.getData() != null) temporaryList.add(current.getData());
if (current.getLeft() != null) queueOfNodes.add(current.getLeft());
if (current.getRight() != null) queueOfNodes.add(current.getRight());
}
}
public Iterator<E> iteratorLevelOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
levelorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE
public Iterator<E> iterator() {
return iteratorPreOrder();
}
// ITERATORE PREORDER ITERATIVO (NON RICORSIVO)
/*
* In questo caso stiamo usando un tipo stack.
* Dobbiamo di fatto simulare uno stack se vogliamo
* iterativamente fare questa cosa.
*
* Perchè se prima dobbiamo visitare il nodo centrale,
* poi il nodo a sinistra e poi il nodo a destra inseriamo
* prima quello di destra e poi quello di sinistra?
*
* Lo stack di fatto è una coda LIFO, ovvero last in - first out
* e quindi l'ultimo che entra è il primo che esce.
*
* dal momento che vale questa cosa, se facciamo entrare prima quello
* di destra e poi quello di sinistra, il primo nodo che verrà
* prelevato è ovviamente quello a sinistra.
*/
protected void itpreorder (BinaryNode<E> node, List<E> temporaryList) {
Stack<BinaryNode<E>> queueOfNodes = new Stack<BinaryNode<E>>();
BinaryNode<E> current;
queueOfNodes.add(node);
while (!queueOfNodes.isEmpty()) {
current = queueOfNodes.pop();
if (current.getData() != null) temporaryList.add(current.getData());
// Come già spiegato pushamo prima il nodo di destra
if (current.getRight() != null) queueOfNodes.push(current.getRight());
// Infine aggiungiamo il nodo di sinistra
if (current.getLeft() != null) queueOfNodes.push(current.getLeft());
}
}
public Iterator<E> ititeratorPreOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
itpreorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATOR INORDER ITERATIVO (NON RICORSIVO)
/*
* Questo metodo riguarda lo stesso di quello superiore.
* Il metodo inorder richiede che si visiti prima sinistra,
* poi il nodo stesso, infine il nodo di destra.
*
* Possiamo quindi sempre adoperare uno Stack per siumlare la
* ricorsione.
*
* Come detto prima, se il primo nodo ad essere prelevato è
* l'ultimo che si inserisce (coda LIFO, Stack) allora per simulare
* sinistra -> centro -> destra.
*
* Nel metodo sono state inserite delle check con uno stack di
* flag che permette di capire quando il nodo centrale è visitare
* oppure no.
*/
private void itinorder(BinaryNode<E> node, List<E> temporaryList) {
Stack<BinaryNode<E>> queueOfNodes = new Stack<BinaryNode<E>>();
Stack<Boolean> flags = new Stack<Boolean>();
BinaryNode<E> current;
Boolean flag;
queueOfNodes.add(node);
flags.push(false);
while (!queueOfNodes.isEmpty()) {
current = queueOfNodes.pop();
flag = flags.pop();
if (flag) {
// il nodo è da visitare
if (current.getData() != null) temporaryList.add(current.getData());
} else {
// il nodo non è da visitare
// prima si aggiunge il nodo di destra
if (current.getRight() != null) {
queueOfNodes.add(current.getRight());
flags.add(false);
}
queueOfNodes.push(current);
flags.push(true);
if (current.getLeft() != null) {
queueOfNodes.add(current.getLeft());
flags.push(false);
}
}
}
}
public Iterator<E> ititeratorInOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
itinorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATOR POST ORDER ITERATIVO (NON RICORSIVO)
/*
* In questo caso la logica è la seguente. si ha la
* necessità di fare il seguente ciclo: SINISTRA -> DESTRA -> NODO CORRENTE
*
* Per simulare lo stack dobbiamo quindi ripercorrerlo al contrario,
* dunque NODO CORRENTE -> DESTRA -> SINISTRA
*
* Possiamo dunque rifare lo stesso, di ciò che abbiamo fatto sopra.
*/
protected void itpostorder(BinaryNode<E> node, List<E> temporaryList) {
Stack<BinaryNode<E>> queueOfNodes = new Stack<BinaryNode<E>>();
Stack<Boolean> flags = new Stack<Boolean>();
BinaryNode<E> current;
Boolean flag;
queueOfNodes.push(node);
flags.push(false);
while (!queueOfNodes.isEmpty()) {
current = queueOfNodes.pop();
flag = flags.pop();
if (flag) {
// il nodo è da visitare
if (current.getData() != null) temporaryList.add(current.getData());
} else {
// il nodo non è ancora da visitare
// Visitiamo il nodo corrente
queueOfNodes.push(current);
flags.push(true);
// visitiamo il nodo di destra
if (current.getRight() != null) {
queueOfNodes.push(current.getRight());
flags.push(false);
}
// visitiamo il nodo di sinistra infine
if (current.getLeft() != null) {
queueOfNodes.push(current.getLeft());
flags.push(false);
}
}
}
}
public Iterator<E> ititeratorPostOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
itpostorder(root, temporaryList);
return temporaryList.iterator();
}
/*
* II parziale 2022/2023
* Realizzare un metodo costruttore della classe LinkedBinaryTree<E> che
* prende in input una lista di oggetti di tipo E e costruisce una catena
* casuale tale che l'iesimo elemento della lista è posizionato al livello iesimo
* della catena e ogni nodo ha probabilità 1/2 di avere un figlio sinistro/destro.
*/
/*
* Spiegazione intuitiva (visto che la melideo intende complicare la consegna):
* Data ad esempio una lista del genere:
* [A, B, C, D]
*
* Si ottiene quindi una catena del genere:
* A
* \
* B
* /
* C
* \
* D
*/
public LinkedBinaryTree(List<E> objectList) {
if (objectList == null) throw new NullPointerException();
Iterator<E> iterator = objectList.iterator();
if (!iterator.hasNext()) return;
E currentObject = iterator.next();
root = new BinaryNode<E>(currentObject);
BinaryNode<E> currentNode = root;
currentNode.setData(currentObject);
size = 1;
while (iterator.hasNext()) {
currentObject = iterator.next();
int wing = (int) (Math.random() * 2);
BinaryNode<E> newNode = new BinaryNode<E>(currentObject);
if (wing == 0) {
// Left
newNode.setParentAsLeftChild(currentNode);
} else {
// Right
newNode.setParentAsRightChild(currentNode);
}
currentNode = newNode;
size++;
}
}
/*
* II parziale 2022
* Si aggiunga alla classe LinkedBinaryTree<E> un metodo
* che stampa le foglie dall'albero corrente (da sinistra verso destra)
*/
public void printLeaf() {
printLeaf(root);
}
public void printLeaf(BinaryNode<E> node) {
if (node == null) return;
if (node.getLeft() == null && node.getRight() == null) System.out.println(node.getData().toString());
else {
printLeaf(node.getLeft());
printLeaf(node.getRight());
}
}
/*
* Si aggiunga alla classe LinkedBinaryTree<E> un metodo che conta il numero
* di foglie dell'albero corrente
*/
public int numberLeaf() {
return numberLeaf(root);
}
public int numberLeaf(BinaryNode<E> node) {
if (node == null) return 0;
if (node.getLeft() == null && node.getRight() == null) return 1;
int nLeft = (node.getLeft() == null) ? 0 : numberLeaf(node.getLeft());
int nRight = (node.getRight() == null) ? 0 : numberLeaf(node.getRight());
return nLeft + nRight;
}
/*
* Si aggiunga alla classe LinkedBinaryTree<E> un metodo che trasforma l'albero corrente
* in modo che ogni suo nodo interno abbia esattamente due figli. Se un nodo ha solo un
* figlio, si aggiunga l'altro nodo figlio come copia del figlio esistente
*/
}
@@ -0,0 +1,14 @@
package jcf_set.example;
public class TreeSetExample2 {
public static void main(String[] Args) {
}
public void run() {
TreeSet<String> tree1 = new TreeSet<String>();
}
}
@@ -0,0 +1,60 @@
package binary_tree;
public class BinaryNode<E> {
// VARIABILI
private BinaryNode<E> left, right, parent;
private E data;
// COSTRUTTORI
public BinaryNode(E data) {
this.data = data;
left = right = parent = null;
}
public BinaryNode(BinaryNode<E> left, E data, BinaryNode<E> right) {
this.data = data;
this.left = left;
this.right = right;
this.parent = null;
if (this.left != null) this.left.parent = this;
if (this.right != null) this.right.parent = this;
}
// METODI
public E getData() {
return data;
}
public BinaryNode<E> getLeft() {
return left;
}
public BinaryNode<E> getRight() {
return right;
}
public BinaryNode<E> getParent() {
return parent;
}
public boolean isRoot() {
return parent == null;
}
public boolean isLeftChild() {
return parent != null && parent.getLeft() == this;
}
public boolean isRightChild() {
return parent != null && parent.getRight() == this;
}
}
@@ -0,0 +1,25 @@
package stack;
public class StackExample {
public static void main(String[] Args) {
MyStack<Character> stack = new ArrayListStack<Character>();
Character a = 'a';
Character b = 'b';
Character c = 'c';
Character d = 'd';
stack.push(a);
stack.push(b);
stack.push(c);
stack.push(d);
// Svuotiamo lo stack
for (int i = 0; i < stack.size(); i++) {
}
}
}
@@ -0,0 +1,121 @@
package binary_tree;
public class BinaryNode<E> {
// VARIABILI
private BinaryNode<E> left, right, parent;
private E data;
// COSTRUTTORI
public BinaryNode(E data) {
this.data = data;
left = right = parent = null;
}
public BinaryNode(BinaryNode<E> left, E data, BinaryNode<E> right) {
this.data = data;
this.left = left;
this.right = right;
this.parent = null;
if (this.left != null) this.left.parent = this;
if (this.right != null) this.right.parent = this;
}
// METODI
public E getData() {
return data;
}
public BinaryNode<E> getLeft() {
return left;
}
public BinaryNode<E> getRight() {
return right;
}
public BinaryNode<E> getParent() {
return parent;
}
public boolean isRoot() {
return parent == null;
}
public boolean isLeftChild() {
return parent != null && parent.getLeft() == this;
}
public boolean isRightChild() {
return parent != null && parent.getRight() == this;
}
public void setData(E data) {
this.data = data;
}
public void setLeft(BinaryNode<E> left) {
this.left = left;
if (this.left != null) this.left.parent = this;
}
public void setRight(BinaryNode<E> right) {
this.right = right;
if (this.right != null) this.right.parent = this;
}
public BinaryNode<E> setParentAsLeftChild(BinaryNode<E> parent) {
if (parent == null) return null;
this.parent = parent;
BinaryNode<E> oldLeft = this.parent.left;
this.parent.left = this;
return oldLeft;
}
public BinaryNode<E> setParentAsRightChild(BinaryNode<E> parent) {
if (parent == null) return null;
this.parent = parent;
BinaryNode<E> oldRight = this.parent.right;
this.parent.right = this;
return oldRight;
}
public BinaryNode<E> setAsRoot() {
if (parent == null) return null;
BinaryNode<E> oldParent = parent;
parent = null;
if (oldParent.left == this) oldParent.left = null;
else oldParent.right = null;
return oldParent;
}
public boolean hasLeft() {
return left != null;
}
public boolean hasRight() {
return right != null;
}
@Override
public boolean equals(Object other) {
if (other == null) return false;
if (other == this) return true;
if (!(other instanceof BinaryNode<?>))
}
}
@@ -0,0 +1,193 @@
package binary_tree;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class LinkedBinaryTree<E> implements BinaryTree<E>{
// VARIABILI D'INSTANZA
private BinaryNode<E> root;
private int size;
// Metodi costruttori
public LinkedBinaryTree() {
root = null;
size = 0;
}
public LinkedBinaryTree(E data) {
root = new BinaryNode<E>(data);
size = 1;
}
public LinkedBinaryTree(LinkedBinaryTree<E> left, E data, LinkedBinaryTree<E> right) {
root = new BinaryNode<E>(left.root, data, right.root);
size = 1 + left.size + right.size;
}
// METODI
public int size() {
return size;
}
@Override
public boolean isEmpty() {
return root == null;
}
public E getRoot() {
if (isEmpty()) return null;
return root.getData();
}
public BinaryNode<E> getRootNode() {
if (isEmpty()) return null;
return root;
}
public void clear() {
root = null;
size = 0;
}
private int getSize(BinaryNode<E> node) {
if (node == null) return 0;
int nLeft = (node.getLeft() == null) ? 0 : getSize(node.getLeft());
int nRight = (node.getRight() == null) ? 0 : getSize(node.getRight());
return 1 + nLeft + nRight;
}
public LinkedBinaryTree<E> removeLeft() {
LinkedBinaryTree<E> leftTree = null;
if (root.getLeft() == null) return leftTree;
leftTree = new LinkedBinaryTree<E>();
leftTree.root = root.getLeft();
leftTree.size = getSize(root.getLeft());
leftTree.root.setAsRoot();
size = size - leftTree.size;
return leftTree;
}
public LinkedBinaryTree<E> removeRight() {
LinkedBinaryTree<E> rightTree = null;
if (root.getRight() == null) return rightTree;
rightTree = new LinkedBinaryTree<E>();
rightTree.root = root.getRight();
rightTree.size = getSize(root.getRight());
rightTree.root.setAsRoot();
size = size - rightTree.size;
return rightTree;
}
protected BinaryNode<E> find(E targetElement, BinaryNode<E> root) {
if (root == null) return null;
if (root.getData().equals(targetElement)) return root;
BinaryNode<E> resNode;
resNode = find(targetElement, root.getLeft());
if (resNode == null) resNode = find(targetElement, root.getRight());
return resNode;
}
public boolean remove(E targetElement) {
if (targetElement == null) return false;
BinaryNode<E> temp = find(targetElement, root);
if (temp != null) {
temp.setData(null);
return true;
}
return false;
}
public boolean contains(E targetElement) {
return find(targetElement, root) != null;
}
// ITERATORE PREORDER
/*
* Qui si utilizza il metodo del preorder.
* Le regole per il preorder sono queste:
* - Visita prima se stesso
* - Poi visita tutto ciò che si trova sinistra
* - Infine visita tutto ciò che si trova a destra
*/
protected void preorder (BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
if (node.getData() != null) temporaryList.add(node.getData());
preorder(node.getLeft(), temporaryList);
preorder(node.getRight(), temporaryList);
}
public Iterator<E> iteratorPreOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
preorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE INORDER
/*
* Qui si utilizza il metodo del inorder.
* Le regole per l'inorder sono queste:
* - Visita prima tutto ciò che si trova a sinistra
* - Poi visita se stesso
* - Infine visita tutto ciò che si trova a destra
*/
protected void inorder(BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
inorder(node.getLeft(), temporaryList);
if (node.getData() != null) temporaryList.add(node.getData());
inorder(node.getRight(), temporaryList);
}
public Iterator<E> iteratorInOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
inorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE POSTORDER
/*
* Qui si utilizza il metodo postorder.
* Le regole per il postorder sono queste:
* - Visita prima di tutto ciò che si trova a sinistra
* - Poi visita tutto ciò che si trova a destra
* - Infine visita il sestesso
*/
protected void postorder(BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
postorder(node.getLeft(), temporaryList);
postorder(node.getRight(), temporaryList);
if (node.getData() != null) temporaryList.add(node.getData());
}
public Iterator<E> iteratorPostOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
postorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE LEVEL ORDER
}
@@ -0,0 +1,101 @@
package binary_tree;
public class LinkedBinaryTree<E> implements BinaryTree<E>{
// VARIABILI D'INSTANZA
private BinaryNode<E> root;
private int size;
// Metodi costruttori
public LinkedBinaryTree() {
root = null;
size = 0;
}
public LinkedBinaryTree(E data) {
root = new BinaryNode<E>(data);
size = 1;
}
public LinkedBinaryTree(LinkedBinaryTree<E> left, E data, LinkedBinaryTree<E> right) {
root = new BinaryNode<E>(left.root, data, right.root);
size = 1 + left.size + right.size;
}
// METODI
public int size() {
return size;
}
@Override
public boolean isEmpty() {
return root == null;
}
public E getRoot() {
if (isEmpty()) return null;
return root.getData();
}
public BinaryNode<E> getRootNode() {
if (isEmpty()) return null;
return root;
}
public void clear() {
root = null;
size = 0;
}
private int getSize(BinaryNode<E> node) {
if (node == null) return 0;
int nLeft = (node.getLeft() == null) ? 0 : getSize(node.getLeft());
int nRight = (node.getRight() == null) ? 0 : getSize(node.getRight());
return 1 + nLeft + nRight;
}
public LinkedBinaryTree<E> removeLeft() {
LinkedBinaryTree<E> leftTree = null;
if (root.getLeft() == null) return leftTree;
leftTree = new LinkedBinaryTree<E>();
leftTree.root = root.getLeft();
leftTree.size = getSize(root.getLeft());
leftTree.root.setAsRoot();
size = size - leftTree.size;
return leftTree;
}
public LinkedBinaryTree<E> removeRight() {
LinkedBinaryTree<E> rightTree = null;
if (root.getRight() == null) return rightTree;
rightTree = new LinkedBinaryTree<E>();
rightTree.root = root.getRight();
rightTree.size = getSize(root.getRight());
rightTree.root.setAsRoot();
size = size - rightTree.size;
return rightTree;
}
protected BinaryNode<E> find(E targetElement, BinaryNode<E> root) {
if (root == null) return null;
if (root.getData().equals(targetElement)) return root;
BinaryNode<E> resNode;
resNode = find(targetElement, root.getLeft());
if (resNode == null) resNode = find(targetElement, root.getRight());
return resNode;
}
public boolean remove(E targetElement) {
if (targetElement == null) return false;
}
}
@@ -0,0 +1,94 @@
package binary_tree;
public class LinkedBinaryTree<E> implements BinaryTree<E>{
// VARIABILI D'INSTANZA
private BinaryNode<E> root;
private int size;
// Metodi costruttori
public LinkedBinaryTree() {
root = null;
size = 0;
}
public LinkedBinaryTree(E data) {
root = new BinaryNode<E>(data);
size = 1;
}
public LinkedBinaryTree(LinkedBinaryTree<E> left, E data, LinkedBinaryTree<E> right) {
root = new BinaryNode<E>(left.root, data, right.root);
size = 1 + left.size + right.size;
}
// METODI
public int size() {
return size;
}
@Override
public boolean isEmpty() {
return root == null;
}
public E getRoot() {
if (isEmpty()) return null;
return root.getData();
}
public BinaryNode<E> getRootNode() {
if (isEmpty()) return null;
return root;
}
public void clear() {
root = null;
size = 0;
}
private int getSize(BinaryNode<E> node) {
if (node == null) return 0;
int nLeft = (node.getLeft() == null) ? 0 : getSize(node.getLeft());
int nRight = (node.getRight() == null) ? 0 : getSize(node.getRight());
return 1 + nLeft + nRight;
}
public LinkedBinaryTree<E> removeLeft() {
LinkedBinaryTree<E> leftTree = null;
if (root.getLeft() == null) return leftTree;
leftTree = new LinkedBinaryTree<E>();
leftTree.root = root.getLeft();
leftTree.size = getSize(root.getLeft());
leftTree.root.setAsRoot();
size = size - leftTree.size;
return leftTree;
}
public LinkedBinaryTree<E> removeRight() {
LinkedBinaryTree<E> rightTree = null;
if (root.getRight() == null) return rightTree;
rightTree = new LinkedBinaryTree<E>();
rightTree.root = root.getRight();
rightTree.size = getSize(root.getRight());
rightTree.root.setAsRoot();
size = size - rightTree.size;
return rightTree;
}
protected BinaryNode<E> find(E targetElement, BinaryNode<E> root) {
if (root == null) return null;
if (root.getData().equals(targetElement)) return root;
BinaryNode<E> resNode;
}
}
@@ -0,0 +1,48 @@
package binary_tree;
import java.util.Iterator;
public class ExerciseBinaryTree {
/*
* Esercizio 1 II parziale 10.01.2018
* Un albero binario di interi si dice pari se tutti i nodi contengono
* un intero positivo pari. Realizzare il metodo statico
* public static boolean IsEvenBtree (BinaryTree<Integer> btree)
* che verifica se l'albero binario dato btree e' pari.
*/
/*
* Spiegazione, in questo caso, non stiamo operando direttamente
* dall'interno dell'albero, quindi possiamo sfruttare gli iteratori.
* Essendo che dobbiamo per forza verificare tutit i vari nodi possiamo
* adoperare qualsiasi tipo di iteratore.
*/
public static boolean isEvenBtree(BinaryTree<Integer> btree) {
boolean even = true;
Iterator<Integer> iterator = btree.iteratorInOrder();
while (iterator.hasNext() && even) {
Integer current = iterator.next();
if ((current <= 0) || !(current % 2 == 0)) even = false;
}
return even;
}
/*
* Esercizio 2
* Realizzare il metodo statico public static Integer MaxValue(BinaryTree<Integer> btree)
* che restituisce il riferimento all'oggetto intero più grande
* contenuto in btree.
*/
/*
* Spiegazione, in questo caso, è necessario e sufficiente iterare tutti gli elementi per
* verificare il maggiore. Non essendoci un vero ordinamento sull'albero siamo obbligati a
* iterare tutti i nodi.
*/
public static Integer maxValue(BinaryTree<Integer> btree) {
Iterator<Integer> iterator = btree.iteratorInOrder();
Integer maxValue;
}
}
@@ -0,0 +1,31 @@
package binary_tree;
public class LinkedBinaryTree<E> implements BinaryTree<E>{
// VARIABILI D'INSTANZA
private BinaryNode<E> root;
private int size;
// Metodi costruttori
public LinkedBinaryTree() {
root = null;
size = 0;
}
public LinkedBinaryTree(E data) {
root = new BinaryNode<E>(data);
size = 1;
}
public LinkedBinaryTree(LinkedBinaryTree<E> left, E data, LinkedBinaryTree<E> right) {
}
// METODI
@Override
public boolean isEmpty() {
}
}
@@ -0,0 +1,31 @@
package binary_tree;
import java.util.Iterator;
public class ExerciseBinaryTree {
/*
* Esercizio 1 II parziale 10.01.2018
* Un albero binario di interi si dice pari se tutti i nodi contengono
* un intero positivo pari. Realizzare il metodo statico
* public static boolean IsEvenBtree (BinaryTree<Integer> btree)
* che verifica se l'albero binario dato btree e' pari.
*/
/*
* Spiegazione, in questo caso, non stiamo operando direttamente
* dall'interno dell'albero, quindi possiamo sfruttare gli iteratori.
* Essendo che dobbiamo per forza verificare tutit i vari nodi possiamo
* adoperare qualsiasi tipo di iteratore.
*/
public static boolean isEvenBtree(BinaryTree<Integer> btree) {
boolean even = true;
Iterator<Integer> iterator = btree.iteratorInOrder();
while (iterator.hasNext() && even) {
Integer current = iterator.next();
if (!(current % 2 == 0)) even = false;
}
return even;
}
}
@@ -0,0 +1,5 @@
package stack;
public class StackExample {
}
@@ -0,0 +1,432 @@
package binary_tree;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Stack;
public class LinkedBinaryTree<E> implements BinaryTree<E>{
// VARIABILI D'INSTANZA
private BinaryNode<E> root;
private int size;
// Metodi costruttori
public LinkedBinaryTree() {
root = null;
size = 0;
}
public LinkedBinaryTree(E data) {
root = new BinaryNode<E>(data);
size = 1;
}
public LinkedBinaryTree(LinkedBinaryTree<E> left, E data, LinkedBinaryTree<E> right) {
root = new BinaryNode<E>(left.root, data, right.root);
size = 1 + left.size + right.size;
}
// METODI
public int size() {
return size;
}
@Override
public boolean isEmpty() {
return root == null;
}
public E getRoot() {
if (isEmpty()) return null;
return root.getData();
}
public BinaryNode<E> getRootNode() {
if (isEmpty()) return null;
return root;
}
public void clear() {
root = null;
size = 0;
}
private int getSize(BinaryNode<E> node) {
if (node == null) return 0;
int nLeft = (node.getLeft() == null) ? 0 : getSize(node.getLeft());
int nRight = (node.getRight() == null) ? 0 : getSize(node.getRight());
return 1 + nLeft + nRight;
}
public LinkedBinaryTree<E> removeLeft() {
LinkedBinaryTree<E> leftTree = null;
if (root.getLeft() == null) return leftTree;
leftTree = new LinkedBinaryTree<E>();
leftTree.root = root.getLeft();
leftTree.size = getSize(root.getLeft());
leftTree.root.setAsRoot();
size = size - leftTree.size;
return leftTree;
}
public LinkedBinaryTree<E> removeRight() {
LinkedBinaryTree<E> rightTree = null;
if (root.getRight() == null) return rightTree;
rightTree = new LinkedBinaryTree<E>();
rightTree.root = root.getRight();
rightTree.size = getSize(root.getRight());
rightTree.root.setAsRoot();
size = size - rightTree.size;
return rightTree;
}
protected BinaryNode<E> find(E targetElement, BinaryNode<E> root) {
if (root == null) return null;
if (root.getData().equals(targetElement)) return root;
BinaryNode<E> resNode;
resNode = find(targetElement, root.getLeft());
if (resNode == null) resNode = find(targetElement, root.getRight());
return resNode;
}
public boolean remove(E targetElement) {
if (targetElement == null) return false;
BinaryNode<E> temp = find(targetElement, root);
if (temp != null) {
temp.setData(null);
return true;
}
return false;
}
public boolean contains(E targetElement) {
return find(targetElement, root) != null;
}
// ITERATORE PREORDER
/*
* Qui si utilizza il metodo del preorder.
* Le regole per il preorder sono queste:
* - Visita prima se stesso
* - Poi visita tutto ciò che si trova sinistra
* - Infine visita tutto ciò che si trova a destra
*/
protected void preorder (BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
if (node.getData() != null) temporaryList.add(node.getData());
preorder(node.getLeft(), temporaryList);
preorder(node.getRight(), temporaryList);
}
public Iterator<E> iteratorPreOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
preorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE INORDER
/*
* Qui si utilizza il metodo del inorder.
* Le regole per l'inorder sono queste:
* - Visita prima tutto ciò che si trova a sinistra
* - Poi visita se stesso
* - Infine visita tutto ciò che si trova a destra
*/
protected void inorder(BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
inorder(node.getLeft(), temporaryList);
if (node.getData() != null) temporaryList.add(node.getData());
inorder(node.getRight(), temporaryList);
}
public Iterator<E> iteratorInOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
inorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE POSTORDER
/*
* Qui si utilizza il metodo postorder.
* Le regole per il postorder sono queste:
* - Visita prima di tutto ciò che si trova a sinistra
* - Poi visita tutto ciò che si trova a destra
* - Infine visita il sestesso
*/
protected void postorder(BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
postorder(node.getLeft(), temporaryList);
postorder(node.getRight(), temporaryList);
if (node.getData() != null) temporaryList.add(node.getData());
}
public Iterator<E> iteratorPostOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
postorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE LEVEL ORDER
/*
* Qui si usa il metodo levelorder.
* Si analizza tutto il livello dell'albero.
* Per chiarire di seguito un esempio:
*
* A
* / \
* B C
* / \ \
* D E F
*
* La lettura avviene quindi in questo modo:
* A - B - C - D - E - F
*
* Si adopera una coda (Queue) di tipo FI-FO (First In - First Out)
*/
protected void levelorder(BinaryNode<E> node, List<E> temporaryList) {
Queue<BinaryNode<E>> queueOfNodes = new LinkedList<BinaryNode<E>>();
BinaryNode<E> current;
queueOfNodes.add(node);
while(!queueOfNodes.isEmpty()) {
current = queueOfNodes.remove();
if (current.getData() != null) temporaryList.add(current.getData());
if (current.getLeft() != null) queueOfNodes.add(current.getLeft());
if (current.getRight() != null) queueOfNodes.add(current.getRight());
}
}
public Iterator<E> iteratorLevelOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
levelorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE
public Iterator<E> iterator() {
return iteratorPreOrder();
}
// ITERATORE PREORDER ITERATIVO (NON RICORSIVO)
/*
* In questo caso stiamo usando un tipo stack.
* Dobbiamo di fatto simulare uno stack se vogliamo
* iterativamente fare questa cosa.
*
* Perchè se prima dobbiamo visitare il nodo centrale,
* poi il nodo a sinistra e poi il nodo a destra inseriamo
* prima quello di destra e poi quello di sinistra?
*
* Lo stack di fatto è una coda LIFO, ovvero last in - first out
* e quindi l'ultimo che entra è il primo che esce.
*
* dal momento che vale questa cosa, se facciamo entrare prima quello
* di destra e poi quello di sinistra, il primo nodo che verrà
* prelevato è ovviamente quello a sinistra.
*/
protected void itpreorder (BinaryNode<E> node, List<E> temporaryList) {
Stack<BinaryNode<E>> queueOfNodes = new Stack<BinaryNode<E>>();
BinaryNode<E> current;
queueOfNodes.add(node);
while (!queueOfNodes.isEmpty()) {
current = queueOfNodes.pop();
if (current.getData() != null) temporaryList.add(current.getData());
// Come già spiegato pushamo prima il nodo di destra
if (current.getRight() != null) queueOfNodes.push(current.getRight());
// Infine aggiungiamo il nodo di sinistra
if (current.getLeft() != null) queueOfNodes.push(current.getLeft());
}
}
public Iterator<E> ititeratorPreOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
itpreorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATOR INORDER ITERATIVO (NON RICORSIVO)
/*
* Questo metodo riguarda lo stesso di quello superiore.
* Il metodo inorder richiede che si visiti prima sinistra,
* poi il nodo stesso, infine il nodo di destra.
*
* Possiamo quindi sempre adoperare uno Stack per siumlare la
* ricorsione.
*
* Come detto prima, se il primo nodo ad essere prelevato è
* l'ultimo che si inserisce (coda LIFO, Stack) allora per simulare
* sinistra -> centro -> destra.
*
* Nel metodo sono state inserite delle check con uno stack di
* flag che permette di capire quando il nodo centrale è visitare
* oppure no.
*/
private void itinorder(BinaryNode<E> node, List<E> temporaryList) {
Stack<BinaryNode<E>> queueOfNodes = new Stack<BinaryNode<E>>();
Stack<Boolean> flags = new Stack<Boolean>();
BinaryNode<E> current;
Boolean flag;
queueOfNodes.add(node);
flags.push(false);
while (!queueOfNodes.isEmpty()) {
current = queueOfNodes.pop();
flag = flags.pop();
if (flag) {
// il nodo è da visitare
if (current.getData() != null) temporaryList.add(current.getData());
} else {
// il nodo non è da visitare
// prima si aggiunge il nodo di destra
if (current.getRight() != null) {
queueOfNodes.add(current.getRight());
flags.add(false);
}
queueOfNodes.push(current);
flags.push(true);
if (current.getLeft() != null) {
queueOfNodes.add(current.getLeft());
flags.push(false);
}
}
}
}
public Iterator<E> ititeratorInOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
itinorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATOR POST ORDER ITERATIVO (NON RICORSIVO)
/*
* In questo caso la logica è la seguente. si ha la
* necessità di fare il seguente ciclo: SINISTRA -> DESTRA -> NODO CORRENTE
*
* Per simulare lo stack dobbiamo quindi ripercorrerlo al contrario,
* dunque NODO CORRENTE -> DESTRA -> SINISTRA
*
* Possiamo dunque rifare lo stesso, di ciò che abbiamo fatto sopra.
*/
protected void itpostorder(BinaryNode<E> node, List<E> temporaryList) {
Stack<BinaryNode<E>> queueOfNodes = new Stack<BinaryNode<E>>();
Stack<Boolean> flags = new Stack<Boolean>();
BinaryNode<E> current;
Boolean flag;
queueOfNodes.push(node);
flags.push(false);
while (!queueOfNodes.isEmpty()) {
current = queueOfNodes.pop();
flag = flags.pop();
if (flag) {
// il nodo è da visitare
if (current.getData() != null) temporaryList.add(current.getData());
} else {
// il nodo non è ancora da visitare
// Visitiamo il nodo corrente
queueOfNodes.push(current);
flags.push(true);
// visitiamo il nodo di destra
if (current.getRight() != null) {
queueOfNodes.push(current.getRight());
flags.push(false);
}
// visitiamo il nodo di sinistra infine
if (current.getLeft() != null) {
queueOfNodes.push(current.getLeft());
flags.push(false);
}
}
}
}
public Iterator<E> ititeratorPostOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
itpostorder(root, temporaryList);
return temporaryList.iterator();
}
/*
* II parziale 2022/2023
* Realizzare un metodo costruttore della classe LinkedBinaryTree<E> che
* prende in input una lista di oggetti di tipo E e costruisce una catena
* casuale tale che l'iesimo elemento della lista è posizionato al livello iesimo
* della catena e ogni nodo ha probabilità 1/2 di avere un figlio sinistro/destro.
*/
/*
* Spiegazione intuitiva (visto che la melideo intende complicare la consegna):
* Data ad esempio una lista del genere:
* [A, B, C, D]
*
* Si ottiene quindi una catena del genere:
* A
* \
* B
* /
* C
* \
* D
*/
public LinkedBinaryTree(List<E> objectList) {
if (objectList == null) throw new NullPointerException();
Iterator<E> iterator = objectList.iterator();
BinaryNode<E> currentNode = root;
while (iterator.hasNext()) {
E currentObject = iterator.next();
currentNode.setData(currentObject);
}
}
}
@@ -0,0 +1,16 @@
package jcf_set.example;
public class InteriRipetuti {
public static void main(String[] Args) {
}
public void run() {
int N = 20;
int MAX_INT = 50;
// HASHSET
}
}
@@ -0,0 +1,224 @@
package binary_tree;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
public class LinkedBinaryTree<E> implements BinaryTree<E>{
// VARIABILI D'INSTANZA
private BinaryNode<E> root;
private int size;
// Metodi costruttori
public LinkedBinaryTree() {
root = null;
size = 0;
}
public LinkedBinaryTree(E data) {
root = new BinaryNode<E>(data);
size = 1;
}
public LinkedBinaryTree(LinkedBinaryTree<E> left, E data, LinkedBinaryTree<E> right) {
root = new BinaryNode<E>(left.root, data, right.root);
size = 1 + left.size + right.size;
}
// METODI
public int size() {
return size;
}
@Override
public boolean isEmpty() {
return root == null;
}
public E getRoot() {
if (isEmpty()) return null;
return root.getData();
}
public BinaryNode<E> getRootNode() {
if (isEmpty()) return null;
return root;
}
public void clear() {
root = null;
size = 0;
}
private int getSize(BinaryNode<E> node) {
if (node == null) return 0;
int nLeft = (node.getLeft() == null) ? 0 : getSize(node.getLeft());
int nRight = (node.getRight() == null) ? 0 : getSize(node.getRight());
return 1 + nLeft + nRight;
}
public LinkedBinaryTree<E> removeLeft() {
LinkedBinaryTree<E> leftTree = null;
if (root.getLeft() == null) return leftTree;
leftTree = new LinkedBinaryTree<E>();
leftTree.root = root.getLeft();
leftTree.size = getSize(root.getLeft());
leftTree.root.setAsRoot();
size = size - leftTree.size;
return leftTree;
}
public LinkedBinaryTree<E> removeRight() {
LinkedBinaryTree<E> rightTree = null;
if (root.getRight() == null) return rightTree;
rightTree = new LinkedBinaryTree<E>();
rightTree.root = root.getRight();
rightTree.size = getSize(root.getRight());
rightTree.root.setAsRoot();
size = size - rightTree.size;
return rightTree;
}
protected BinaryNode<E> find(E targetElement, BinaryNode<E> root) {
if (root == null) return null;
if (root.getData().equals(targetElement)) return root;
BinaryNode<E> resNode;
resNode = find(targetElement, root.getLeft());
if (resNode == null) resNode = find(targetElement, root.getRight());
return resNode;
}
public boolean remove(E targetElement) {
if (targetElement == null) return false;
BinaryNode<E> temp = find(targetElement, root);
if (temp != null) {
temp.setData(null);
return true;
}
return false;
}
public boolean contains(E targetElement) {
return find(targetElement, root) != null;
}
// ITERATORE PREORDER
/*
* Qui si utilizza il metodo del preorder.
* Le regole per il preorder sono queste:
* - Visita prima se stesso
* - Poi visita tutto ciò che si trova sinistra
* - Infine visita tutto ciò che si trova a destra
*/
protected void preorder (BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
if (node.getData() != null) temporaryList.add(node.getData());
preorder(node.getLeft(), temporaryList);
preorder(node.getRight(), temporaryList);
}
public Iterator<E> iteratorPreOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
preorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE INORDER
/*
* Qui si utilizza il metodo del inorder.
* Le regole per l'inorder sono queste:
* - Visita prima tutto ciò che si trova a sinistra
* - Poi visita se stesso
* - Infine visita tutto ciò che si trova a destra
*/
protected void inorder(BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
inorder(node.getLeft(), temporaryList);
if (node.getData() != null) temporaryList.add(node.getData());
inorder(node.getRight(), temporaryList);
}
public Iterator<E> iteratorInOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
inorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE POSTORDER
/*
* Qui si utilizza il metodo postorder.
* Le regole per il postorder sono queste:
* - Visita prima di tutto ciò che si trova a sinistra
* - Poi visita tutto ciò che si trova a destra
* - Infine visita il sestesso
*/
protected void postorder(BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
postorder(node.getLeft(), temporaryList);
postorder(node.getRight(), temporaryList);
if (node.getData() != null) temporaryList.add(node.getData());
}
public Iterator<E> iteratorPostOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
postorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE LEVEL ORDER
/*
* Qui si usa il metodo levelorder.
* Si analizza tutto il livello dell'albero.
* Per chiarire di seguito un esempio:
*
* A
* / \
* B C
* / \ \
* D E F
*
* La lettura avviene quindi in questo modo:
* A - B - C - D - E - F
*
* Si adopera una coda (Queue) di tipo FI-FO (First In - First Out)
*/
protected void levelorder(BinaryNode<E> node, List<E> temporaryList) {
Queue<BinaryNode<E>> queueOfNodes = new LinkedList<BinaryNode<E>>();
BinaryNode<E> current;
queueOfNodes.add(node);
while(!queueOfNodes.isEmpty()) {
current = queueOfNodes.remove();
if (current.getData() != null) templist.add();
}
}
}
@@ -0,0 +1,383 @@
package binary_tree;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Stack;
public class LinkedBinaryTree<E> implements BinaryTree<E>{
// VARIABILI D'INSTANZA
private BinaryNode<E> root;
private int size;
// Metodi costruttori
public LinkedBinaryTree() {
root = null;
size = 0;
}
public LinkedBinaryTree(E data) {
root = new BinaryNode<E>(data);
size = 1;
}
public LinkedBinaryTree(LinkedBinaryTree<E> left, E data, LinkedBinaryTree<E> right) {
root = new BinaryNode<E>(left.root, data, right.root);
size = 1 + left.size + right.size;
}
// METODI
public int size() {
return size;
}
@Override
public boolean isEmpty() {
return root == null;
}
public E getRoot() {
if (isEmpty()) return null;
return root.getData();
}
public BinaryNode<E> getRootNode() {
if (isEmpty()) return null;
return root;
}
public void clear() {
root = null;
size = 0;
}
private int getSize(BinaryNode<E> node) {
if (node == null) return 0;
int nLeft = (node.getLeft() == null) ? 0 : getSize(node.getLeft());
int nRight = (node.getRight() == null) ? 0 : getSize(node.getRight());
return 1 + nLeft + nRight;
}
public LinkedBinaryTree<E> removeLeft() {
LinkedBinaryTree<E> leftTree = null;
if (root.getLeft() == null) return leftTree;
leftTree = new LinkedBinaryTree<E>();
leftTree.root = root.getLeft();
leftTree.size = getSize(root.getLeft());
leftTree.root.setAsRoot();
size = size - leftTree.size;
return leftTree;
}
public LinkedBinaryTree<E> removeRight() {
LinkedBinaryTree<E> rightTree = null;
if (root.getRight() == null) return rightTree;
rightTree = new LinkedBinaryTree<E>();
rightTree.root = root.getRight();
rightTree.size = getSize(root.getRight());
rightTree.root.setAsRoot();
size = size - rightTree.size;
return rightTree;
}
protected BinaryNode<E> find(E targetElement, BinaryNode<E> root) {
if (root == null) return null;
if (root.getData().equals(targetElement)) return root;
BinaryNode<E> resNode;
resNode = find(targetElement, root.getLeft());
if (resNode == null) resNode = find(targetElement, root.getRight());
return resNode;
}
public boolean remove(E targetElement) {
if (targetElement == null) return false;
BinaryNode<E> temp = find(targetElement, root);
if (temp != null) {
temp.setData(null);
return true;
}
return false;
}
public boolean contains(E targetElement) {
return find(targetElement, root) != null;
}
// ITERATORE PREORDER
/*
* Qui si utilizza il metodo del preorder.
* Le regole per il preorder sono queste:
* - Visita prima se stesso
* - Poi visita tutto ciò che si trova sinistra
* - Infine visita tutto ciò che si trova a destra
*/
protected void preorder (BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
if (node.getData() != null) temporaryList.add(node.getData());
preorder(node.getLeft(), temporaryList);
preorder(node.getRight(), temporaryList);
}
public Iterator<E> iteratorPreOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
preorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE INORDER
/*
* Qui si utilizza il metodo del inorder.
* Le regole per l'inorder sono queste:
* - Visita prima tutto ciò che si trova a sinistra
* - Poi visita se stesso
* - Infine visita tutto ciò che si trova a destra
*/
protected void inorder(BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
inorder(node.getLeft(), temporaryList);
if (node.getData() != null) temporaryList.add(node.getData());
inorder(node.getRight(), temporaryList);
}
public Iterator<E> iteratorInOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
inorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE POSTORDER
/*
* Qui si utilizza il metodo postorder.
* Le regole per il postorder sono queste:
* - Visita prima di tutto ciò che si trova a sinistra
* - Poi visita tutto ciò che si trova a destra
* - Infine visita il sestesso
*/
protected void postorder(BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
postorder(node.getLeft(), temporaryList);
postorder(node.getRight(), temporaryList);
if (node.getData() != null) temporaryList.add(node.getData());
}
public Iterator<E> iteratorPostOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
postorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE LEVEL ORDER
/*
* Qui si usa il metodo levelorder.
* Si analizza tutto il livello dell'albero.
* Per chiarire di seguito un esempio:
*
* A
* / \
* B C
* / \ \
* D E F
*
* La lettura avviene quindi in questo modo:
* A - B - C - D - E - F
*
* Si adopera una coda (Queue) di tipo FI-FO (First In - First Out)
*/
protected void levelorder(BinaryNode<E> node, List<E> temporaryList) {
Queue<BinaryNode<E>> queueOfNodes = new LinkedList<BinaryNode<E>>();
BinaryNode<E> current;
queueOfNodes.add(node);
while(!queueOfNodes.isEmpty()) {
current = queueOfNodes.remove();
if (current.getData() != null) temporaryList.add(current.getData());
if (current.getLeft() != null) queueOfNodes.add(current.getLeft());
if (current.getRight() != null) queueOfNodes.add(current.getRight());
}
}
public Iterator<E> iteratorLevelOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
levelorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE
public Iterator<E> iterator() {
return iteratorPreOrder();
}
// ITERATORE PREORDER ITERATIVO (NON RICORSIVO)
/*
* In questo caso stiamo usando un tipo stack.
* Dobbiamo di fatto simulare uno stack se vogliamo
* iterativamente fare questa cosa.
*
* Perchè se prima dobbiamo visitare il nodo centrale,
* poi il nodo a sinistra e poi il nodo a destra inseriamo
* prima quello di destra e poi quello di sinistra?
*
* Lo stack di fatto è una coda LIFO, ovvero last in - first out
* e quindi l'ultimo che entra è il primo che esce.
*
* dal momento che vale questa cosa, se facciamo entrare prima quello
* di destra e poi quello di sinistra, il primo nodo che verrà
* prelevato è ovviamente quello a sinistra.
*/
protected void itpreorder (BinaryNode<E> node, List<E> temporaryList) {
Stack<BinaryNode<E>> queueOfNodes = new Stack<BinaryNode<E>>();
BinaryNode<E> current;
queueOfNodes.add(node);
while (!queueOfNodes.isEmpty()) {
current = queueOfNodes.pop();
if (current.getData() != null) temporaryList.add(current.getData());
// Come già spiegato pushamo prima il nodo di destra
if (current.getRight() != null) queueOfNodes.push(current.getRight());
// Infine aggiungiamo il nodo di sinistra
if (current.getLeft() != null) queueOfNodes.push(current.getLeft());
}
}
public Iterator<E> ititeratorPreOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
itpreorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATOR INORDER ITERATIVO (NON RICORSIVO)
/*
* Questo metodo riguarda lo stesso di quello superiore.
* Il metodo inorder richiede che si visiti prima sinistra,
* poi il nodo stesso, infine il nodo di destra.
*
* Possiamo quindi sempre adoperare uno Stack per siumlare la
* ricorsione.
*
* Come detto prima, se il primo nodo ad essere prelevato è
* l'ultimo che si inserisce (coda LIFO, Stack) allora per simulare
* sinistra -> centro -> destra.
*
* Nel metodo sono state inserite delle check con uno stack di
* flag che permette di capire quando il nodo centrale è visitare
* oppure no.
*/
private void itinorder(BinaryNode<E> node, List<E> temporaryList) {
Stack<BinaryNode<E>> queueOfNodes = new Stack<BinaryNode<E>>();
Stack<Boolean> flags = new Stack<Boolean>();
BinaryNode<E> current;
Boolean flag;
queueOfNodes.add(node);
flags.push(false);
while (!queueOfNodes.isEmpty()) {
current = queueOfNodes.pop();
flag = flags.pop();
if (flag) {
// il nodo è da visitare
if (current.getData() != null) temporaryList.add(current.getData());
} else {
// il nodo non è da visitare
// prima si aggiunge il nodo di destra
if (current.getRight() != null) {
queueOfNodes.add(current.getRight());
flags.add(false);
}
queueOfNodes.push(current);
flags.push(true);
if (current.getLeft() != null) {
queueOfNodes.add(current.getLeft());
flags.push(false);
}
}
}
}
public Iterator<E> ititeratorInOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
itinorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATOR POST ORDER ITERATIVO (NON RICORSIVO)
/*
* In questo caso la logica è la seguente. si ha la
* necessità di fare il seguente ciclo: SINISTRA -> DESTRA -> NODO CORRENTE
*
* Per simulare lo stack dobbiamo quindi ripercorrerlo al contrario,
* dunque NODO CORRENTE -> DESTRA -> SINISTRA
*
* Possiamo dunque rifare lo stesso, di ciò che abbiamo fatto sopra.
*/
protected void itpostorder(BinaryNode<E> node, List<E> temporaryList) {
Stack<BinaryNode<E>> queueOfNodes = new Stack<BinaryNode<E>>();
Stack<Boolean> flags = new Stack<Boolean>();
BinaryNode<E> current;
Boolean flag;
queueOfNodes.push(node);
while (!queueOfNodes.isEmpty()) {
current = queueOfNodes.pop();
flag = flags.pop();
if (flag) {
// il nodo è da visitare
if (current.getData() != null) temporaryList.add(current.getData());
} else {
// il nodo non è ancora da visitare
// Visitiamo il nodo corrente
queueOfNodes.push(current);
flags.push(true);
// visitiamo il nodo di destra
if (current.getRight() != null) {
queueOfNodes.push(current.getRight());
}
}
}
}
}
@@ -0,0 +1,83 @@
package binary_tree;
public class LinkedBinaryTree<E> implements BinaryTree<E>{
// VARIABILI D'INSTANZA
private BinaryNode<E> root;
private int size;
// Metodi costruttori
public LinkedBinaryTree() {
root = null;
size = 0;
}
public LinkedBinaryTree(E data) {
root = new BinaryNode<E>(data);
size = 1;
}
public LinkedBinaryTree(LinkedBinaryTree<E> left, E data, LinkedBinaryTree<E> right) {
root = new BinaryNode<E>(left.root, data, right.root);
size = 1 + left.size + right.size;
}
// METODI
public int size() {
return size;
}
@Override
public boolean isEmpty() {
return root == null;
}
public E getRoot() {
if (isEmpty()) return null;
return root.getData();
}
public BinaryNode<E> getRootNode() {
if (isEmpty()) return null;
return root;
}
public void clear() {
root = null;
size = 0;
}
private int getSize(BinaryNode<E> node) {
if (node == null) return 0;
int nLeft = (node.getLeft() == null) ? 0 : getSize(node.getLeft());
int nRight = (node.getRight() == null) ? 0 : getSize(node.getRight());
return 1 + nLeft + nRight;
}
public LinkedBinaryTree<E> removeLeft() {
LinkedBinaryTree<E> leftTree = null;
if (root.getLeft() == null) return leftTree;
leftTree = new LinkedBinaryTree<E>();
leftTree.root = root.getLeft();
leftTree.size = getSize(root.getLeft());
leftTree.root.setAsRoot();
size = size - leftTree.size;
return leftTree;
}
public LinkedBinaryTree<E> removeRight() {
LinkedBinaryTree<E> rightTree = null;
if (root.getRight() == null) return rightTree;
rightTree = new LinkedBinaryTree<E>();
rightTree.root = root.getRight();
rightTree.size = getSize(root.getRight());
}
}
@@ -0,0 +1,500 @@
package binary_tree;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Stack;
public class LinkedBinaryTree<E> implements BinaryTree<E>{
// VARIABILI D'INSTANZA
private BinaryNode<E> root;
private int size;
// Metodi costruttori
public LinkedBinaryTree() {
root = null;
size = 0;
}
public LinkedBinaryTree(E data) {
root = new BinaryNode<E>(data);
size = 1;
}
public LinkedBinaryTree(LinkedBinaryTree<E> left, E data, LinkedBinaryTree<E> right) {
root = new BinaryNode<E>(left.root, data, right.root);
size = 1 + left.size + right.size;
}
// METODI
public int size() {
return size;
}
@Override
public boolean isEmpty() {
return root == null;
}
public E getRoot() {
if (isEmpty()) return null;
return root.getData();
}
public BinaryNode<E> getRootNode() {
if (isEmpty()) return null;
return root;
}
public void clear() {
root = null;
size = 0;
}
private int getSize(BinaryNode<E> node) {
if (node == null) return 0;
int nLeft = (node.getLeft() == null) ? 0 : getSize(node.getLeft());
int nRight = (node.getRight() == null) ? 0 : getSize(node.getRight());
return 1 + nLeft + nRight;
}
public LinkedBinaryTree<E> removeLeft() {
LinkedBinaryTree<E> leftTree = null;
if (root.getLeft() == null) return leftTree;
leftTree = new LinkedBinaryTree<E>();
leftTree.root = root.getLeft();
leftTree.size = getSize(root.getLeft());
leftTree.root.setAsRoot();
size = size - leftTree.size;
return leftTree;
}
public LinkedBinaryTree<E> removeRight() {
LinkedBinaryTree<E> rightTree = null;
if (root.getRight() == null) return rightTree;
rightTree = new LinkedBinaryTree<E>();
rightTree.root = root.getRight();
rightTree.size = getSize(root.getRight());
rightTree.root.setAsRoot();
size = size - rightTree.size;
return rightTree;
}
protected BinaryNode<E> find(E targetElement, BinaryNode<E> root) {
if (root == null) return null;
if (root.getData().equals(targetElement)) return root;
BinaryNode<E> resNode;
resNode = find(targetElement, root.getLeft());
if (resNode == null) resNode = find(targetElement, root.getRight());
return resNode;
}
public boolean remove(E targetElement) {
if (targetElement == null) return false;
BinaryNode<E> temp = find(targetElement, root);
if (temp != null) {
temp.setData(null);
return true;
}
return false;
}
public boolean contains(E targetElement) {
return find(targetElement, root) != null;
}
// ITERATORE PREORDER
/*
* Qui si utilizza il metodo del preorder.
* Le regole per il preorder sono queste:
* - Visita prima se stesso
* - Poi visita tutto ciò che si trova sinistra
* - Infine visita tutto ciò che si trova a destra
*/
protected void preorder (BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
if (node.getData() != null) temporaryList.add(node.getData());
preorder(node.getLeft(), temporaryList);
preorder(node.getRight(), temporaryList);
}
public Iterator<E> iteratorPreOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
preorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE INORDER
/*
* Qui si utilizza il metodo del inorder.
* Le regole per l'inorder sono queste:
* - Visita prima tutto ciò che si trova a sinistra
* - Poi visita se stesso
* - Infine visita tutto ciò che si trova a destra
*/
protected void inorder(BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
inorder(node.getLeft(), temporaryList);
if (node.getData() != null) temporaryList.add(node.getData());
inorder(node.getRight(), temporaryList);
}
public Iterator<E> iteratorInOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
inorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE POSTORDER
/*
* Qui si utilizza il metodo postorder.
* Le regole per il postorder sono queste:
* - Visita prima di tutto ciò che si trova a sinistra
* - Poi visita tutto ciò che si trova a destra
* - Infine visita il sestesso
*/
protected void postorder(BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
postorder(node.getLeft(), temporaryList);
postorder(node.getRight(), temporaryList);
if (node.getData() != null) temporaryList.add(node.getData());
}
public Iterator<E> iteratorPostOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
postorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE LEVEL ORDER
/*
* Qui si usa il metodo levelorder.
* Si analizza tutto il livello dell'albero.
* Per chiarire di seguito un esempio:
*
* A
* / \
* B C
* / \ \
* D E F
*
* La lettura avviene quindi in questo modo:
* A - B - C - D - E - F
*
* Si adopera una coda (Queue) di tipo FI-FO (First In - First Out)
*/
protected void levelorder(BinaryNode<E> node, List<E> temporaryList) {
Queue<BinaryNode<E>> queueOfNodes = new LinkedList<BinaryNode<E>>();
BinaryNode<E> current;
queueOfNodes.add(node);
while(!queueOfNodes.isEmpty()) {
current = queueOfNodes.remove();
if (current.getData() != null) temporaryList.add(current.getData());
if (current.getLeft() != null) queueOfNodes.add(current.getLeft());
if (current.getRight() != null) queueOfNodes.add(current.getRight());
}
}
public Iterator<E> iteratorLevelOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
levelorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE
public Iterator<E> iterator() {
return iteratorPreOrder();
}
// ITERATORE PREORDER ITERATIVO (NON RICORSIVO)
/*
* In questo caso stiamo usando un tipo stack.
* Dobbiamo di fatto simulare uno stack se vogliamo
* iterativamente fare questa cosa.
*
* Perchè se prima dobbiamo visitare il nodo centrale,
* poi il nodo a sinistra e poi il nodo a destra inseriamo
* prima quello di destra e poi quello di sinistra?
*
* Lo stack di fatto è una coda LIFO, ovvero last in - first out
* e quindi l'ultimo che entra è il primo che esce.
*
* dal momento che vale questa cosa, se facciamo entrare prima quello
* di destra e poi quello di sinistra, il primo nodo che verrà
* prelevato è ovviamente quello a sinistra.
*/
protected void itpreorder (BinaryNode<E> node, List<E> temporaryList) {
Stack<BinaryNode<E>> queueOfNodes = new Stack<BinaryNode<E>>();
BinaryNode<E> current;
queueOfNodes.add(node);
while (!queueOfNodes.isEmpty()) {
current = queueOfNodes.pop();
if (current.getData() != null) temporaryList.add(current.getData());
// Come già spiegato pushamo prima il nodo di destra
if (current.getRight() != null) queueOfNodes.push(current.getRight());
// Infine aggiungiamo il nodo di sinistra
if (current.getLeft() != null) queueOfNodes.push(current.getLeft());
}
}
public Iterator<E> ititeratorPreOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
itpreorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATOR INORDER ITERATIVO (NON RICORSIVO)
/*
* Questo metodo riguarda lo stesso di quello superiore.
* Il metodo inorder richiede che si visiti prima sinistra,
* poi il nodo stesso, infine il nodo di destra.
*
* Possiamo quindi sempre adoperare uno Stack per siumlare la
* ricorsione.
*
* Come detto prima, se il primo nodo ad essere prelevato è
* l'ultimo che si inserisce (coda LIFO, Stack) allora per simulare
* sinistra -> centro -> destra.
*
* Nel metodo sono state inserite delle check con uno stack di
* flag che permette di capire quando il nodo centrale è visitare
* oppure no.
*/
private void itinorder(BinaryNode<E> node, List<E> temporaryList) {
Stack<BinaryNode<E>> queueOfNodes = new Stack<BinaryNode<E>>();
Stack<Boolean> flags = new Stack<Boolean>();
BinaryNode<E> current;
Boolean flag;
queueOfNodes.add(node);
flags.push(false);
while (!queueOfNodes.isEmpty()) {
current = queueOfNodes.pop();
flag = flags.pop();
if (flag) {
// il nodo è da visitare
if (current.getData() != null) temporaryList.add(current.getData());
} else {
// il nodo non è da visitare
// prima si aggiunge il nodo di destra
if (current.getRight() != null) {
queueOfNodes.add(current.getRight());
flags.add(false);
}
queueOfNodes.push(current);
flags.push(true);
if (current.getLeft() != null) {
queueOfNodes.add(current.getLeft());
flags.push(false);
}
}
}
}
public Iterator<E> ititeratorInOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
itinorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATOR POST ORDER ITERATIVO (NON RICORSIVO)
/*
* In questo caso la logica è la seguente. si ha la
* necessità di fare il seguente ciclo: SINISTRA -> DESTRA -> NODO CORRENTE
*
* Per simulare lo stack dobbiamo quindi ripercorrerlo al contrario,
* dunque NODO CORRENTE -> DESTRA -> SINISTRA
*
* Possiamo dunque rifare lo stesso, di ciò che abbiamo fatto sopra.
*/
protected void itpostorder(BinaryNode<E> node, List<E> temporaryList) {
Stack<BinaryNode<E>> queueOfNodes = new Stack<BinaryNode<E>>();
Stack<Boolean> flags = new Stack<Boolean>();
BinaryNode<E> current;
Boolean flag;
queueOfNodes.push(node);
flags.push(false);
while (!queueOfNodes.isEmpty()) {
current = queueOfNodes.pop();
flag = flags.pop();
if (flag) {
// il nodo è da visitare
if (current.getData() != null) temporaryList.add(current.getData());
} else {
// il nodo non è ancora da visitare
// Visitiamo il nodo corrente
queueOfNodes.push(current);
flags.push(true);
// visitiamo il nodo di destra
if (current.getRight() != null) {
queueOfNodes.push(current.getRight());
flags.push(false);
}
// visitiamo il nodo di sinistra infine
if (current.getLeft() != null) {
queueOfNodes.push(current.getLeft());
flags.push(false);
}
}
}
}
public Iterator<E> ititeratorPostOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
itpostorder(root, temporaryList);
return temporaryList.iterator();
}
/*
* II parziale 2022/2023
* Realizzare un metodo costruttore della classe LinkedBinaryTree<E> che
* prende in input una lista di oggetti di tipo E e costruisce una catena
* casuale tale che l'iesimo elemento della lista è posizionato al livello iesimo
* della catena e ogni nodo ha probabilità 1/2 di avere un figlio sinistro/destro.
*/
/*
* Spiegazione intuitiva (visto che la melideo intende complicare la consegna):
* Data ad esempio una lista del genere:
* [A, B, C, D]
*
* Si ottiene quindi una catena del genere:
* A
* \
* B
* /
* C
* \
* D
*/
public LinkedBinaryTree(List<E> objectList) {
if (objectList == null) throw new NullPointerException();
Iterator<E> iterator = objectList.iterator();
if (!iterator.hasNext()) return;
E currentObject = iterator.next();
root = new BinaryNode<E>(currentObject);
BinaryNode<E> currentNode = root;
currentNode.setData(currentObject);
size = 1;
while (iterator.hasNext()) {
currentObject = iterator.next();
int wing = (int) (Math.random() * 2);
BinaryNode<E> newNode = new BinaryNode<E>(currentObject);
if (wing == 0) {
// Left
newNode.setParentAsLeftChild(currentNode);
} else {
// Right
newNode.setParentAsRightChild(currentNode);
}
currentNode = newNode;
size++;
}
}
/*
* II parziale 2022
* Si aggiunga alla classe LinkedBinaryTree<E> un metodo
* che stampa le foglie dall'albero corrente (da sinistra verso destra)
*/
public void printLeaf() {
printLeaf(root);
}
public void printLeaf(BinaryNode<E> node) {
if (node == null) return;
if (node.getLeft() == null && node.getRight() == null) System.out.println(node.getData().toString());
else {
printLeaf(node.getLeft());
printLeaf(node.getRight());
}
}
/*
* Si aggiunga alla classe LinkedBinaryTree<E> un metodo che conta il numero
* di foglie dell'albero corrente
*/
public int numberLeaf() {
return numberLeaf(root);
}
public int numberLeaf(BinaryNode<E> node) {
if (node == null) return 0;
if (node.getLeft() == null && node.getRight() == null) return 1;
int nLeft = (node.getLeft() == null) ? 0 : numberLeaf(node.getLeft());
int nRight = (node.getRight() == null) ? 0 : numberLeaf(node.getRight());
return nLeft + nRight;
}
/*
* Si aggiunga alla classe LinkedBinaryTree<E> un metodo che trasforma l'albero corrente
* in modo che ogni suo nodo interno abbia esattamente due figli. Se un nodo ha solo un
* figlio, si aggiunga l'altro nodo figlio come copia del figlio esistente
*/
public void makeFull() {
makeFull(root);
}
public void makeFull(BinaryNode<E> node) {
if (node == null) return;
}
}
@@ -0,0 +1,87 @@
package binary_tree;
public class LinkedBinaryTree<E> implements BinaryTree<E>{
// VARIABILI D'INSTANZA
private BinaryNode<E> root;
private int size;
// Metodi costruttori
public LinkedBinaryTree() {
root = null;
size = 0;
}
public LinkedBinaryTree(E data) {
root = new BinaryNode<E>(data);
size = 1;
}
public LinkedBinaryTree(LinkedBinaryTree<E> left, E data, LinkedBinaryTree<E> right) {
root = new BinaryNode<E>(left.root, data, right.root);
size = 1 + left.size + right.size;
}
// METODI
public int size() {
return size;
}
@Override
public boolean isEmpty() {
return root == null;
}
public E getRoot() {
if (isEmpty()) return null;
return root.getData();
}
public BinaryNode<E> getRootNode() {
if (isEmpty()) return null;
return root;
}
public void clear() {
root = null;
size = 0;
}
private int getSize(BinaryNode<E> node) {
if (node == null) return 0;
int nLeft = (node.getLeft() == null) ? 0 : getSize(node.getLeft());
int nRight = (node.getRight() == null) ? 0 : getSize(node.getRight());
return 1 + nLeft + nRight;
}
public LinkedBinaryTree<E> removeLeft() {
LinkedBinaryTree<E> leftTree = null;
if (root.getLeft() == null) return leftTree;
leftTree = new LinkedBinaryTree<E>();
leftTree.root = root.getLeft();
leftTree.size = getSize(root.getLeft());
leftTree.root.setAsRoot();
size = size - leftTree.size;
return leftTree;
}
public LinkedBinaryTree<E> removeRight() {
LinkedBinaryTree<E> rightTree = null;
if (root.getRight() == null) return rightTree;
rightTree = new LinkedBinaryTree<E>();
rightTree.root = root.getRight();
rightTree.size = getSize(root.getRight());
size = size - rightTree.size;
return rightTree;
}
}
@@ -0,0 +1,5 @@
package test;
public class Main {
}
@@ -0,0 +1,26 @@
package binary_tree;
public class LinkedBinaryTree<E> implements BinaryTree<E>{
// VARIABILI D'INSTANZA
private BinaryNode<E> root;
private int size;
// Metodi costruttori
public LinkedBinaryTree() {
root = null;
size = 0;
}
public LinkedBinaryTree(E data) {
}
// METODI
@Override
public boolean isEmpty() {
}
}
@@ -0,0 +1,38 @@
package parziale.p251110;
import java.util.ArrayList;
import java.util.Iterator;
public class Clinica {
ArrayList<Paziente> pazienti = new ArrayList<Paziente>();
// 1. Numero di pazienti Ricoverati
public int pazientiRicoverati() {
return pazienti.size();
}
// 2. Inserimento del paziente
/*
* Dal momento che non ci è permesso adoperare
* TreeSet per l'ordine e per l'unicità
*/
public boolean ricoveraPaziente(Paziente paziente) {
// Se il paziente è nullo, nulla verrà aggiunto
if (paziente == null) return false;
// Controllo se il paziente è già presente nella lista ricoveri
Iterator<Paziente> it = pazienti.iterator();
while (it.hasNext()) {
Paziente current = it.next();
if (paziente.equals(current)) return false; // Se è già presente un paziente con id uguale allora non viene aggiunto e ritorna false
}
// Aggiunta del paziente
Iterator<Paziente> it = pazienti.iterator();
while (it.hasNext()) {
}
}
}
@@ -0,0 +1,502 @@
package binary_tree;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Stack;
public class LinkedBinaryTree<E> implements BinaryTree<E>{
// VARIABILI D'INSTANZA
private BinaryNode<E> root;
private int size;
// Metodi costruttori
public LinkedBinaryTree() {
root = null;
size = 0;
}
public LinkedBinaryTree(E data) {
root = new BinaryNode<E>(data);
size = 1;
}
public LinkedBinaryTree(LinkedBinaryTree<E> left, E data, LinkedBinaryTree<E> right) {
root = new BinaryNode<E>(left.root, data, right.root);
size = 1 + left.size + right.size;
}
// METODI
public int size() {
return size;
}
@Override
public boolean isEmpty() {
return root == null;
}
public E getRoot() {
if (isEmpty()) return null;
return root.getData();
}
public BinaryNode<E> getRootNode() {
if (isEmpty()) return null;
return root;
}
public void clear() {
root = null;
size = 0;
}
private int getSize(BinaryNode<E> node) {
if (node == null) return 0;
int nLeft = (node.getLeft() == null) ? 0 : getSize(node.getLeft());
int nRight = (node.getRight() == null) ? 0 : getSize(node.getRight());
return 1 + nLeft + nRight;
}
public LinkedBinaryTree<E> removeLeft() {
LinkedBinaryTree<E> leftTree = null;
if (root.getLeft() == null) return leftTree;
leftTree = new LinkedBinaryTree<E>();
leftTree.root = root.getLeft();
leftTree.size = getSize(root.getLeft());
leftTree.root.setAsRoot();
size = size - leftTree.size;
return leftTree;
}
public LinkedBinaryTree<E> removeRight() {
LinkedBinaryTree<E> rightTree = null;
if (root.getRight() == null) return rightTree;
rightTree = new LinkedBinaryTree<E>();
rightTree.root = root.getRight();
rightTree.size = getSize(root.getRight());
rightTree.root.setAsRoot();
size = size - rightTree.size;
return rightTree;
}
protected BinaryNode<E> find(E targetElement, BinaryNode<E> root) {
if (root == null) return null;
if (root.getData().equals(targetElement)) return root;
BinaryNode<E> resNode;
resNode = find(targetElement, root.getLeft());
if (resNode == null) resNode = find(targetElement, root.getRight());
return resNode;
}
public boolean remove(E targetElement) {
if (targetElement == null) return false;
BinaryNode<E> temp = find(targetElement, root);
if (temp != null) {
temp.setData(null);
return true;
}
return false;
}
public boolean contains(E targetElement) {
return find(targetElement, root) != null;
}
// ITERATORE PREORDER
/*
* Qui si utilizza il metodo del preorder.
* Le regole per il preorder sono queste:
* - Visita prima se stesso
* - Poi visita tutto ciò che si trova sinistra
* - Infine visita tutto ciò che si trova a destra
*/
protected void preorder (BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
if (node.getData() != null) temporaryList.add(node.getData());
preorder(node.getLeft(), temporaryList);
preorder(node.getRight(), temporaryList);
}
public Iterator<E> iteratorPreOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
preorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE INORDER
/*
* Qui si utilizza il metodo del inorder.
* Le regole per l'inorder sono queste:
* - Visita prima tutto ciò che si trova a sinistra
* - Poi visita se stesso
* - Infine visita tutto ciò che si trova a destra
*/
protected void inorder(BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
inorder(node.getLeft(), temporaryList);
if (node.getData() != null) temporaryList.add(node.getData());
inorder(node.getRight(), temporaryList);
}
public Iterator<E> iteratorInOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
inorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE POSTORDER
/*
* Qui si utilizza il metodo postorder.
* Le regole per il postorder sono queste:
* - Visita prima di tutto ciò che si trova a sinistra
* - Poi visita tutto ciò che si trova a destra
* - Infine visita il sestesso
*/
protected void postorder(BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
postorder(node.getLeft(), temporaryList);
postorder(node.getRight(), temporaryList);
if (node.getData() != null) temporaryList.add(node.getData());
}
public Iterator<E> iteratorPostOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
postorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE LEVEL ORDER
/*
* Qui si usa il metodo levelorder.
* Si analizza tutto il livello dell'albero.
* Per chiarire di seguito un esempio:
*
* A
* / \
* B C
* / \ \
* D E F
*
* La lettura avviene quindi in questo modo:
* A - B - C - D - E - F
*
* Si adopera una coda (Queue) di tipo FI-FO (First In - First Out)
*/
protected void levelorder(BinaryNode<E> node, List<E> temporaryList) {
Queue<BinaryNode<E>> queueOfNodes = new LinkedList<BinaryNode<E>>();
BinaryNode<E> current;
queueOfNodes.add(node);
while(!queueOfNodes.isEmpty()) {
current = queueOfNodes.remove();
if (current.getData() != null) temporaryList.add(current.getData());
if (current.getLeft() != null) queueOfNodes.add(current.getLeft());
if (current.getRight() != null) queueOfNodes.add(current.getRight());
}
}
public Iterator<E> iteratorLevelOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
levelorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE
public Iterator<E> iterator() {
return iteratorPreOrder();
}
// ITERATORE PREORDER ITERATIVO (NON RICORSIVO)
/*
* In questo caso stiamo usando un tipo stack.
* Dobbiamo di fatto simulare uno stack se vogliamo
* iterativamente fare questa cosa.
*
* Perchè se prima dobbiamo visitare il nodo centrale,
* poi il nodo a sinistra e poi il nodo a destra inseriamo
* prima quello di destra e poi quello di sinistra?
*
* Lo stack di fatto è una coda LIFO, ovvero last in - first out
* e quindi l'ultimo che entra è il primo che esce.
*
* dal momento che vale questa cosa, se facciamo entrare prima quello
* di destra e poi quello di sinistra, il primo nodo che verrà
* prelevato è ovviamente quello a sinistra.
*/
protected void itpreorder (BinaryNode<E> node, List<E> temporaryList) {
Stack<BinaryNode<E>> queueOfNodes = new Stack<BinaryNode<E>>();
BinaryNode<E> current;
queueOfNodes.add(node);
while (!queueOfNodes.isEmpty()) {
current = queueOfNodes.pop();
if (current.getData() != null) temporaryList.add(current.getData());
// Come già spiegato pushamo prima il nodo di destra
if (current.getRight() != null) queueOfNodes.push(current.getRight());
// Infine aggiungiamo il nodo di sinistra
if (current.getLeft() != null) queueOfNodes.push(current.getLeft());
}
}
public Iterator<E> ititeratorPreOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
itpreorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATOR INORDER ITERATIVO (NON RICORSIVO)
/*
* Questo metodo riguarda lo stesso di quello superiore.
* Il metodo inorder richiede che si visiti prima sinistra,
* poi il nodo stesso, infine il nodo di destra.
*
* Possiamo quindi sempre adoperare uno Stack per siumlare la
* ricorsione.
*
* Come detto prima, se il primo nodo ad essere prelevato è
* l'ultimo che si inserisce (coda LIFO, Stack) allora per simulare
* sinistra -> centro -> destra.
*
* Nel metodo sono state inserite delle check con uno stack di
* flag che permette di capire quando il nodo centrale è visitare
* oppure no.
*/
private void itinorder(BinaryNode<E> node, List<E> temporaryList) {
Stack<BinaryNode<E>> queueOfNodes = new Stack<BinaryNode<E>>();
Stack<Boolean> flags = new Stack<Boolean>();
BinaryNode<E> current;
Boolean flag;
queueOfNodes.add(node);
flags.push(false);
while (!queueOfNodes.isEmpty()) {
current = queueOfNodes.pop();
flag = flags.pop();
if (flag) {
// il nodo è da visitare
if (current.getData() != null) temporaryList.add(current.getData());
} else {
// il nodo non è da visitare
// prima si aggiunge il nodo di destra
if (current.getRight() != null) {
queueOfNodes.add(current.getRight());
flags.add(false);
}
queueOfNodes.push(current);
flags.push(true);
if (current.getLeft() != null) {
queueOfNodes.add(current.getLeft());
flags.push(false);
}
}
}
}
public Iterator<E> ititeratorInOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
itinorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATOR POST ORDER ITERATIVO (NON RICORSIVO)
/*
* In questo caso la logica è la seguente. si ha la
* necessità di fare il seguente ciclo: SINISTRA -> DESTRA -> NODO CORRENTE
*
* Per simulare lo stack dobbiamo quindi ripercorrerlo al contrario,
* dunque NODO CORRENTE -> DESTRA -> SINISTRA
*
* Possiamo dunque rifare lo stesso, di ciò che abbiamo fatto sopra.
*/
protected void itpostorder(BinaryNode<E> node, List<E> temporaryList) {
Stack<BinaryNode<E>> queueOfNodes = new Stack<BinaryNode<E>>();
Stack<Boolean> flags = new Stack<Boolean>();
BinaryNode<E> current;
Boolean flag;
queueOfNodes.push(node);
flags.push(false);
while (!queueOfNodes.isEmpty()) {
current = queueOfNodes.pop();
flag = flags.pop();
if (flag) {
// il nodo è da visitare
if (current.getData() != null) temporaryList.add(current.getData());
} else {
// il nodo non è ancora da visitare
// Visitiamo il nodo corrente
queueOfNodes.push(current);
flags.push(true);
// visitiamo il nodo di destra
if (current.getRight() != null) {
queueOfNodes.push(current.getRight());
flags.push(false);
}
// visitiamo il nodo di sinistra infine
if (current.getLeft() != null) {
queueOfNodes.push(current.getLeft());
flags.push(false);
}
}
}
}
public Iterator<E> ititeratorPostOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
itpostorder(root, temporaryList);
return temporaryList.iterator();
}
/*
* II parziale 2022/2023
* Realizzare un metodo costruttore della classe LinkedBinaryTree<E> che
* prende in input una lista di oggetti di tipo E e costruisce una catena
* casuale tale che l'iesimo elemento della lista è posizionato al livello iesimo
* della catena e ogni nodo ha probabilità 1/2 di avere un figlio sinistro/destro.
*/
/*
* Spiegazione intuitiva (visto che la melideo intende complicare la consegna):
* Data ad esempio una lista del genere:
* [A, B, C, D]
*
* Si ottiene quindi una catena del genere:
* A
* \
* B
* /
* C
* \
* D
*/
public LinkedBinaryTree(List<E> objectList) {
if (objectList == null) throw new NullPointerException();
Iterator<E> iterator = objectList.iterator();
if (!iterator.hasNext()) return;
E currentObject = iterator.next();
root = new BinaryNode<E>(currentObject);
BinaryNode<E> currentNode = root;
currentNode.setData(currentObject);
size = 1;
while (iterator.hasNext()) {
currentObject = iterator.next();
int wing = (int) (Math.random() * 2);
BinaryNode<E> newNode = new BinaryNode<E>(currentObject);
if (wing == 0) {
// Left
newNode.setParentAsLeftChild(currentNode);
} else {
// Right
newNode.setParentAsRightChild(currentNode);
}
currentNode = newNode;
size++;
}
}
/*
* II parziale 2022
* Si aggiunga alla classe LinkedBinaryTree<E> un metodo
* che stampa le foglie dall'albero corrente (da sinistra verso destra)
*/
public void printLeaf() {
printLeaf(root);
}
public void printLeaf(BinaryNode<E> node) {
if (node == null) return;
if (node.getLeft() == null && node.getRight() == null) System.out.println(node.getData().toString());
else {
printLeaf(node.getLeft());
printLeaf(node.getRight());
}
}
/*
* Si aggiunga alla classe LinkedBinaryTree<E> un metodo che conta il numero
* di foglie dell'albero corrente
*/
public int numberLeaf() {
return numberLeaf(root);
}
public int numberLeaf(BinaryNode<E> node) {
if (node == null) return 0;
if (node.getLeft() == null && node.getRight() == null) return 1;
int nLeft = (node.getLeft() == null) ? 0 : numberLeaf(node.getLeft());
int nRight = (node.getRight() == null) ? 0 : numberLeaf(node.getRight());
return nLeft + nRight;
}
/*
* Si aggiunga alla classe LinkedBinaryTree<E> un metodo che trasforma l'albero corrente
* in modo che ogni suo nodo interno abbia esattamente due figli. Se un nodo ha solo un
* figlio, si aggiunga l'altro nodo figlio come copia del figlio esistente
*/
public void makeFull() {
makeFull(root);
}
public void makeFull(BinaryNode<E> node) {
if (node == null) return; // Se il nodo è nullo, non serve fare operazioni
if (node.hasLeft() && node.hasRight()) return; // Se il nodo ha sia il figlio sinstro che destro, non serve fare operazioni
}
}
@@ -0,0 +1,28 @@
package vettore_ordinabile;
public class VettoriIntero extends VettoreOrdinabile{
// Metodo costruttore default
/*
* Contiene solamente 10 elementi
* */
public VettoriIntero() {
super(10);
}
// Metodo costruttore custom
/*
* Contiene n elementi
*/
public VettoriIntero(int dimensioneMassima) {
super(dimensioneMassima);
}
// Metodo aggiungi
/*
* Questo metodo è un metodo bloccante in modo che
* non aggiungino oggetti che non siano di tipo Integer
*/
public
}
@@ -0,0 +1,39 @@
package comparatori.videogioco;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Main {
public static void main(String[] Args) {
ArrayList<Videogioco> giochi = new ArrayList<Videogioco>();
giochi.add(new Videogioco("The Last of Us Part II", "PS5", 2020, 39.99, 9));
giochi.add(new Videogioco("Cyberpunk 2077", "PC", 2020, 29.99, 8));
giochi.add(new Videogioco("Minecraft", "PC", 2011, 19.99, 10));
giochi.add(new Videogioco("Ghost of Tsushima", "PS5", 2020, 49.99, 9));
giochi.add(new Videogioco("Resident Evil 4 Remake", "PS5", 2023, 44.99, 9));
giochi.add(new Videogioco("GTA V", "PC", 2013, 14.99, 8));
giochi.add(new Videogioco("God of War Ragnarok", "PS5", 2022, 59.99, 10));
giochi.add(new Videogioco("Fortnite", "PC", 2017, 0.0, 7));
// Ordina mediante Comparable - compareTo & stampa
Collections.sort(giochi);
printList(giochi);
}
private <T> void printList(List<T> lista) {
System.out.print("{");
for (int i = 0; i < lista.size(); i++) {
System.out.print(" [");
System.out.print(lista.get(i).toString());
System.out.print("] ");
}
System.out.print("}");
}
}
@@ -0,0 +1,26 @@
package comparatori.videogioco;
import java.util.ArrayList;
import java.util.Collections;
public class Main {
public static void main(String[] Args) {
ArrayList<Videogioco> giochi = new ArrayList<Videogioco>();
giochi.add(new Videogioco("The Last of Us Part II", "PS5", 2020, 39.99, 9));
giochi.add(new Videogioco("Cyberpunk 2077", "PC", 2020, 29.99, 8));
giochi.add(new Videogioco("Minecraft", "PC", 2011, 19.99, 10));
giochi.add(new Videogioco("Ghost of Tsushima", "PS5", 2020, 49.99, 9));
giochi.add(new Videogioco("Resident Evil 4 Remake", "PS5", 2023, 44.99, 9));
giochi.add(new Videogioco("GTA V", "PC", 2013, 14.99, 8));
giochi.add(new Videogioco("God of War Ragnarok", "PS5", 2022, 59.99, 10));
giochi.add(new Videogioco("Fortnite", "PC", 2017, 0.0, 7));
// Per adoperare il comparable
Collections.sort(giochi);
}
}
@@ -0,0 +1,156 @@
package binary_tree;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class LinkedBinaryTree<E> implements BinaryTree<E>{
// VARIABILI D'INSTANZA
private BinaryNode<E> root;
private int size;
// Metodi costruttori
public LinkedBinaryTree() {
root = null;
size = 0;
}
public LinkedBinaryTree(E data) {
root = new BinaryNode<E>(data);
size = 1;
}
public LinkedBinaryTree(LinkedBinaryTree<E> left, E data, LinkedBinaryTree<E> right) {
root = new BinaryNode<E>(left.root, data, right.root);
size = 1 + left.size + right.size;
}
// METODI
public int size() {
return size;
}
@Override
public boolean isEmpty() {
return root == null;
}
public E getRoot() {
if (isEmpty()) return null;
return root.getData();
}
public BinaryNode<E> getRootNode() {
if (isEmpty()) return null;
return root;
}
public void clear() {
root = null;
size = 0;
}
private int getSize(BinaryNode<E> node) {
if (node == null) return 0;
int nLeft = (node.getLeft() == null) ? 0 : getSize(node.getLeft());
int nRight = (node.getRight() == null) ? 0 : getSize(node.getRight());
return 1 + nLeft + nRight;
}
public LinkedBinaryTree<E> removeLeft() {
LinkedBinaryTree<E> leftTree = null;
if (root.getLeft() == null) return leftTree;
leftTree = new LinkedBinaryTree<E>();
leftTree.root = root.getLeft();
leftTree.size = getSize(root.getLeft());
leftTree.root.setAsRoot();
size = size - leftTree.size;
return leftTree;
}
public LinkedBinaryTree<E> removeRight() {
LinkedBinaryTree<E> rightTree = null;
if (root.getRight() == null) return rightTree;
rightTree = new LinkedBinaryTree<E>();
rightTree.root = root.getRight();
rightTree.size = getSize(root.getRight());
rightTree.root.setAsRoot();
size = size - rightTree.size;
return rightTree;
}
protected BinaryNode<E> find(E targetElement, BinaryNode<E> root) {
if (root == null) return null;
if (root.getData().equals(targetElement)) return root;
BinaryNode<E> resNode;
resNode = find(targetElement, root.getLeft());
if (resNode == null) resNode = find(targetElement, root.getRight());
return resNode;
}
public boolean remove(E targetElement) {
if (targetElement == null) return false;
BinaryNode<E> temp = find(targetElement, root);
if (temp != null) {
temp.setData(null);
return true;
}
return false;
}
public boolean contains(E targetElement) {
return find(targetElement, root) != null;
}
// ITERATORE PREORDER
/*
* Qui si utilizza il metodo del preorder.
* Le regole per il preorder sono queste:
* - Visita prima se stesso
* - Poi visita tutto ciò che si trova sinistra
* - Infine visita tutto ciò che si trova a destra
*/
protected void preorder (BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
if (node.getData() != null) temporaryList.add(node.getData());
preorder(node.getLeft(), temporaryList);
preorder(node.getRight(), temporaryList);
}
public Iterator<E> iteratorPreOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
preorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE INORDER
/*
* Qui si utilizza il metodo del inorder.
* Le regole per l'inorder sono queste:
* - Visita prima tutto ciò che si trova a sinistra
* - Poi visita se stesso
* - Infine visita tutto ciò che si trova a destra
*/
protected void inorder(BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
inorder();
}
}
@@ -0,0 +1,445 @@
package binary_tree;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Stack;
public class LinkedBinaryTree<E> implements BinaryTree<E>{
// VARIABILI D'INSTANZA
private BinaryNode<E> root;
private int size;
// Metodi costruttori
public LinkedBinaryTree() {
root = null;
size = 0;
}
public LinkedBinaryTree(E data) {
root = new BinaryNode<E>(data);
size = 1;
}
public LinkedBinaryTree(LinkedBinaryTree<E> left, E data, LinkedBinaryTree<E> right) {
root = new BinaryNode<E>(left.root, data, right.root);
size = 1 + left.size + right.size;
}
// METODI
public int size() {
return size;
}
@Override
public boolean isEmpty() {
return root == null;
}
public E getRoot() {
if (isEmpty()) return null;
return root.getData();
}
public BinaryNode<E> getRootNode() {
if (isEmpty()) return null;
return root;
}
public void clear() {
root = null;
size = 0;
}
private int getSize(BinaryNode<E> node) {
if (node == null) return 0;
int nLeft = (node.getLeft() == null) ? 0 : getSize(node.getLeft());
int nRight = (node.getRight() == null) ? 0 : getSize(node.getRight());
return 1 + nLeft + nRight;
}
public LinkedBinaryTree<E> removeLeft() {
LinkedBinaryTree<E> leftTree = null;
if (root.getLeft() == null) return leftTree;
leftTree = new LinkedBinaryTree<E>();
leftTree.root = root.getLeft();
leftTree.size = getSize(root.getLeft());
leftTree.root.setAsRoot();
size = size - leftTree.size;
return leftTree;
}
public LinkedBinaryTree<E> removeRight() {
LinkedBinaryTree<E> rightTree = null;
if (root.getRight() == null) return rightTree;
rightTree = new LinkedBinaryTree<E>();
rightTree.root = root.getRight();
rightTree.size = getSize(root.getRight());
rightTree.root.setAsRoot();
size = size - rightTree.size;
return rightTree;
}
protected BinaryNode<E> find(E targetElement, BinaryNode<E> root) {
if (root == null) return null;
if (root.getData().equals(targetElement)) return root;
BinaryNode<E> resNode;
resNode = find(targetElement, root.getLeft());
if (resNode == null) resNode = find(targetElement, root.getRight());
return resNode;
}
public boolean remove(E targetElement) {
if (targetElement == null) return false;
BinaryNode<E> temp = find(targetElement, root);
if (temp != null) {
temp.setData(null);
return true;
}
return false;
}
public boolean contains(E targetElement) {
return find(targetElement, root) != null;
}
// ITERATORE PREORDER
/*
* Qui si utilizza il metodo del preorder.
* Le regole per il preorder sono queste:
* - Visita prima se stesso
* - Poi visita tutto ciò che si trova sinistra
* - Infine visita tutto ciò che si trova a destra
*/
protected void preorder (BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
if (node.getData() != null) temporaryList.add(node.getData());
preorder(node.getLeft(), temporaryList);
preorder(node.getRight(), temporaryList);
}
public Iterator<E> iteratorPreOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
preorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE INORDER
/*
* Qui si utilizza il metodo del inorder.
* Le regole per l'inorder sono queste:
* - Visita prima tutto ciò che si trova a sinistra
* - Poi visita se stesso
* - Infine visita tutto ciò che si trova a destra
*/
protected void inorder(BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
inorder(node.getLeft(), temporaryList);
if (node.getData() != null) temporaryList.add(node.getData());
inorder(node.getRight(), temporaryList);
}
public Iterator<E> iteratorInOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
inorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE POSTORDER
/*
* Qui si utilizza il metodo postorder.
* Le regole per il postorder sono queste:
* - Visita prima di tutto ciò che si trova a sinistra
* - Poi visita tutto ciò che si trova a destra
* - Infine visita il sestesso
*/
protected void postorder(BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
postorder(node.getLeft(), temporaryList);
postorder(node.getRight(), temporaryList);
if (node.getData() != null) temporaryList.add(node.getData());
}
public Iterator<E> iteratorPostOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
postorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE LEVEL ORDER
/*
* Qui si usa il metodo levelorder.
* Si analizza tutto il livello dell'albero.
* Per chiarire di seguito un esempio:
*
* A
* / \
* B C
* / \ \
* D E F
*
* La lettura avviene quindi in questo modo:
* A - B - C - D - E - F
*
* Si adopera una coda (Queue) di tipo FI-FO (First In - First Out)
*/
protected void levelorder(BinaryNode<E> node, List<E> temporaryList) {
Queue<BinaryNode<E>> queueOfNodes = new LinkedList<BinaryNode<E>>();
BinaryNode<E> current;
queueOfNodes.add(node);
while(!queueOfNodes.isEmpty()) {
current = queueOfNodes.remove();
if (current.getData() != null) temporaryList.add(current.getData());
if (current.getLeft() != null) queueOfNodes.add(current.getLeft());
if (current.getRight() != null) queueOfNodes.add(current.getRight());
}
}
public Iterator<E> iteratorLevelOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
levelorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE
public Iterator<E> iterator() {
return iteratorPreOrder();
}
// ITERATORE PREORDER ITERATIVO (NON RICORSIVO)
/*
* In questo caso stiamo usando un tipo stack.
* Dobbiamo di fatto simulare uno stack se vogliamo
* iterativamente fare questa cosa.
*
* Perchè se prima dobbiamo visitare il nodo centrale,
* poi il nodo a sinistra e poi il nodo a destra inseriamo
* prima quello di destra e poi quello di sinistra?
*
* Lo stack di fatto è una coda LIFO, ovvero last in - first out
* e quindi l'ultimo che entra è il primo che esce.
*
* dal momento che vale questa cosa, se facciamo entrare prima quello
* di destra e poi quello di sinistra, il primo nodo che verrà
* prelevato è ovviamente quello a sinistra.
*/
protected void itpreorder (BinaryNode<E> node, List<E> temporaryList) {
Stack<BinaryNode<E>> queueOfNodes = new Stack<BinaryNode<E>>();
BinaryNode<E> current;
queueOfNodes.add(node);
while (!queueOfNodes.isEmpty()) {
current = queueOfNodes.pop();
if (current.getData() != null) temporaryList.add(current.getData());
// Come già spiegato pushamo prima il nodo di destra
if (current.getRight() != null) queueOfNodes.push(current.getRight());
// Infine aggiungiamo il nodo di sinistra
if (current.getLeft() != null) queueOfNodes.push(current.getLeft());
}
}
public Iterator<E> ititeratorPreOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
itpreorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATOR INORDER ITERATIVO (NON RICORSIVO)
/*
* Questo metodo riguarda lo stesso di quello superiore.
* Il metodo inorder richiede che si visiti prima sinistra,
* poi il nodo stesso, infine il nodo di destra.
*
* Possiamo quindi sempre adoperare uno Stack per siumlare la
* ricorsione.
*
* Come detto prima, se il primo nodo ad essere prelevato è
* l'ultimo che si inserisce (coda LIFO, Stack) allora per simulare
* sinistra -> centro -> destra.
*
* Nel metodo sono state inserite delle check con uno stack di
* flag che permette di capire quando il nodo centrale è visitare
* oppure no.
*/
private void itinorder(BinaryNode<E> node, List<E> temporaryList) {
Stack<BinaryNode<E>> queueOfNodes = new Stack<BinaryNode<E>>();
Stack<Boolean> flags = new Stack<Boolean>();
BinaryNode<E> current;
Boolean flag;
queueOfNodes.add(node);
flags.push(false);
while (!queueOfNodes.isEmpty()) {
current = queueOfNodes.pop();
flag = flags.pop();
if (flag) {
// il nodo è da visitare
if (current.getData() != null) temporaryList.add(current.getData());
} else {
// il nodo non è da visitare
// prima si aggiunge il nodo di destra
if (current.getRight() != null) {
queueOfNodes.add(current.getRight());
flags.add(false);
}
queueOfNodes.push(current);
flags.push(true);
if (current.getLeft() != null) {
queueOfNodes.add(current.getLeft());
flags.push(false);
}
}
}
}
public Iterator<E> ititeratorInOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
itinorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATOR POST ORDER ITERATIVO (NON RICORSIVO)
/*
* In questo caso la logica è la seguente. si ha la
* necessità di fare il seguente ciclo: SINISTRA -> DESTRA -> NODO CORRENTE
*
* Per simulare lo stack dobbiamo quindi ripercorrerlo al contrario,
* dunque NODO CORRENTE -> DESTRA -> SINISTRA
*
* Possiamo dunque rifare lo stesso, di ciò che abbiamo fatto sopra.
*/
protected void itpostorder(BinaryNode<E> node, List<E> temporaryList) {
Stack<BinaryNode<E>> queueOfNodes = new Stack<BinaryNode<E>>();
Stack<Boolean> flags = new Stack<Boolean>();
BinaryNode<E> current;
Boolean flag;
queueOfNodes.push(node);
flags.push(false);
while (!queueOfNodes.isEmpty()) {
current = queueOfNodes.pop();
flag = flags.pop();
if (flag) {
// il nodo è da visitare
if (current.getData() != null) temporaryList.add(current.getData());
} else {
// il nodo non è ancora da visitare
// Visitiamo il nodo corrente
queueOfNodes.push(current);
flags.push(true);
// visitiamo il nodo di destra
if (current.getRight() != null) {
queueOfNodes.push(current.getRight());
flags.push(false);
}
// visitiamo il nodo di sinistra infine
if (current.getLeft() != null) {
queueOfNodes.push(current.getLeft());
flags.push(false);
}
}
}
}
public Iterator<E> ititeratorPostOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
itpostorder(root, temporaryList);
return temporaryList.iterator();
}
/*
* II parziale 2022/2023
* Realizzare un metodo costruttore della classe LinkedBinaryTree<E> che
* prende in input una lista di oggetti di tipo E e costruisce una catena
* casuale tale che l'iesimo elemento della lista è posizionato al livello iesimo
* della catena e ogni nodo ha probabilità 1/2 di avere un figlio sinistro/destro.
*/
/*
* Spiegazione intuitiva (visto che la melideo intende complicare la consegna):
* Data ad esempio una lista del genere:
* [A, B, C, D]
*
* Si ottiene quindi una catena del genere:
* A
* \
* B
* /
* C
* \
* D
*/
public LinkedBinaryTree(List<E> objectList) {
if (objectList == null) throw new NullPointerException();
Iterator<E> iterator = objectList.iterator();
if (!iterator.hasNext()) return;
BinaryNode<E> currentNode = root;
E currentObject = iterator.next();
currentNode.setData(currentObject);
while (iterator.hasNext()) {
currentObject = iterator.next();
int wing = (int) (Math.random() * 2);
BinaryNode<E> newNode = new BinaryNode<E>(currentObject);
//newNode.setParent(currentNode);
if (wing == 0) {
// Left Wing
newNode.setParentAsLeftChild(currentNode);
} else {
// Right Wing
}
}
}
}
@@ -0,0 +1,16 @@
package jcf_set.example;
public class InteriRipetuti {
public static void main(String[] Args) {
}
public void run() {
int N = 20;
int MAX_INT = 50;
}
}
@@ -0,0 +1,15 @@
package queue;
import java.util.ArrayList;
import java.util.List;
public class ArrayListQueue<T> implements MyQueue<T> {
private List<T> queue = new ArrayList<T>();
@Override
public boolean offer(T item) {
return queue.add(item);
}
}
@@ -0,0 +1,79 @@
package vettore_ordinabile;
public abstract class VettoreOrdinabile {
// Variabili di istanza
private Object[] vettore; // Vettore dove memorizzare i dati
private int dimensioneMassima;
private int dimensioneCorrente;
// Costruttore
public VettoreOrdinabile(int dimensioneMassima) {
if (dimensioneMassima < 0) throw new IllegalArgumentException("La dimensione non può essere negativa");
this.dimensioneMassima = dimensioneMassima;
}
// FUNZIONI DI ISTANZA
/**
* Funzione aggiungi.
* Permette di aggiungere un elemento se la dimensione lo permette.
*/
public boolean aggiungi(Object elemento) {
if (elemento != null && dimensioneCorrente < dimensioneMassima) {
vettore[dimensioneCorrente] = elemento;
dimensioneCorrente++;
return true;
} else return false;
}
/**
* Funzione leggi.
* Permette di leggere un elemento ad una determinata posizione.
*/
public Object leggi(int indice) {
if (indice >= 0 && indice < dimensioneCorrente) {
return vettore[indice];
} else return null;
}
/**
* Funzione che restituisce la dimensione corrente
*/
public int dimensione() {
return dimensioneCorrente;
}
/**
* Funzione che visualizza l'array
*/
public void visualizza() {
this.ordina();
for (int i = 0; i < this.dimensioneMassima; i++) {
System.out.println(leggi(i));
}
}
/**
* Funzione che ordina l'array
*/
public void ordina() {
for (int i = 0; i < dimensioneCorrente; i++) {
int minimo = i;
int j;
for (j = i+1; j < dimensioneCorrente; j++) {
if (confronta(vettore[minimo], vettore[j]) > 0) minimo = j;
}
Object temp = vettore[minimo];
vettore[minimo] = vettore[j];
vettore[j] = temp;
}
}
// FUNZIONI ASTRATTE
/**
* Funzione che restituisce il valore della comparazione
*/
protected abstract int confronta(Object elemento1, Object elemento2);
}
@@ -0,0 +1,103 @@
package binary_tree;
public class LinkedBinaryTree<E> implements BinaryTree<E>{
// VARIABILI D'INSTANZA
private BinaryNode<E> root;
private int size;
// Metodi costruttori
public LinkedBinaryTree() {
root = null;
size = 0;
}
public LinkedBinaryTree(E data) {
root = new BinaryNode<E>(data);
size = 1;
}
public LinkedBinaryTree(LinkedBinaryTree<E> left, E data, LinkedBinaryTree<E> right) {
root = new BinaryNode<E>(left.root, data, right.root);
size = 1 + left.size + right.size;
}
// METODI
public int size() {
return size;
}
@Override
public boolean isEmpty() {
return root == null;
}
public E getRoot() {
if (isEmpty()) return null;
return root.getData();
}
public BinaryNode<E> getRootNode() {
if (isEmpty()) return null;
return root;
}
public void clear() {
root = null;
size = 0;
}
private int getSize(BinaryNode<E> node) {
if (node == null) return 0;
int nLeft = (node.getLeft() == null) ? 0 : getSize(node.getLeft());
int nRight = (node.getRight() == null) ? 0 : getSize(node.getRight());
return 1 + nLeft + nRight;
}
public LinkedBinaryTree<E> removeLeft() {
LinkedBinaryTree<E> leftTree = null;
if (root.getLeft() == null) return leftTree;
leftTree = new LinkedBinaryTree<E>();
leftTree.root = root.getLeft();
leftTree.size = getSize(root.getLeft());
leftTree.root.setAsRoot();
size = size - leftTree.size;
return leftTree;
}
public LinkedBinaryTree<E> removeRight() {
LinkedBinaryTree<E> rightTree = null;
if (root.getRight() == null) return rightTree;
rightTree = new LinkedBinaryTree<E>();
rightTree.root = root.getRight();
rightTree.size = getSize(root.getRight());
rightTree.root.setAsRoot();
size = size - rightTree.size;
return rightTree;
}
protected BinaryNode<E> find(E targetElement, BinaryNode<E> root) {
if (root == null) return null;
if (root.getData().equals(targetElement)) return root;
BinaryNode<E> resNode;
resNode = find(targetElement, root.getLeft());
if (resNode == null) resNode = find(targetElement, root.getRight());
return resNode;
}
public boolean remove(E targetElement) {
if (targetElement == null) return false;
BinaryNode<E> temp = find(targetElement, root);
}
}
@@ -0,0 +1,17 @@
package comparatori.videogioco;
public class Videogioco implements Comparable<Videogioco>{
// Campi di istanza
private String titolo;
private String piattaforma;
private Integer annoUscita;
private Double prezzo;
private Integer voto;
// Costruttore
private Videogioco() {}
public
}
@@ -0,0 +1,29 @@
package queue;
import java.util.ArrayList;
import java.util.List;
public class ArrayListQueue<T> implements MyQueue<T> {
private List<T> queue = new ArrayList<T>();
@Override
public boolean offer(T item) {
return queue.add(item);
}
@Override
public T remove() {
return queue.removeFirst();
}
@Override
public T peek() {
return queue.getFirst();
}
@Override
public int size() {
return queue.getSize();
}
}
@@ -0,0 +1,74 @@
package binary_tree;
public class BinaryNode<E> {
// VARIABILI
private BinaryNode<E> left, right, parent;
private E data;
// COSTRUTTORI
public BinaryNode(E data) {
this.data = data;
left = right = parent = null;
}
public BinaryNode(BinaryNode<E> left, E data, BinaryNode<E> right) {
this.data = data;
this.left = left;
this.right = right;
this.parent = null;
if (this.left != null) this.left.parent = this;
if (this.right != null) this.right.parent = this;
}
// METODI
public E getData() {
return data;
}
public BinaryNode<E> getLeft() {
return left;
}
public BinaryNode<E> getRight() {
return right;
}
public BinaryNode<E> getParent() {
return parent;
}
public boolean isRoot() {
return parent == null;
}
public boolean isLeftChild() {
return parent != null && parent.getLeft() == this;
}
public boolean isRightChild() {
return parent != null && parent.getRight() == this;
}
public void setData(E data) {
this.data = data;
}
public void setLeft(BinaryNode<E> left) {
this.left = left;
if (this.left != null) this.left.parent = this;
}
public void setRight(BinaryNode<E> right) {
this.right = right;
if (this.right != null)
}
}
@@ -0,0 +1,22 @@
package stack;
public class StackExample {
public static void main(String[] Args) {
MyStack<Character> stack = new ArrayListStack<Character>();
Character a = 'a';
Character b = 'b';
Character c = 'c';
Character d = 'd';
stack.push(a);
stack.push(b);
stack.push(c);
stack.push(d);
// Svuotiamo lo stack
}
}
@@ -0,0 +1,324 @@
package binary_tree;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Stack;
public class LinkedBinaryTree<E> implements BinaryTree<E>{
// VARIABILI D'INSTANZA
private BinaryNode<E> root;
private int size;
// Metodi costruttori
public LinkedBinaryTree() {
root = null;
size = 0;
}
public LinkedBinaryTree(E data) {
root = new BinaryNode<E>(data);
size = 1;
}
public LinkedBinaryTree(LinkedBinaryTree<E> left, E data, LinkedBinaryTree<E> right) {
root = new BinaryNode<E>(left.root, data, right.root);
size = 1 + left.size + right.size;
}
// METODI
public int size() {
return size;
}
@Override
public boolean isEmpty() {
return root == null;
}
public E getRoot() {
if (isEmpty()) return null;
return root.getData();
}
public BinaryNode<E> getRootNode() {
if (isEmpty()) return null;
return root;
}
public void clear() {
root = null;
size = 0;
}
private int getSize(BinaryNode<E> node) {
if (node == null) return 0;
int nLeft = (node.getLeft() == null) ? 0 : getSize(node.getLeft());
int nRight = (node.getRight() == null) ? 0 : getSize(node.getRight());
return 1 + nLeft + nRight;
}
public LinkedBinaryTree<E> removeLeft() {
LinkedBinaryTree<E> leftTree = null;
if (root.getLeft() == null) return leftTree;
leftTree = new LinkedBinaryTree<E>();
leftTree.root = root.getLeft();
leftTree.size = getSize(root.getLeft());
leftTree.root.setAsRoot();
size = size - leftTree.size;
return leftTree;
}
public LinkedBinaryTree<E> removeRight() {
LinkedBinaryTree<E> rightTree = null;
if (root.getRight() == null) return rightTree;
rightTree = new LinkedBinaryTree<E>();
rightTree.root = root.getRight();
rightTree.size = getSize(root.getRight());
rightTree.root.setAsRoot();
size = size - rightTree.size;
return rightTree;
}
protected BinaryNode<E> find(E targetElement, BinaryNode<E> root) {
if (root == null) return null;
if (root.getData().equals(targetElement)) return root;
BinaryNode<E> resNode;
resNode = find(targetElement, root.getLeft());
if (resNode == null) resNode = find(targetElement, root.getRight());
return resNode;
}
public boolean remove(E targetElement) {
if (targetElement == null) return false;
BinaryNode<E> temp = find(targetElement, root);
if (temp != null) {
temp.setData(null);
return true;
}
return false;
}
public boolean contains(E targetElement) {
return find(targetElement, root) != null;
}
// ITERATORE PREORDER
/*
* Qui si utilizza il metodo del preorder.
* Le regole per il preorder sono queste:
* - Visita prima se stesso
* - Poi visita tutto ciò che si trova sinistra
* - Infine visita tutto ciò che si trova a destra
*/
protected void preorder (BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
if (node.getData() != null) temporaryList.add(node.getData());
preorder(node.getLeft(), temporaryList);
preorder(node.getRight(), temporaryList);
}
public Iterator<E> iteratorPreOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
preorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE INORDER
/*
* Qui si utilizza il metodo del inorder.
* Le regole per l'inorder sono queste:
* - Visita prima tutto ciò che si trova a sinistra
* - Poi visita se stesso
* - Infine visita tutto ciò che si trova a destra
*/
protected void inorder(BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
inorder(node.getLeft(), temporaryList);
if (node.getData() != null) temporaryList.add(node.getData());
inorder(node.getRight(), temporaryList);
}
public Iterator<E> iteratorInOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
inorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE POSTORDER
/*
* Qui si utilizza il metodo postorder.
* Le regole per il postorder sono queste:
* - Visita prima di tutto ciò che si trova a sinistra
* - Poi visita tutto ciò che si trova a destra
* - Infine visita il sestesso
*/
protected void postorder(BinaryNode<E> node, List<E> temporaryList) {
if (node == null) return;
postorder(node.getLeft(), temporaryList);
postorder(node.getRight(), temporaryList);
if (node.getData() != null) temporaryList.add(node.getData());
}
public Iterator<E> iteratorPostOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
postorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE LEVEL ORDER
/*
* Qui si usa il metodo levelorder.
* Si analizza tutto il livello dell'albero.
* Per chiarire di seguito un esempio:
*
* A
* / \
* B C
* / \ \
* D E F
*
* La lettura avviene quindi in questo modo:
* A - B - C - D - E - F
*
* Si adopera una coda (Queue) di tipo FI-FO (First In - First Out)
*/
protected void levelorder(BinaryNode<E> node, List<E> temporaryList) {
Queue<BinaryNode<E>> queueOfNodes = new LinkedList<BinaryNode<E>>();
BinaryNode<E> current;
queueOfNodes.add(node);
while(!queueOfNodes.isEmpty()) {
current = queueOfNodes.remove();
if (current.getData() != null) temporaryList.add(current.getData());
if (current.getLeft() != null) queueOfNodes.add(current.getLeft());
if (current.getRight() != null) queueOfNodes.add(current.getRight());
}
}
public Iterator<E> iteratorLevelOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
levelorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATORE
public Iterator<E> iterator() {
return iteratorPreOrder();
}
// ITERATORE PREORDER ITERATIVO (NON RICORSIVO)
/*
* In questo caso stiamo usando un tipo stack.
* Dobbiamo di fatto simulare uno stack se vogliamo
* iterativamente fare questa cosa.
*
* Perchè se prima dobbiamo visitare il nodo centrale,
* poi il nodo a sinistra e poi il nodo a destra inseriamo
* prima quello di destra e poi quello di sinistra?
*
* Lo stack di fatto è una coda LIFO, ovvero last in - first out
* e quindi l'ultimo che entra è il primo che esce.
*
* dal momento che vale questa cosa, se facciamo entrare prima quello
* di destra e poi quello di sinistra, il primo nodo che verrà
* prelevato è ovviamente quello a sinistra.
*/
protected void itpreorder (BinaryNode<E> node, List<E> temporaryList) {
Stack<BinaryNode<E>> queueOfNodes = new Stack<BinaryNode<E>>();
BinaryNode<E> current;
queueOfNodes.add(node);
while (!queueOfNodes.isEmpty()) {
current = queueOfNodes.pop();
if (current.getData() != null) temporaryList.add(current.getData());
// Come già spiegato pushamo prima il nodo di destra
if (current.getRight() != null) queueOfNodes.push(current.getRight());
// Infine aggiungiamo il nodo di sinistra
if (current.getLeft() != null) queueOfNodes.push(current.getLeft());
}
}
public Iterator<E> ititeratorInOrder() {
ArrayList<E> temporaryList = new ArrayList<E>();
itpreorder(root, temporaryList);
return temporaryList.iterator();
}
// ITERATOR INORDER ITERATIVO (NON RICORSIVO)
/*
* Questo metodo riguarda lo stesso di quello superiore.
* Il metodo inorder richiede che si visiti prima sinistra,
* poi il nodo stesso, infine il nodo di destra.
*
* Possiamo quindi sempre adoperare uno Stack per siumlare la
* ricorsione.
*
* Come detto prima, se il primo nodo ad essere prelevato è
* l'ultimo che si inserisce (coda LIFO, Stack) allora per simulare
* sinistra -> centro -> destra, il primo nodo da inserire è quello di
* destra
*/
private void itinorder(BinaryNode<E> node, List<E> temporaryList) {
Stack<BinaryNode<E>> queueOfNodes = new Stack<BinaryNode<E>>();
Stack<Boolean> flags = new Stack<Boolean>();
BinaryNode<E> current;
Boolean flag;
queueOfNodes.add(node);
flags.push(false);
while (!queueOfNodes.isEmpty()) {
current = queueOfNodes.pop();
flag = flags.pop();
if (flag) {
// il nodo è da visitare
if (current.getData() != null) temporaryList.add(current.getData());
} else {
// il nodo non è da visitare
// prima si aggiunge il nodo di destra
if (current.getRight() != null) {
queueOfNodes.add(current.getRight());
}
}
}
}
}
@@ -0,0 +1,88 @@
package binary_tree;
public class LinkedBinaryTree<E> implements BinaryTree<E>{
// VARIABILI D'INSTANZA
private BinaryNode<E> root;
private int size;
// Metodi costruttori
public LinkedBinaryTree() {
root = null;
size = 0;
}
public LinkedBinaryTree(E data) {
root = new BinaryNode<E>(data);
size = 1;
}
public LinkedBinaryTree(LinkedBinaryTree<E> left, E data, LinkedBinaryTree<E> right) {
root = new BinaryNode<E>(left.root, data, right.root);
size = 1 + left.size + right.size;
}
// METODI
public int size() {
return size;
}
@Override
public boolean isEmpty() {
return root == null;
}
public E getRoot() {
if (isEmpty()) return null;
return root.getData();
}
public BinaryNode<E> getRootNode() {
if (isEmpty()) return null;
return root;
}
public void clear() {
root = null;
size = 0;
}
private int getSize(BinaryNode<E> node) {
if (node == null) return 0;
int nLeft = (node.getLeft() == null) ? 0 : getSize(node.getLeft());
int nRight = (node.getRight() == null) ? 0 : getSize(node.getRight());
return 1 + nLeft + nRight;
}
public LinkedBinaryTree<E> removeLeft() {
LinkedBinaryTree<E> leftTree = null;
if (root.getLeft() == null) return leftTree;
leftTree = new LinkedBinaryTree<E>();
leftTree.root = root.getLeft();
leftTree.size = getSize(root.getLeft());
leftTree.root.setAsRoot();
size = size - leftTree.size;
return leftTree;
}
public LinkedBinaryTree<E> removeRight() {
LinkedBinaryTree<E> rightTree = null;
if (root.getRight() == null) return rightTree;
rightTree = new LinkedBinaryTree<E>();
rightTree.root = root.getRight();
rightTree.size = getSize(root.getRight());
rightTree.root.setAsRoot();
size = size - rightTree.size;
return rightTree;
}
}
@@ -0,0 +1,41 @@
package parziale.p251110;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.ListIterator;
public class Clinica {
ArrayList<Paziente> pazienti = new ArrayList<Paziente>();
// 1. Numero di pazienti Ricoverati
public int pazientiRicoverati() {
return pazienti.size();
}
// 2. Inserimento del paziente
/*
* Dal momento che non ci è permesso adoperare
* TreeSet per l'ordine e per l'unicità
*/
public boolean ricoveraPaziente(Paziente paziente) {
// Se il paziente è nullo, nulla verrà aggiunto
if (paziente == null) return false;
// Controllo se il paziente è già presente nella lista ricoveri
Iterator<Paziente> it = pazienti.iterator();
while (it.hasNext()) {
Paziente current = it.next();
if (paziente.equals(current)) return false; // Se è già presente un paziente con id uguale allora non viene aggiunto e ritorna false
}
// Aggiunta del paziente
ListIterator<Paziente> it = pazienti.iterator();
while (it.hasNext()) {
Paziente current = it.next();
int cmp = current.compareTo(paziente);
if ()
}
}
}
@@ -0,0 +1,25 @@
package binary_tree;
public class BinaryNode<E> {
// VARIABILI
private BinaryNode<E> left, right, parent;
private E data;
// COSTRUTTORI
public BinaryNode(E data) {
this.data = data;
left = right = parent = null;
}
public BinaryNode(BinaryNode<E> left, E data, BinaryNode<E> right) {
this.data = data;
}
// METODI
}
@@ -0,0 +1,7 @@
package binary_tree;
public interface BinaryTree {
public boolean isEmpty();
}
@@ -0,0 +1,5 @@
package jcf_set.example;
public class TreeSetExample2 {
}
@@ -0,0 +1,29 @@
package vettore_ordinabile;
public class VettoriIntero extends VettoreOrdinabile{
// Metodo costruttore default
/*
* Contiene solamente 10 elementi
* */
public VettoriIntero() {
super(10);
}
// Metodo costruttore custom
/*
* Contiene n elementi
*/
public VettoriIntero(int dimensioneMassima) {
super(dimensioneMassima);
}
// Metodo aggiungi
/*
* Questo metodo è un metodo bloccante in modo che
* non aggiungino oggetti che non siano di tipo Integer
*/
@Override
public
}
@@ -0,0 +1,22 @@
package stack;
public interface MyStack<T> {
/**
* Aggiunge un elemento al top dello stack.
* @param Elemento che deve essere aggiunto nello stack.
*/
void push(T item);
/**
* Rimuove l'elemento al top dello stack.
* @return
*/
T pop();
T peek();
int size();
boolean isEmpty();
}
@@ -0,0 +1,82 @@
package binary_tree;
public class BinaryNode<E> {
// VARIABILI
private BinaryNode<E> left, right, parent;
private E data;
// COSTRUTTORI
public BinaryNode(E data) {
this.data = data;
left = right = parent = null;
}
public BinaryNode(BinaryNode<E> left, E data, BinaryNode<E> right) {
this.data = data;
this.left = left;
this.right = right;
this.parent = null;
if (this.left != null) this.left.parent = this;
if (this.right != null) this.right.parent = this;
}
// METODI
public E getData() {
return data;
}
public BinaryNode<E> getLeft() {
return left;
}
public BinaryNode<E> getRight() {
return right;
}
public BinaryNode<E> getParent() {
return parent;
}
public boolean isRoot() {
return parent == null;
}
public boolean isLeftChild() {
return parent != null && parent.getLeft() == this;
}
public boolean isRightChild() {
return parent != null && parent.getRight() == this;
}
public void setData(E data) {
this.data = data;
}
public void setLeft(BinaryNode<E> left) {
this.left = left;
if (this.left != null) this.left.parent = this;
}
public void setRight(BinaryNode<E> right) {
this.right = right;
if (this.right != null) this.right.parent = this;
}
public BinaryNode<E> setParentAsLeftChild(BinaryNode<E> parent) {
if (this.parent == null) return null;
this.parent = parent;
BinaryNode<E> oldLeft = this.parent.left;
this.parent.left = this;
return oldLeft;
}
}
@@ -0,0 +1,138 @@
package binary_tree;
public class BinaryNode<E> {
// VARIABILI
private BinaryNode<E> left, right, parent;
private E data;
// COSTRUTTORI
public BinaryNode(E data) {
this.data = data;
left = right = parent = null;
}
public BinaryNode(BinaryNode<E> left, E data, BinaryNode<E> right) {
this.data = data;
this.left = left;
this.right = right;
this.parent = null;
if (this.left != null) this.left.parent = this;
if (this.right != null) this.right.parent = this;
}
// METODI
public E getData() {
return data;
}
public BinaryNode<E> getLeft() {
return left;
}
public BinaryNode<E> getRight() {
return right;
}
public BinaryNode<E> getParent() {
return parent;
}
public boolean isRoot() {
return parent == null;
}
public boolean isLeftChild() {
return parent != null && parent.getLeft() == this;
}
public boolean isRightChild() {
return parent != null && parent.getRight() == this;
}
public void setData(E data) {
this.data = data;
}
public void setLeft(BinaryNode<E> left) {
this.left = left;
if (this.left != null) this.left.parent = this;
}
public void setRight(BinaryNode<E> right) {
this.right = right;
if (this.right != null) this.right.parent = this;
}
public BinaryNode<E> setParentAsLeftChild(BinaryNode<E> parent) {
if (parent == null) return null;
this.parent = parent;
BinaryNode<E> oldLeft = this.parent.left;
this.parent.left = this;
return oldLeft;
}
public BinaryNode<E> setParentAsRightChild(BinaryNode<E> parent) {
if (parent == null) return null;
this.parent = parent;
BinaryNode<E> oldRight = this.parent.right;
this.parent.right = this;
return oldRight;
}
public BinaryNode<E> setAsRoot() {
if (parent == null) return null;
BinaryNode<E> oldParent = parent;
parent = null;
if (oldParent.left == this) oldParent.left = null;
else oldParent.right = null;
return oldParent;
}
public boolean hasLeft() {
return left != null;
}
public boolean hasRight() {
return right != null;
}
@Override
public boolean equals(Object other) {
if (other == null) return false;
if (other == this) return true;
if (!(other instanceof BinaryNode<?>)) return false;
BinaryNode<?> otherType = (BinaryNode<?>)other;
if (!data.equals(otherType.data) || hasLeft() != otherType.hasLeft() || hasRight() != otherType.hasRight()) return false;
if (this.left != null && !left.equals(otherType.left)) return false;
if (this.right != null && !right.equals(otherType.right)) return false;
return true;
}
public int levelOf() {
int d = 0;
BinaryNode<E> cur = this;
while (cur.parent != null){
d++;
cur = cur.parent;
}
}
}
@@ -0,0 +1,30 @@
package jcf_set.example;
import java.util.TreeSet;
public class TreeSetExample2 {
public static void main(String[] Args) {
}
public void run() {
TreeSet<String> tree1 = new TreeSet<String>();
tree1.add("yes");
tree1.add("no");
tree1.add("maybe");
tree1.add("always");
tree1.add("no");
System.out.println("Stampa del TreeSet1: ");
System.out.println(tree1);
TreeSet<String> tree2 = new TreeSet<String>(tree1);
System.out.println("Stampa del TreeSet1: ");
System.out.println(tree1);
}
}
@@ -0,0 +1,105 @@
package binary_tree;
public class LinkedBinaryTree<E> implements BinaryTree<E>{
// VARIABILI D'INSTANZA
private BinaryNode<E> root;
private int size;
// Metodi costruttori
public LinkedBinaryTree() {
root = null;
size = 0;
}
public LinkedBinaryTree(E data) {
root = new BinaryNode<E>(data);
size = 1;
}
public LinkedBinaryTree(LinkedBinaryTree<E> left, E data, LinkedBinaryTree<E> right) {
root = new BinaryNode<E>(left.root, data, right.root);
size = 1 + left.size + right.size;
}
// METODI
public int size() {
return size;
}
@Override
public boolean isEmpty() {
return root == null;
}
public E getRoot() {
if (isEmpty()) return null;
return root.getData();
}
public BinaryNode<E> getRootNode() {
if (isEmpty()) return null;
return root;
}
public void clear() {
root = null;
size = 0;
}
private int getSize(BinaryNode<E> node) {
if (node == null) return 0;
int nLeft = (node.getLeft() == null) ? 0 : getSize(node.getLeft());
int nRight = (node.getRight() == null) ? 0 : getSize(node.getRight());
return 1 + nLeft + nRight;
}
public LinkedBinaryTree<E> removeLeft() {
LinkedBinaryTree<E> leftTree = null;
if (root.getLeft() == null) return leftTree;
leftTree = new LinkedBinaryTree<E>();
leftTree.root = root.getLeft();
leftTree.size = getSize(root.getLeft());
leftTree.root.setAsRoot();
size = size - leftTree.size;
return leftTree;
}
public LinkedBinaryTree<E> removeRight() {
LinkedBinaryTree<E> rightTree = null;
if (root.getRight() == null) return rightTree;
rightTree = new LinkedBinaryTree<E>();
rightTree.root = root.getRight();
rightTree.size = getSize(root.getRight());
rightTree.root.setAsRoot();
size = size - rightTree.size;
return rightTree;
}
protected BinaryNode<E> find(E targetElement, BinaryNode<E> root) {
if (root == null) return null;
if (root.getData().equals(targetElement)) return root;
BinaryNode<E> resNode;
resNode = find(targetElement, root.getLeft());
if (resNode == null) resNode = find(targetElement, root.getRight());
return resNode;
}
public boolean remove(E targetElement) {
if (targetElement == null) return false;
BinaryNode<E> temp = find(targetElement, root);
if (temp != null) {
} else return false;
}
}
@@ -0,0 +1,36 @@
package comparatori.videogioco;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Main {
public static void main(String[] Args) {
ArrayList<Videogioco> giochi = new ArrayList<Videogioco>();
giochi.add(new Videogioco("The Last of Us Part II", "PS5", 2020, 39.99, 9));
giochi.add(new Videogioco("Cyberpunk 2077", "PC", 2020, 29.99, 8));
giochi.add(new Videogioco("Minecraft", "PC", 2011, 19.99, 10));
giochi.add(new Videogioco("Ghost of Tsushima", "PS5", 2020, 49.99, 9));
giochi.add(new Videogioco("Resident Evil 4 Remake", "PS5", 2023, 44.99, 9));
giochi.add(new Videogioco("GTA V", "PC", 2013, 14.99, 8));
giochi.add(new Videogioco("God of War Ragnarok", "PS5", 2022, 59.99, 10));
giochi.add(new Videogioco("Fortnite", "PC", 2017, 0.0, 7));
// Per adoperare il comparable
Collections.sort(giochi);
}
private <T> void printList(List<T> lista) {
System.out.print("{");
for (int i = 0; i < lista.size(); i++) {
System.out.print
}
}
}

Some files were not shown because too many files have changed in this diff Show More