mac->arch

This commit is contained in:
eslusarz
2026-05-19 13:42:21 +02:00
parent 646f4dc077
commit 30b66dd99b
305 changed files with 1617 additions and 31630 deletions
+1
View File
@@ -0,0 +1 @@
/.metadata/
+3 -3
View File
@@ -1,4 +1,4 @@
#Tue May 12 13:59:16 CEST 2026 #Tue May 12 15:01:46 CEST 2026
host=DESKTOP-ALBQHEK host=eslusarzs-MacBook-Pro.local
process-id=5624 process-id=23862
user=eslusarz user=eslusarz
+168
View File
@@ -891,3 +891,171 @@ user global configuration and to define the default location to store repositori
not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and
EGit might behave differently since they see different configuration options. EGit might behave differently since they see different configuration options.
This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. This warning can be switched off on the Team > Git > Confirmations and Warnings preference page.
!SESSION 2026-05-12 15:01:42.681 -----------------------------------------------
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-12 15:01:43.636
!MESSAGE Activated before the state location was initialized. Retry after the state location is initialized.
!ENTRY org.eclipse.core.resources 2 10035 2026-05-12 15:01:46.121
!MESSAGE The workspace exited with unsaved changes in the previous session; refreshing workspace to recover changes.
!ENTRY org.eclipse.core.resources 4 567 2026-05-12 15:01:46.173
!MESSAGE Workspace restored, but some problems occurred.
!SUBENTRY 1 org.eclipse.core.resources 4 567 2026-05-12 15:01:46.173
!MESSAGE Could not read metadata for '.org.eclipse.egit.core.cmp'.
!STACK 1
org.eclipse.core.internal.resources.ResourceException(/.org.eclipse.egit.core.cmp)[567]: java.lang.Exception: The project description file (.project) for '.org.eclipse.egit.core.cmp' is missing. This file contains important information about the project. The project will not function properly until this file is restored.
at org.eclipse.core.internal.resources.ResourceException.provideStackTrace(ResourceException.java:42)
at org.eclipse.core.internal.resources.ResourceException.<init>(ResourceException.java:38)
at org.eclipse.core.internal.localstore.FileSystemResourceManager.read(FileSystemResourceManager.java:1015)
at org.eclipse.core.internal.resources.SaveManager.restoreMetaInfo(SaveManager.java:1004)
at org.eclipse.core.internal.resources.SaveManager.restoreMetaInfo(SaveManager.java:983)
at org.eclipse.core.internal.resources.SaveManager.restore(SaveManager.java:825)
at org.eclipse.core.internal.resources.SaveManager.startup(SaveManager.java:1689)
at org.eclipse.core.internal.resources.Workspace.startup(Workspace.java:2677)
at org.eclipse.core.internal.resources.Workspace.open(Workspace.java:2369)
at org.eclipse.core.resources.ResourcesPlugin$WorkspaceInitCustomizer.addingService(ResourcesPlugin.java:591)
at org.eclipse.core.resources.ResourcesPlugin$WorkspaceInitCustomizer.addingService(ResourcesPlugin.java:1)
at org.osgi.util.tracker.ServiceTracker$Tracked.customizerAdding(ServiceTracker.java:947)
at org.osgi.util.tracker.ServiceTracker$Tracked.customizerAdding(ServiceTracker.java:1)
at org.osgi.util.tracker.AbstractTracked.trackAdding(AbstractTracked.java:257)
at org.osgi.util.tracker.AbstractTracked.trackInitial(AbstractTracked.java:184)
at org.osgi.util.tracker.ServiceTracker.open(ServiceTracker.java:324)
at org.osgi.util.tracker.ServiceTracker.open(ServiceTracker.java:267)
at org.eclipse.core.resources.ResourcesPlugin.start(ResourcesPlugin.java:565)
at org.eclipse.osgi.internal.framework.BundleContextImpl$2.run(BundleContextImpl.java:838)
at org.eclipse.osgi.internal.framework.BundleContextImpl$2.run(BundleContextImpl.java:1)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:571)
at org.eclipse.osgi.internal.framework.BundleContextImpl.startActivator(BundleContextImpl.java:830)
at org.eclipse.osgi.internal.framework.BundleContextImpl.start(BundleContextImpl.java:780)
at org.eclipse.osgi.internal.framework.EquinoxBundle.startWorker0(EquinoxBundle.java:1082)
at org.eclipse.osgi.internal.framework.EquinoxBundle$EquinoxModule.startWorker(EquinoxBundle.java:394)
at org.eclipse.osgi.container.Module.doStart(Module.java:643)
at org.eclipse.osgi.container.Module.start(Module.java:500)
at org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:528)
at org.eclipse.osgi.internal.hooks.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:122)
at org.eclipse.osgi.internal.loader.classpath.ClasspathManager.findLocalClass(ClasspathManager.java:620)
at org.eclipse.osgi.internal.loader.ModuleClassLoader.findLocalClass(ModuleClassLoader.java:353)
at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:418)
at org.eclipse.osgi.internal.loader.sources.SingleSourcePackage.loadClass(SingleSourcePackage.java:41)
at org.eclipse.osgi.internal.loader.BundleLoader.findClass0(BundleLoader.java:523)
at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:439)
at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:195)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:526)
at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:186)
at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:219)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:149)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:115)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:467)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:298)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:615)
at org.eclipse.equinox.launcher.Main.basicRun(Main.java:563)
at org.eclipse.equinox.launcher.Main.run(Main.java:1415)
!SUBENTRY 2 org.eclipse.core.resources 4 567 2026-05-12 15:01:46.174
!MESSAGE The project description file (.project) for '.org.eclipse.egit.core.cmp' is missing. This file contains important information about the project. The project will not function properly until this file is restored.
!STACK 0
java.lang.Exception: The project description file (.project) for '.org.eclipse.egit.core.cmp' is missing. This file contains important information about the project. The project will not function properly until this file is restored.
at org.eclipse.core.internal.resources.ResourceException.provideStackTrace(ResourceException.java:42)
at org.eclipse.core.internal.resources.ResourceException.<init>(ResourceException.java:38)
at org.eclipse.core.internal.localstore.FileSystemResourceManager.read(FileSystemResourceManager.java:1015)
at org.eclipse.core.internal.resources.SaveManager.restoreMetaInfo(SaveManager.java:1004)
at org.eclipse.core.internal.resources.SaveManager.restoreMetaInfo(SaveManager.java:983)
at org.eclipse.core.internal.resources.SaveManager.restore(SaveManager.java:825)
at org.eclipse.core.internal.resources.SaveManager.startup(SaveManager.java:1689)
at org.eclipse.core.internal.resources.Workspace.startup(Workspace.java:2677)
at org.eclipse.core.internal.resources.Workspace.open(Workspace.java:2369)
at org.eclipse.core.resources.ResourcesPlugin$WorkspaceInitCustomizer.addingService(ResourcesPlugin.java:591)
at org.eclipse.core.resources.ResourcesPlugin$WorkspaceInitCustomizer.addingService(ResourcesPlugin.java:1)
at org.osgi.util.tracker.ServiceTracker$Tracked.customizerAdding(ServiceTracker.java:947)
at org.osgi.util.tracker.ServiceTracker$Tracked.customizerAdding(ServiceTracker.java:1)
at org.osgi.util.tracker.AbstractTracked.trackAdding(AbstractTracked.java:257)
at org.osgi.util.tracker.AbstractTracked.trackInitial(AbstractTracked.java:184)
at org.osgi.util.tracker.ServiceTracker.open(ServiceTracker.java:324)
at org.osgi.util.tracker.ServiceTracker.open(ServiceTracker.java:267)
at org.eclipse.core.resources.ResourcesPlugin.start(ResourcesPlugin.java:565)
at org.eclipse.osgi.internal.framework.BundleContextImpl$2.run(BundleContextImpl.java:838)
at org.eclipse.osgi.internal.framework.BundleContextImpl$2.run(BundleContextImpl.java:1)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:571)
at org.eclipse.osgi.internal.framework.BundleContextImpl.startActivator(BundleContextImpl.java:830)
at org.eclipse.osgi.internal.framework.BundleContextImpl.start(BundleContextImpl.java:780)
at org.eclipse.osgi.internal.framework.EquinoxBundle.startWorker0(EquinoxBundle.java:1082)
at org.eclipse.osgi.internal.framework.EquinoxBundle$EquinoxModule.startWorker(EquinoxBundle.java:394)
at org.eclipse.osgi.container.Module.doStart(Module.java:643)
at org.eclipse.osgi.container.Module.start(Module.java:500)
at org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:528)
at org.eclipse.osgi.internal.hooks.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:122)
at org.eclipse.osgi.internal.loader.classpath.ClasspathManager.findLocalClass(ClasspathManager.java:620)
at org.eclipse.osgi.internal.loader.ModuleClassLoader.findLocalClass(ModuleClassLoader.java:353)
at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:418)
at org.eclipse.osgi.internal.loader.sources.SingleSourcePackage.loadClass(SingleSourcePackage.java:41)
at org.eclipse.osgi.internal.loader.BundleLoader.findClass0(BundleLoader.java:523)
at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:439)
at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:195)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:526)
at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:186)
at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:219)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:149)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:115)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:467)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:298)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:615)
at org.eclipse.equinox.launcher.Main.basicRun(Main.java:563)
at org.eclipse.equinox.launcher.Main.run(Main.java:1415)
!ENTRY ch.qos.logback.classic 1 0 2026-05-12 15:01:46.409
!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-13 12:09:02.056
!MESSAGE AbortCompilation computing hover information in Graph.java at offset 199
!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 9 :
-----
package network;
public interface Graph<Vertex, Wheight> implements Iterable<Vertex> {
public boolean containsVertex(Vertex vertex);
public boolean addVertex(Vertex vertex);
public boolean |removeVertex(Vertex vertex);
-----
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
@@ -1,491 +0,0 @@
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
}
}
@@ -1,35 +0,0 @@
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);
}
}
@@ -1,492 +0,0 @@
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
}
}
@@ -1,30 +0,0 @@
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;
}
}
@@ -1,17 +0,0 @@
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;
}
}
@@ -1,39 +0,0 @@
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("}");
}
}
@@ -1,30 +0,0 @@
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
}
}
}
}
@@ -1,494 +0,0 @@
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
*/
}
@@ -1,48 +0,0 @@
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;
}
}
@@ -1,31 +0,0 @@
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;
}
}
@@ -1,16 +0,0 @@
package jcf_set.example;
public class InteriRipetuti {
public static void main(String[] Args) {
}
public void run() {
int N = 20;
int MAX_INT = 50;
// HASHSET
}
}
@@ -1,500 +0,0 @@
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;
}
}
@@ -1,502 +0,0 @@
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
}
}
@@ -1,39 +0,0 @@
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("}");
}
}
@@ -1,26 +0,0 @@
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);
}
}
@@ -1,16 +0,0 @@
package jcf_set.example;
public class InteriRipetuti {
public static void main(String[] Args) {
}
public void run() {
int N = 20;
int MAX_INT = 50;
}
}
@@ -1,17 +0,0 @@
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
}
@@ -1,36 +0,0 @@
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
}
}
}
@@ -1,26 +0,0 @@
package comparatori.videogioco;
import java.util.ArrayList;
import java.util.Collection;
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
List.sort(giochi);
}
}
@@ -1,18 +0,0 @@
package comparatori.videogioco;
import java.util.Comparator;
public class ComparatorVideogioco3 implements Comparator<Videogioco> {
/**
* Prima ordina per piattaforma alfabetica.
* Se la piattaforma è uguale, per anno
* di uscita crescente
* se l'anno è uguale, allora per titolo alfabetico
*/
@Override
public int compare(Videogioco v1, Videogioco v2) {
int cpm =
}
}
@@ -1,55 +0,0 @@
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;
}
// Getter
public String titolo() {
return titolo;
}
public String piattaforma() {
return piattaforma;
}
public Integer annoUscita() {
return annoUscita;
}
public Double prezzo() {
return prezzo;
}
public Integer voto() {
return voto;
}
// Implementazione del metodo comparatore
/**
* compareTo ordina per prezzo crescente
*/
}
@@ -1,515 +0,0 @@
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
if (!node.hasLeft() && !node.hasRight()) return; // Se il nodo è una foglia non ha bisogno di fare operazioni
BinaryNode<E> copy;
if (!node.hasLeft()) {
// Si copia il figlio destro in quello sinistro
copy = new BinaryNode<E>(node.getRight().getData());
node.setLeft(copy);
copy.setParentAsLeftChild(node);
} else {
copy = new BinaryNode<E>(node.getLeft().getData());
node.setRight(copy);
copy.setParentAsRightChild(node);
}
}
}
@@ -1,28 +0,0 @@
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;
}
}
@@ -1,37 +0,0 @@
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);
// TREESET (ordinato)
}
}
@@ -1,9 +0,0 @@
package comparatori.videogioco;
public class Main {
public static void main(String[] Args) {
}
}
@@ -1,34 +0,0 @@
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)) {
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)
}
}
@@ -1,27 +0,0 @@
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() && )
}
}
@@ -1,11 +0,0 @@
package comparatori.videogioco;
public class Main {
public static void main(String[] Args) {
ArrayList<Videogioco> giochi = new ArrayList<Videogioco>();
}
}
@@ -1,503 +0,0 @@
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
}
}
@@ -1,500 +0,0 @@
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() {
}
public void makeFull(BinaryNode<E node) {
}
}
@@ -1,49 +0,0 @@
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
System.out.println("ordina per prezzo crescente");
Collections.sort(giochi);
printList(giochi);
// Ordina i videogiochi per titolo alfabetico crescente
System.out.println("Ordina i videogiochi per titolo alfabetico crescente");
Collections.sort(giochi, new ComparatorVideogioco1());
printList(giochi);
// Ordina dal voto più alto al più basso
System.out.println("Ordina dal voto più alto al più basso");
Collections.sort(giochi, new ComparatorVideogioco1());
printList(giochi);
}
private static <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("}");
}
}
@@ -1,51 +0,0 @@
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;
}
// Getter
public String titolo() {
return titolo;
}
public String piattaforma() {
return piattaforma;
}
public Integer annoUscita() {
return annoUscita;
}
public Double prezzo() {
return prezzo;
}
public Integer voto() {
return voto;
}
}
@@ -1,63 +0,0 @@
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;
}
// Getter
public String titolo() {
return titolo;
}
public String piattaforma() {
return piattaforma;
}
public Integer annoUscita() {
return annoUscita;
}
public Double prezzo() {
return prezzo;
}
public Integer voto() {
return voto;
}
// Implementazione del metodo comparatore
/**
* compareTo ordina per prezzo crescente
*/
@Override
public int compareTo(Videogioco videogioco) {
if (this.prezzo < videogioco.prezzo) return -1;
if (this.prezzo > videogioco.prezzo) return 1;
return 0;
}
}
@@ -1,41 +0,0 @@
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);
// Ordina i videogiochi per titolo alfabetico crescente
}
private static <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("}");
}
}
@@ -1,41 +0,0 @@
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 static <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("}");
}
}
@@ -1,61 +0,0 @@
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;
}
// Getter
public String titolo() {
return titolo;
}
public String piattaforma() {
return piattaforma;
}
public Integer annoUscita() {
return annoUscita;
}
public Double prezzo() {
return prezzo;
}
public Integer voto() {
return voto;
}
// Implementazione del metodo comparatore
/**
* compareTo ordina per prezzo crescente
*/
@Override
public int compareTo(Videogioco videogioco) {
if (this.prezzo < videogioco.prezzo) return -1;
if (this.prezzo > videogioco.prezzo) return 1;
return 0;
}
}
@@ -1,511 +0,0 @@
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
if (!node.hasLeft() && !node.hasRight()) return; // Se il nodo è una foglia non ha bisogno di fare operazioni
BinaryNode<E> copy;
if (!node.hasLeft()) {
// Si copia il figlio destro in quello sinistro
copy =
} else {
}
}
}
@@ -1,38 +0,0 @@
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 (non ordinato)
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);
// TREESET (ordinato)
}
}
@@ -1,43 +0,0 @@
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
System.out.println("ordina per prezzo crescente");
Collections.sort(giochi);
printList(giochi);
// Ordina i videogiochi per titolo alfabetico crescente
Collections.sort(giochi, new ComparatorVideogioco1());
printList(giochi);
}
private static <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("}");
}
}
@@ -1,64 +0,0 @@
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;
}
// Getter
public String titolo() {
return titolo;
}
public String piattaforma() {
return piattaforma;
}
public Integer annoUscita() {
return annoUscita;
}
public Double prezzo() {
return prezzo;
}
public Integer voto() {
return voto;
}
// Implementazione del metodo comparatore
/**
* compareTo ordina per prezzo crescente
*/
@Override
public int compareTo(Videogioco videogioco) {
if (this.prezzo < videogioco.prezzo) return -1;
if (this.prezzo > videogioco.prezzo) return 1;
return 0;
}
@Override
}
@@ -1,51 +0,0 @@
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();
if (!iterator.hasNext()) return null;
Integer maxValue = iterator.next();
while (iterator.hasNext()) {
Integer current = iterator.next();
}
}
}
@@ -1,511 +0,0 @@
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
if (!node.hasLeft() && !node.hasRight()) return; // Se il nodo è una foglia non ha bisogno di fare operazioni
BinaryNode<E> copy;
if (!node.hasLeft()) {
// Si copia il figlio destro in quello sinistro
} else {
}
}
}
@@ -1,18 +0,0 @@
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;
}
}
@@ -1,41 +0,0 @@
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);
// Ordina i videogiochi per titolo alfabetico crescente
}
private static <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("}");
}
}
@@ -1,33 +0,0 @@
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;
}
// Getter
public String titolo() {
return titolo;
}
}
@@ -1,26 +0,0 @@
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();
}
}
@@ -1,27 +0,0 @@
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;
}
}
@@ -1,491 +0,0 @@
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 (node.getLeft() == null && node.getRight() == null) return 1;
return n
}
}
@@ -1,31 +0,0 @@
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;
}
}
@@ -1,51 +0,0 @@
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
System.out.println("ordina per prezzo crescente");
Collections.sort(giochi);
printList(giochi);
// Ordina i videogiochi per titolo alfabetico crescente
System.out.println("Ordina i videogiochi per titolo alfabetico crescente");
Collections.sort(giochi, new ComparatorVideogioco1());
printList(giochi);
// Ordina dal voto più alto al più basso
System.out.println("Ordina dal voto più alto al più basso");
Collections.sort(giochi, new ComparatorVideogioco2());
printList(giochi);
// Multi
}
private static <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("}");
}
}
@@ -1,44 +0,0 @@
package jcf_set.example;
import java.util.HashSet;
import java.util.Random;
import java.util.Set;
import java.util.TreeSet;
public class InteriRipetuti {
public static void main(String[] Args) {
new InteriRipetuti().run();
}
public void run() {
int N = 20;
int MAX_INT = 50;
// HASHSET (non ordinato)
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);
// TREESET (ordinato)
Set<Integer> treeset = new TreeSet<Integer>(hashset);
// Stampa di treeset
System.out.println("Treeset");
for (Integer x : treeset) System.out.println(x + " ");
System.out.println(); System.out.println(hashset);
}
}
@@ -1,35 +0,0 @@
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)) {
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);
}
}
@@ -1,37 +0,0 @@
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("}");
}
}
@@ -1,51 +0,0 @@
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();
if (!iterator.hasNext()) return null;
Integer maxValue = iterator.next();
while (iterator.hasNext()) {
}
}
}
@@ -1,38 +0,0 @@
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.
*/
}
@@ -1,11 +0,0 @@
package comparatori.videogioco;
import java.util.Comparator;
public class ComparatorVideogioco2 implements Comparator<Videogioco> {
public in compare() {
}
}
@@ -1,514 +0,0 @@
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 è una foglia non ha bisogno di fare operazioni
BinaryNode<E> copy;
if (!node.hasLeft()) {
// Si copia il figlio destro in quello sinistro
copy = new BinaryNode<E>(node.getRight().getData());
node.setLeft(copy);
copy.setParentAsLeftChild(node);
} else {
copy = new BinaryNode<E>(node.getLeft().getData());
node.setRight(copy);
copy.setParentAsRightChild(node);
}
}
}
@@ -1,41 +0,0 @@
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);
// Ordina i videogiochi per titolo alfabetico crescente
Collections.sort(giochi, new ComparatorVideogioco1());
}
private static <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("}");
}
}
@@ -1,512 +0,0 @@
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
if (!node.hasLeft() && !node.hasRight()) return; // Se il nodo è una foglia non ha bisogno di fare operazioni
BinaryNode<E> copy;
if (!node.hasLeft()) {
// Si copia il figlio destro in quello sinistro
copy = new BinaryNode<E>(node.getRight().getData());
node.setLeft(copy);
} else {
copy = new BinaryNode<E>(node.getLeft().getData());
}
}
}
@@ -1,516 +0,0 @@
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 è una foglia non ha bisogno di fare operazioni
BinaryNode<E> copy;
if (!node.hasLeft()) {
// Si copia il figlio destro in quello sinistro
copy = new BinaryNode<E>(node.getRight().getData());
node.setLeft(copy);
copy.setParentAsLeftChild(node);
} else {
copy = new BinaryNode<E>(node.getLeft().getData());
node.setRight(copy);
copy.setParentAsRightChild(node);
}
}
}
@@ -1,59 +0,0 @@
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;
}
// Getter
public String titolo() {
return titolo;
}
public String piattaforma() {
return piattaforma;
}
public Integer annoUscita() {
return annoUscita;
}
public Double prezzo() {
return prezzo;
}
public Integer voto() {
return voto;
}
// Implementazione del metodo comparatore
/**
* compareTo ordina per prezzo crescente
*/
@Override
public int compareTo(Videogioco videogioco) {
}
}
@@ -1,24 +0,0 @@
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();
}
}
@@ -1,491 +0,0 @@
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 (node.getLeft() == null && node.getRight()) return 1;
return n
}
}
@@ -1,15 +0,0 @@
package comparatori.videogioco;
import java.util.Comparator;
public class ComparatorVideogioco1 implements Comparator<Videogioco> {
/**
* Ordina i videogiochi per titolo alfabetico crescente
*/
@Override
public int compareTo(Videogioco v1, Videogioco v2) {
return String.compareTo(v1.titolo(), v2.titolo());
}
}
@@ -1,31 +0,0 @@
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;
}
}
@@ -1,509 +0,0 @@
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
if (!node.hasLeft() && !node.hasRight()) return; // Se il nodo è una foglia non ha bisogno di fare operazioni
if (!node.hasLeft()) {
// Si copia il figlio destro in quello sinistro
} else {
}
}
}
@@ -1,14 +0,0 @@
package jcf_set.example;
public class InteriRipetuti {
public static void main(String[] Args) {
}
public void run() {
int N = 20;
int MAX_INT = 50;
}
}
@@ -1,501 +0,0 @@
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;
if (node.hasLeft() && node.hasRight()) return;
}
}
@@ -1,30 +0,0 @@
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 ()
}
}
}
@@ -1,5 +0,0 @@
package comparatori.videogioco;
public class ComparatorVideogioco2 implements Comparator<Videogioco> {
}
@@ -1,493 +0,0 @@
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
*/
}
@@ -1,39 +0,0 @@
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
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("}");
}
}
@@ -1,14 +0,0 @@
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.
*/
}
@@ -1,29 +0,0 @@
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();
}
}
}
@@ -1,49 +0,0 @@
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();
if (!iterator.hasNext()) return null;
Integer maxValue;
}
}
@@ -1,43 +0,0 @@
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.
*/
}
@@ -1,9 +0,0 @@
package jcf_set.example;
public class InteriRipetuti {
public static void main(String[] Args) {
}
}
@@ -1,42 +0,0 @@
package jcf_set.example;
import java.util.HashSet;
import java.util.Random;
import java.util.Set;
import java.util.TreeSet;
public class InteriRipetuti {
public static void main(String[] Args) {
new InteriRipetuti().run();
}
public void run() {
int N = 20;
int MAX_INT = 50;
// HASHSET (non ordinato)
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);
// TREESET (ordinato)
Set<Integer> treeset = new TreeSet<Integer>(hashset);
// Stampa di treeset
}
}
@@ -1,19 +0,0 @@
package comparatori.videogioco;
import java.util.Comparator;
public class ComparatorVideogioco3 implements Comparator<Videogioco> {
/**
* Prima ordina per piattaforma alfabetica.
* Se la piattaforma è uguale, per anno
* di uscita crescente
* se l'anno è uguale, allora per titolo alfabetico
*/
@Override
public int compare(Videogioco v1, Videogioco v2) {
int cmp = v1.piattaforma().compareTo(v2.piattaforma());
if (cmp == 0) return cmp;
}
}
@@ -1,54 +0,0 @@
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
System.out.println("ordina per prezzo crescente");
Collections.sort(giochi);
printList(giochi);
// Ordina i videogiochi per titolo alfabetico crescente
System.out.println("Ordina i videogiochi per titolo alfabetico crescente");
Collections.sort(giochi, new ComparatorVideogioco1());
printList(giochi);
// Ordina dal voto più alto al più basso
System.out.println("Ordina dal voto più alto al più basso");
Collections.sort(giochi, new ComparatorVideogioco2());
printList(giochi);
// Multi
System.out.println("Multi");
Collections.sort(giochi, new ComparatorVideogioco3());
printList(giochi);
}
private static <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("}");
}
}
@@ -1,33 +0,0 @@
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;
}
}
@@ -1,62 +0,0 @@
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();
if (!iterator.hasNext()) return null;
Integer maxValue = iterator.next();
while (iterator.hasNext()) {
Integer current = iterator.next();
if (current > maxValue) maxValue = current;
}
return maxValue;
}
/*
* 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.
*/
}
@@ -1,15 +0,0 @@
package comparatori.videogioco;
import java.util.Comparator;
public class ComparatorVideogioco1 implements Comparator<Videogioco> {
/**
* Ordina i videogiochi per titolo alfabetico crescente
*/
@Override
public int compareTo(Videogioco v1, Videogioco v2) {
}
}
@@ -1,46 +0,0 @@
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) {
Integer maxValue;
}
}
@@ -1,511 +0,0 @@
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
if (!node.hasLeft() && !node.hasRight()) return; // Se il nodo è una foglia non ha bisogno di fare operazioni
BinaryNode<E> copy;
if (!node.hasLeft()) {
// Si copia il figlio destro in quello sinistro
copy = new BinaryNode<E>(node.getRight());
} else {
}
}
}
@@ -1,511 +0,0 @@
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
if (!node.hasLeft() && !node.hasRight()) return; // Se il nodo è una foglia non ha bisogno di fare operazioni
BinaryNode<E> copy;
if (!node.hasLeft()) {
// Si copia il figlio destro in quello sinistro
copy = new BinaryNode<E>();
} else {
}
}
}
@@ -1,20 +0,0 @@
package comparatori.videogioco;
import java.util.Comparator;
public class ComparatorVideogioco3 implements Comparator<Videogioco> {
/**
* Prima ordina per piattaforma alfabetica.
* Se la piattaforma è uguale, per anno
* di uscita crescente
* se l'anno è uguale, allora per titolo alfabetico
*/
@Override
public int compare(Videogioco v1, Videogioco v2) {
int cmp = v1.piattaforma().compareTo(v2.piattaforma());
if (cmp == 0) return cmp;
}
}
@@ -1,21 +0,0 @@
package comparatori.videogioco;
import java.util.Comparator;
public class ComparatorVideogioco3 implements Comparator<Videogioco> {
/**
* Prima ordina per piattaforma alfabetica.
* Se la piattaforma è uguale, per anno
* di uscita crescente
* se l'anno è uguale, allora per titolo alfabetico
*/
@Override
public int compare(Videogioco v1, Videogioco v2) {
int cmp = v1.piattaforma().compareTo(v2.piattaforma());
if (cmp == 0) return cmp;
cmp = v1.annoUscita() - v2.annoUscita();
if (cmp == 0) return cmp;
}
}
@@ -1,41 +0,0 @@
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;
}
// Getter
public String titolo() {
return titolo;
}
public String piattaforma() {
return piattaforma;
}
public Integer annoUscita() {
return annoUscita;
}
}
@@ -1,506 +0,0 @@
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
if (!node.hasLeft() && !node.hasRight()) return; // Se il nodo è una foglia non ha bisogno di fare operazioni
if (!node.hasLeft()) {
}
}
}
@@ -1,29 +0,0 @@
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) {
}
}
}
@@ -1,504 +0,0 @@
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
if (!node.hasLeft() && !node.hasRight()) return; // Se il nodo è una foglia non ha bisogno di fare operazioni
//if ()
}
}
@@ -1,511 +0,0 @@
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
if (!node.hasLeft() && !node.hasRight()) return; // Se il nodo è una foglia non ha bisogno di fare operazioni
BinaryNode<E> copy;
if (!node.hasLeft()) {
// Si copia il figlio destro in quello sinistro
copy = new BinaryNode<E>();
} else {
}
}
}
@@ -1,16 +0,0 @@
package comparatori.videogioco;
import java.util.Comparator;
public class ComparatorVideogioco2 implements Comparator<Videogioco> {
/**
* Ordina dal più alto al più basso
* @return
*/
@Override
public int compare() {
}
}

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