Compare commits

...

13 Commits

4 changed files with 318 additions and 0 deletions

39
lab2/pom.xml Normal file
View File

@@ -0,0 +1,39 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>ru.spbstu.telematics.java</groupId>
<artifactId>lab2</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>lab2</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.9.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.9.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<archive>
<manifest>
<mainClass>ru.spbstu.telematics.java.App</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,17 @@
package ru.spbstu.telematics.java;
public class App
{
public static void main( String[] args )
{
MyTreeSet<Integer> tree = new MyTreeSet<>();
System.out.println(tree.add(10));
System.out.println(tree.add(20));
System.out.println(tree.add(10));
System.out.println("Содержимое дерева:");
for (Integer val: tree) {
System.out.println(val);
}
}
}

View File

@@ -0,0 +1,163 @@
package ru.spbstu.telematics.java;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Stack;
public class MyTreeSet<E extends Comparable<E>> implements Iterable<E> {
// Класс для представления узла дерева
private class Node {
E value;
Node left;
Node right;
Node(E value) {
this.value = value;
}
}
private Node root;
private int size;
public MyTreeSet() {
root = null;
size = 0;
}
public int size() {
return size;
}
public boolean add(E element) {
if (element == null) {
throw new NullPointerException("Нельзя добавить null в TreeSet!");
}
if (root == null) {
root = new Node(element);
size++;
return true;
}
Node currentNode = root;
Node parentNode = null;
while (currentNode != null) {
int cmp = element.compareTo(currentNode.value);
if (cmp == 0) return false;
parentNode = currentNode;
currentNode = cmp < 0 ? currentNode.left : currentNode.right;
}
Node newNode = new Node(element);
if (element.compareTo(parentNode.value) < 0) {
parentNode.left = newNode;
} else {
parentNode.right = newNode;
}
size++;
return true;
}
public boolean contains(E element) {
if (element == null) {
throw new NullPointerException("Нельзя добавить null в TreeSet!");
}
return contains(root, element);
}
private boolean contains(Node node, E element) {
if (node == null) return false;
int cmp = element.compareTo(node.value);
if (cmp == 0) return true;
return cmp < 0 ? contains(node.left, element) : contains(node.right, element);
}
public boolean remove(E element) {
if (element == null) {
throw new NullPointerException("Null элементы не допускаются");
}
if (!contains(element)) return false;
root = remove(root, element);
size--;
return true;
}
private Node remove(Node node, E element) {
if (node == null) return null;
int cmp = element.compareTo(node.value);
if (cmp < 0) {
node.left = remove(node.left, element);
} else if (cmp > 0) {
node.right = remove(node.right, element);
} else {
// Узел для удаления найден
if (node.left == null && node.right == null) {
// Если он является листом, то просто удаляем его
return null;
} else if (node.left == null) {
// Если у него нету левого поддерева, то заменяем правым узлом
return node.right;
} else if (node.right == null) {
// Если у него нету правого поддерева, то заменяем левым узлом
return node.left;
} else {
// Если есть оба поддерева, то заменяем самым наименьшим элементом правого поддерева
Node successor = minValueNode(node.right);
node.value = successor.value;
node.right = remove(node.right, successor.value);
}
}
return node;
}
private Node minValueNode(Node node) {
Node current = node;
while (current.left != null) {
current = current.left;
}
return current;
}
@Override
public Iterator<E> iterator() {
return new MyTreeSetIterator();
}
private class MyTreeSetIterator implements Iterator<E> {
// На вершине стека всегда будет лежать наименьший элемент в дереве
Stack<Node> nodeStack = new Stack<>();
MyTreeSetIterator() {
pushAllLeftToStack(root);
}
void pushAllLeftToStack(Node current) {
if (current == null) return;
nodeStack.push(current);
pushAllLeftToStack(current.left);
}
@Override
public boolean hasNext() {
return nodeStack.size() != 0;
}
@Override
public E next() {
if (!hasNext()) throw new NoSuchElementException();
Node minNode = nodeStack.pop();
if (minNode.right != null) {
pushAllLeftToStack(minNode.right);
}
return minNode.value;
}
}
}

View File

@@ -0,0 +1,99 @@
package ru.spbstu.telematics.java;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.TreeSet;
class MyTreeSetTests {
MyTreeSet<Integer> myTreeSet;
TreeSet<Integer> treeSet;
@BeforeEach
void setUp() {
myTreeSet = new MyTreeSet<>();
treeSet = new TreeSet<>();
}
@Test
void testAdd() {
assertThrows(NullPointerException.class, () -> myTreeSet.add(null));
assertThrows(NullPointerException.class, () -> treeSet.add(null));
assertEquals(myTreeSet.add(150), treeSet.add(150));
assertEquals(myTreeSet.add(200), treeSet.add(200));
assertEquals(myTreeSet.add(150), treeSet.add(150));
assertThrows(NullPointerException.class, () -> myTreeSet.add(null));
assertThrows(NullPointerException.class, () -> treeSet.add(null));
}
@Test
void testContains() {
assertEquals(myTreeSet.contains(15), treeSet.contains(15));
treeSet.add(15);
myTreeSet.add(15);
assertEquals(myTreeSet.contains(15), treeSet.contains(15));
assertEquals(myTreeSet.contains(50), treeSet.contains(50));
treeSet.add(50);
myTreeSet.add(50);
assertEquals(myTreeSet.contains(50), treeSet.contains(50));
assertThrows(NullPointerException.class, () -> myTreeSet.contains(null));
assertThrows(NullPointerException.class, () -> treeSet.contains(null));
}
@Test
void testRemove() {
assertEquals(myTreeSet.remove(15), treeSet.remove(15));
treeSet.add(15);
myTreeSet.add(15);
assertEquals(myTreeSet.remove(15), treeSet.remove(15));
assertEquals(myTreeSet.remove(50), treeSet.remove(50));
treeSet.add(50);
myTreeSet.add(50);
assertEquals(myTreeSet.remove(50), treeSet.remove(50));
assertThrows(NullPointerException.class, () -> myTreeSet.remove(null));
assertThrows(NullPointerException.class, () -> treeSet.remove(null));
}
@Test
void testSize() {
assertEquals(myTreeSet.size(), treeSet.size());
treeSet.add(15);
myTreeSet.add(15);
assertEquals(myTreeSet.size(), treeSet.size());
treeSet.add(50);
myTreeSet.add(50);
assertEquals(myTreeSet.size(), treeSet.size());
assertEquals(myTreeSet.remove(50), treeSet.remove(50));
assertEquals(myTreeSet.size(), treeSet.size());
}
@Test
void testIterator() {
treeSet.add(15);
myTreeSet.add(15);
treeSet.add(250);
myTreeSet.add(250);
treeSet.add(50);
myTreeSet.add(50);
Iterator<Integer> itMyTreeSet = myTreeSet.iterator();
Iterator<Integer> itTreeSet = treeSet.iterator();
assertEquals(itMyTreeSet.hasNext(), itTreeSet.hasNext());
assertEquals(itMyTreeSet.next(), itTreeSet.next());
assertEquals(itMyTreeSet.hasNext(), itTreeSet.hasNext());
assertEquals(itMyTreeSet.next(), itTreeSet.next());
assertEquals(itMyTreeSet.hasNext(), itTreeSet.hasNext());
assertEquals(itMyTreeSet.next(), itTreeSet.next());
assertEquals(itMyTreeSet.hasNext(), itTreeSet.hasNext());
assertThrows(NoSuchElementException.class, () -> itMyTreeSet.next());
assertThrows(NoSuchElementException.class, () -> itTreeSet.next());
}
}