Compare commits
13 Commits
7fd4b38c38
...
29c367e3f7
| Author | SHA1 | Date | |
|---|---|---|---|
| 29c367e3f7 | |||
| 47427ae6fe | |||
| b40778d10c | |||
| c5277dd0dc | |||
| b0a214bedb | |||
| 0b5f8e6aba | |||
| 65f7586e24 | |||
| a87c13dc42 | |||
| 4bb503b70f | |||
| dbdd2396ca | |||
| b23c8ac9cd | |||
| 6100f1becb | |||
| 27737cf7b4 |
39
lab2/pom.xml
Normal file
39
lab2/pom.xml
Normal 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>
|
||||||
17
lab2/src/main/java/ru/spbstu/telematics/java/App.java
Normal file
17
lab2/src/main/java/ru/spbstu/telematics/java/App.java
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
163
lab2/src/main/java/ru/spbstu/telematics/java/MyTreeSet.java
Normal file
163
lab2/src/main/java/ru/spbstu/telematics/java/MyTreeSet.java
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
99
lab2/src/test/java/ru/spbstu/telematics/java/AppTest.java
Normal file
99
lab2/src/test/java/ru/spbstu/telematics/java/AppTest.java
Normal 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());
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user