├── .gitignore ├── src ├── main │ └── java │ │ └── io │ │ └── sancta │ │ └── sanctorum │ │ └── structures │ │ ├── AbstractCollection.java │ │ ├── queue │ │ ├── Queue.java │ │ ├── SimplyQueue.java │ │ └── PriorityQueue.java │ │ ├── tree │ │ ├── Node.java │ │ ├── Tree.java │ │ └── SimplyTree.java │ │ ├── list │ │ ├── ListIterator.java │ │ ├── List.java │ │ ├── DoubleLinkedList.java │ │ ├── ArrayList.java │ │ └── SingleLinkedList.java │ │ └── Stack.java └── test │ └── java │ └── io │ └── sancta │ └── sanctorum │ └── structures │ ├── queue │ ├── PriorityQueueTest.java │ └── SimplyQueueTest.java │ ├── StackTest.java │ ├── tree │ └── SimpleTreeTest.java │ └── list │ ├── ArrayListTest.java │ ├── DoubleLinkedListTest.java │ └── SingleLinkedListTest.java ├── ReadMe.md ├── LICENSE.md ├── pom.xml └── .github └── workflows └── jekyll-gh-pages.yml /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | .idea/ 3 | .idea 4 | *.iml 5 | *.class 6 | *.info 7 | /target/ 8 | /.idea/ 9 | -------------------------------------------------------------------------------- /src/main/java/io/sancta/sanctorum/structures/AbstractCollection.java: -------------------------------------------------------------------------------- 1 | package io.sancta.sanctorum.structures; 2 | 3 | public abstract class AbstractCollection { 4 | public abstract int size(); 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/io/sancta/sanctorum/structures/queue/Queue.java: -------------------------------------------------------------------------------- 1 | package io.sancta.sanctorum.structures.queue; 2 | 3 | public interface Queue { 4 | 5 | void put(T element); 6 | 7 | T peek(); 8 | 9 | T pull(); 10 | 11 | T firstElement(); 12 | 13 | T lastElement(); 14 | } -------------------------------------------------------------------------------- /src/main/java/io/sancta/sanctorum/structures/tree/Node.java: -------------------------------------------------------------------------------- 1 | package io.sancta.sanctorum.structures.tree; 2 | 3 | class Node > { 4 | 5 | public T element; 6 | public Node leftChild; 7 | public Node rightChild; 8 | public Node parent; 9 | 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/io/sancta/sanctorum/structures/tree/Tree.java: -------------------------------------------------------------------------------- 1 | package io.sancta.sanctorum.structures.tree; 2 | 3 | public interface Tree extends Iterable { 4 | 5 | int getSize(); 6 | 7 | boolean add(T element); 8 | 9 | boolean remove(T element); 10 | 11 | boolean contains(T element); 12 | 13 | T getRoot(); 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/io/sancta/sanctorum/structures/list/ListIterator.java: -------------------------------------------------------------------------------- 1 | package io.sancta.sanctorum.structures.list; 2 | 3 | import java.util.Iterator; 4 | 5 | public interface ListIterator extends Iterator { 6 | 7 | boolean hasNext(); 8 | 9 | T next(); 10 | 11 | boolean hasPrevious(); 12 | 13 | int nextIndex(); 14 | 15 | int previousIndex(); 16 | 17 | void set(T t); 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/io/sancta/sanctorum/structures/list/List.java: -------------------------------------------------------------------------------- 1 | package io.sancta.sanctorum.structures.list; 2 | 3 | import java.util.Comparator; 4 | 5 | public interface List { 6 | 7 | int size(); 8 | 9 | void add(T element); 10 | 11 | void add(int index, T element); 12 | 13 | void remove(int index); 14 | 15 | boolean remove(T element); 16 | 17 | T get(int index); 18 | 19 | void set(int index, T element); 20 | 21 | int indexOf(T element); 22 | 23 | void clear(); 24 | 25 | void sort(Comparator comparator); 26 | 27 | } 28 | -------------------------------------------------------------------------------- /ReadMe.md: -------------------------------------------------------------------------------- 1 | # data-structure 2 | 3 | 1. Стек + 4 | 2. Очередь + 5 | 3. Линейный список + 6 | 4. Односвязный список + 7 | 5. Двусвязный список + 8 | 6. Сортировка разных списков + 9 | 7. Итератор + 10 | 8. Очередь с приоритетом + 11 | 9. Дерево + 12 | 9.0. Простое дерево + 13 | 9.1. АВЛ 14 | 9.2. Красно-черное дерево 15 | 10. Множество 16 | 11. Карта соответствия 17 | 12. Hash 18 | 13. Графы 19 | 13.1. Список смежных вершин 20 | 13.2. Матрица смежности 21 | 14. Отрисовка графов 22 | 15. Алгоритмы на графах 23 | 24 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/main/java/io/sancta/sanctorum/structures/Stack.java: -------------------------------------------------------------------------------- 1 | package io.sancta.sanctorum.structures; 2 | 3 | public class Stack extends AbstractCollection { 4 | 5 | private Node last; 6 | private int size; 7 | 8 | private static class Node { 9 | private T element; 10 | private Node next; 11 | } 12 | 13 | @Override 14 | public int size() { 15 | return size; 16 | } 17 | 18 | public void push(T element){ 19 | if (element == null) { 20 | throw new IllegalArgumentException("New element cannot be null"); 21 | } 22 | Node node = new Node<>(); 23 | node.element = element; 24 | node.next = last; 25 | last = node; 26 | size++; 27 | } 28 | 29 | public T pop(){ 30 | if (size == 0) { 31 | return null; 32 | } 33 | 34 | T element = last.element; 35 | last = last.next; 36 | size--; 37 | return element; 38 | } 39 | 40 | public T peek(){ 41 | if (size == 0) { 42 | return null; 43 | } 44 | return last.element; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/test/java/io/sancta/sanctorum/structures/queue/PriorityQueueTest.java: -------------------------------------------------------------------------------- 1 | package io.sancta.sanctorum.structures.queue; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import static org.junit.jupiter.api.Assertions.assertEquals; 6 | 7 | class PriorityQueueTest { 8 | 9 | @Test 10 | void put() { 11 | PriorityQueue queue = new PriorityQueue<>(true); 12 | queue.put(85); 13 | queue.put(59); 14 | queue.put(12); 15 | queue.put(9); 16 | queue.put(20); 17 | queue.put(31); 18 | queue.put(60); 19 | 20 | assertEquals(9, queue.peek()); 21 | } 22 | 23 | @Test 24 | void get() { 25 | PriorityQueue queue = new PriorityQueue<>(true); 26 | queue.put(85); 27 | queue.put(59); 28 | queue.put(12); 29 | queue.put(9); 30 | queue.put(20); 31 | queue.put(31); 32 | queue.put(60); 33 | 34 | assertEquals(9, queue.poll()); 35 | assertEquals(12, queue.poll()); 36 | assertEquals(20, queue.poll()); 37 | assertEquals(31, queue.poll()); 38 | assertEquals(59, queue.poll()); 39 | assertEquals(60, queue.poll()); 40 | assertEquals(85, queue.poll()); 41 | } 42 | } -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | io.sancta-sanctorum 8 | data-structure 9 | 1.0-SNAPSHOT 10 | 11 | 12 | 13 | 14 | org.junit.jupiter 15 | junit-jupiter-api 16 | 5.8.2 17 | test 18 | 19 | 20 | 21 | 22 | 23 | 17 24 | 25 | 26 | 27 | 28 | 29 | org.apache.maven.plugins 30 | maven-compiler-plugin 31 | 32 | ${java.version} 33 | ${java.version} 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /src/main/java/io/sancta/sanctorum/structures/queue/SimplyQueue.java: -------------------------------------------------------------------------------- 1 | package io.sancta.sanctorum.structures.queue; 2 | 3 | import io.sancta.sanctorum.structures.AbstractCollection; 4 | 5 | public class SimplyQueue extends AbstractCollection implements Queue { 6 | 7 | private Node first; 8 | private Node last; 9 | private int size; 10 | 11 | private static class Node { 12 | private T element; 13 | private Node next; 14 | } 15 | 16 | @Override 17 | public int size() { 18 | return size; 19 | } 20 | 21 | @Override 22 | public void put(T element) { 23 | if (element == null) { 24 | throw new IllegalArgumentException("New element cannot be null"); 25 | } 26 | 27 | Node node = new Node<>(); 28 | node.element = element; 29 | if (size == 0) { 30 | first = node; 31 | } else { 32 | last.next = node; 33 | } 34 | last = node; 35 | size++; 36 | } 37 | 38 | @Override 39 | public T peek() { 40 | if (size == 0) { 41 | return null; 42 | } 43 | return first.element; 44 | } 45 | 46 | @Override 47 | public T poll() { 48 | if (size == 0) { 49 | return null; 50 | } 51 | T retElement = first.element; 52 | first = first.next; 53 | size--; 54 | return retElement; 55 | } 56 | 57 | // public T lastElement(){ 58 | // if (size == 0) { 59 | // return null; 60 | // } 61 | // return lastSegment.element; 62 | // } 63 | } 64 | -------------------------------------------------------------------------------- /.github/workflows/jekyll-gh-pages.yml: -------------------------------------------------------------------------------- 1 | # Sample workflow for building and deploying a Jekyll site to GitHub Pages 2 | name: Deploy Jekyll with GitHub Pages dependencies preinstalled 3 | 4 | on: 5 | # Runs on pushes targeting the default branch 6 | push: 7 | branches: ["master"] 8 | 9 | # Allows you to run this workflow manually from the Actions tab 10 | workflow_dispatch: 11 | 12 | # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages 13 | permissions: 14 | contents: read 15 | pages: write 16 | id-token: write 17 | 18 | # Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. 19 | # However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. 20 | concurrency: 21 | group: "pages" 22 | cancel-in-progress: false 23 | 24 | jobs: 25 | # Build job 26 | build: 27 | runs-on: ubuntu-latest 28 | steps: 29 | - name: Checkout 30 | uses: actions/checkout@v3 31 | - name: Setup Pages 32 | uses: actions/configure-pages@v3 33 | - name: Build with Jekyll 34 | uses: actions/jekyll-build-pages@v1 35 | with: 36 | source: ./ 37 | destination: ./_site 38 | - name: Upload artifact 39 | uses: actions/upload-pages-artifact@v2 40 | 41 | # Deployment job 42 | deploy: 43 | environment: 44 | name: github-pages 45 | url: ${{ steps.deployment.outputs.page_url }} 46 | runs-on: ubuntu-latest 47 | needs: build 48 | steps: 49 | - name: Deploy to GitHub Pages 50 | id: deployment 51 | uses: actions/deploy-pages@v2 52 | -------------------------------------------------------------------------------- /src/test/java/io/sancta/sanctorum/structures/StackTest.java: -------------------------------------------------------------------------------- 1 | package io.sancta.sanctorum.structures; 2 | 3 | import org.junit.jupiter.api.BeforeEach; 4 | import org.junit.jupiter.api.Test; 5 | 6 | import static org.junit.jupiter.api.Assertions.*; 7 | 8 | class StackTest { 9 | 10 | private Stack stringStack; 11 | 12 | @BeforeEach 13 | public void init() { 14 | stringStack = new Stack<>(); 15 | } 16 | 17 | void fillStack() { 18 | stringStack.push("Привет"); 19 | stringStack.push("меня"); 20 | stringStack.push("зовут"); 21 | stringStack.push("Собака"); 22 | } 23 | 24 | @Test 25 | void push() { 26 | fillStack(); 27 | assertEquals(4, stringStack.size()); 28 | assertEquals("Собака", stringStack.pop()); 29 | assertEquals("зовут", stringStack.pop()); 30 | assertEquals(2, stringStack.size()); 31 | } 32 | 33 | @Test 34 | void pop() { 35 | assertNull(stringStack.pop()); 36 | assertEquals(0, stringStack.size()); 37 | } 38 | 39 | @Test 40 | void peek() { 41 | fillStack(); 42 | assertEquals(4, stringStack.size()); 43 | assertEquals("Собака", stringStack.peek()); 44 | assertEquals("Собака", stringStack.peek()); 45 | assertEquals(4, stringStack.size()); 46 | } 47 | 48 | @Test 49 | void pushNullException() { 50 | assertThrows(IllegalArgumentException.class, () -> stringStack.push(null)); 51 | } 52 | 53 | @Test 54 | void pushNullMessage() { 55 | try { 56 | stringStack.push(null); 57 | fail("No exception"); 58 | } catch (IllegalArgumentException e) { 59 | assertEquals("New element cannot be null", e.getMessage()); 60 | } 61 | } 62 | } -------------------------------------------------------------------------------- /src/test/java/io/sancta/sanctorum/structures/queue/SimplyQueueTest.java: -------------------------------------------------------------------------------- 1 | package io.sancta.sanctorum.structures.queue; 2 | 3 | import org.junit.jupiter.api.BeforeEach; 4 | import org.junit.jupiter.api.Test; 5 | 6 | import static org.junit.jupiter.api.Assertions.*; 7 | 8 | public class SimplyQueueTest { 9 | 10 | private SimplyQueue stringQueue; 11 | 12 | @BeforeEach 13 | void init() { 14 | stringQueue = new SimplyQueue<>(); 15 | } 16 | 17 | void fillQueue() { 18 | stringQueue.put("Привет"); 19 | stringQueue.put("меня"); 20 | stringQueue.put("зовут"); 21 | stringQueue.put("Собака"); 22 | } 23 | 24 | @Test 25 | void poll() { 26 | fillQueue(); 27 | assertEquals(4, stringQueue.size()); 28 | assertEquals("Привет", stringQueue.poll()); 29 | assertEquals("меня", stringQueue.poll()); 30 | assertEquals(2, stringQueue.size()); 31 | } 32 | 33 | @Test 34 | void get() { 35 | assertNull(stringQueue.poll()); 36 | assertEquals(0, stringQueue.size()); 37 | } 38 | 39 | @Test 40 | void peek() { 41 | fillQueue(); 42 | assertEquals(4, stringQueue.size()); 43 | assertEquals("Привет", stringQueue.peek()); 44 | assertEquals("Привет", stringQueue.peek()); 45 | assertEquals(4, stringQueue.size()); 46 | } 47 | 48 | // @Test 49 | // void lastElement() { 50 | // fillQueue(); 51 | // assertEquals(4, stringQueue.size()); 52 | // assertEquals("Собака", stringQueue.lastElement()); 53 | // assertEquals("Собака", stringQueue.lastElement()); 54 | // assertEquals(4, stringQueue.size()); 55 | // } 56 | 57 | @Test 58 | void putNullException() { 59 | assertThrows(IllegalArgumentException.class, () -> stringQueue.put(null)); 60 | } 61 | 62 | @Test 63 | void putNullMessage() { 64 | try { 65 | stringQueue.put(null); 66 | fail("No exception"); 67 | } catch (IllegalArgumentException e) { 68 | assertEquals("New element cannot be null", e.getMessage()); 69 | } 70 | } 71 | } -------------------------------------------------------------------------------- /src/test/java/io/sancta/sanctorum/structures/tree/SimpleTreeTest.java: -------------------------------------------------------------------------------- 1 | package io.sancta.sanctorum.structures.tree; 2 | 3 | import org.junit.jupiter.api.BeforeEach; 4 | import org.junit.jupiter.api.Test; 5 | 6 | import java.util.Random; 7 | 8 | import static org.junit.jupiter.api.Assertions.*; 9 | 10 | class SimpleTreeTest { 11 | 12 | private SimplyTree tree; 13 | 14 | @BeforeEach 15 | void init() { 16 | tree = new SimplyTree<>(); 17 | } 18 | 19 | @Test 20 | void add() { 21 | assertTrue(tree.add(5)); 22 | assertTrue(tree.add(91)); 23 | assertTrue(tree.add(1)); 24 | assertTrue(tree.add(18)); 25 | assertTrue(tree.add(24)); 26 | 27 | assertFalse(tree.add(5)); 28 | assertFalse(tree.add(1)); 29 | assertEquals(5, tree.getSize()); 30 | } 31 | 32 | @Test 33 | void iterator() { 34 | tree.add(4); 35 | tree.add(2); 36 | tree.add(6); 37 | tree.add(1); 38 | tree.add(3); 39 | tree.add(5); 40 | tree.add(7); 41 | tree.add(5); 42 | tree.add(91); 43 | tree.add(1); 44 | tree.add(18); 45 | tree.add(24); 46 | tree.add(10); 47 | tree.add(31); 48 | tree.add(24); 49 | tree.add(15); 50 | tree.add(63); 51 | Random r = new Random(); 52 | 53 | for (int i = 0; i < 1000; i++) { 54 | tree.add(Math.abs(r.nextInt())); 55 | } 56 | 57 | int previuos = -1; 58 | for (int element: tree) { 59 | System.out.println(element); 60 | assertTrue(previuos < element); 61 | previuos = element; 62 | } 63 | } 64 | 65 | @Test 66 | void contains() { 67 | tree.add(5); 68 | tree.add(91); 69 | tree.add(1); 70 | assertTrue(tree.contains(5)); 71 | assertTrue(tree.contains(91)); 72 | assertFalse(tree.contains(10)); 73 | } 74 | 75 | @Test 76 | void remove() { 77 | tree.add(4); 78 | tree.add(2); 79 | tree.add(6); 80 | tree.add(1); 81 | tree.add(3); 82 | tree.add(5); 83 | tree.add(7); 84 | tree.add(5); 85 | tree.remove(6); 86 | assertFalse(tree.contains(6)); 87 | 88 | int previuos = -1; 89 | for (int element: tree) { 90 | System.out.println(element); 91 | assertTrue(previuos < element); 92 | previuos = element; 93 | } 94 | } 95 | } -------------------------------------------------------------------------------- /src/main/java/io/sancta/sanctorum/structures/queue/PriorityQueue.java: -------------------------------------------------------------------------------- 1 | package io.sancta.sanctorum.structures.queue; 2 | 3 | import io.sancta.sanctorum.structures.AbstractCollection; 4 | import io.sancta.sanctorum.structures.list.ArrayList; 5 | 6 | public class PriorityQueue> extends AbstractCollection implements Queue { 7 | 8 | private final boolean min; 9 | private final ArrayList list = new ArrayList<>(); 10 | 11 | public PriorityQueue(boolean min) { 12 | this.min = min; 13 | } 14 | 15 | @Override 16 | public int size() { 17 | return list.size(); 18 | } 19 | 20 | @Override 21 | public void put(T element) { 22 | list.add(element); 23 | int index = list.size() - 1; 24 | 25 | // while (parent(index) >= 0 && Utils.compare(list.get(index), list.get(parent(index)), min)) { 26 | // list.set(index, list.get(parent(index))); 27 | // list.set(parent(index), element); 28 | // index = parent(index); 29 | // } 30 | } 31 | 32 | @Override 33 | public T peek() { 34 | return list.get(0); 35 | } 36 | 37 | @Override 38 | public T poll() { 39 | T element = list.get(0); 40 | list.set(0, list.get(list.size() - 1)); 41 | list.remove(list.size() - 1); 42 | int index = 0; 43 | 44 | // while ((leftChild(index) >= 0 && Utils.compare(list.get(leftChild(index)), list.get(index), min)) || 45 | // (rightChild(index) >= 0 && Utils.compare(list.get(rightChild(index)), list.get(index), min))) { 46 | // // Меняем на правого ребёнка, когда есть правый ребёнок, который приоритетнее, чем левый 47 | // // иначе меняем на левого 48 | // if (rightChild(index) >= 0 && Utils.compare(list.get(rightChild(index)), list.get(leftChild(index)), min)) { 49 | // T tmp = list.get(index); 50 | // list.set(index, list.get(rightChild(index))); 51 | // list.set(rightChild(index), tmp); 52 | // index = rightChild(index); 53 | // } else { 54 | // T tmp = list.get(index); 55 | // list.set(index, list.get(leftChild(index))); 56 | // list.set(leftChild(index), tmp); 57 | // index = leftChild(index); 58 | // } 59 | // } 60 | return element; 61 | } 62 | 63 | private int leftChild(int number) { 64 | number = 2 * number + 1; 65 | if (number >= list.size()) { 66 | return -1; 67 | } 68 | return number; 69 | } 70 | 71 | private int rightChild(int number) { 72 | number = 2 * number + 2; 73 | if (number >= list.size()) { 74 | return -1; 75 | } 76 | return number; 77 | } 78 | 79 | private int parent(int number) { 80 | if (number == 0) { 81 | return -1; 82 | } 83 | return (number - 1) / 2; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/main/java/io/sancta/sanctorum/structures/list/DoubleLinkedList.java: -------------------------------------------------------------------------------- 1 | package io.sancta.sanctorum.structures.list; 2 | 3 | import io.sancta.sanctorum.structures.AbstractCollection; 4 | 5 | import java.util.*; 6 | 7 | public class DoubleLinkedList extends AbstractCollection implements List { 8 | 9 | private Node first; 10 | private Node last; 11 | private int size; 12 | 13 | public boolean quickSort; 14 | 15 | private static class Node { 16 | public T element; 17 | public Node next; 18 | public Node prev; 19 | } 20 | 21 | @Override 22 | public int size() { 23 | return size; 24 | } 25 | 26 | @Override 27 | public void add(T element) { 28 | add(size, element); 29 | } 30 | 31 | @Override 32 | public void add(int index, T element) { 33 | if (index < 0 || index > size) { 34 | throw new IllegalArgumentException("Not correct index"); 35 | } 36 | 37 | Node node = new Node<>(); 38 | node.element = element; 39 | 40 | if (size == 0) { 41 | first = node; 42 | last = node; 43 | } else if (size == index) { 44 | last.next = node; 45 | node.prev = last; 46 | last = node; 47 | } else if (index == 0) { 48 | first.prev = node; 49 | node.next = first; 50 | first = node; 51 | } else { 52 | Node corruntNode = getNode(index); 53 | node.next = corruntNode; 54 | node.prev = corruntNode.prev; 55 | corruntNode.prev.next = node; 56 | corruntNode.prev = node; 57 | } 58 | size++; 59 | } 60 | 61 | @Override 62 | public void remove(int index) { 63 | if (index < 0 || index >= size) { 64 | throw new IllegalArgumentException("Not correct index"); 65 | } 66 | 67 | if (size == 1) { 68 | first = null; 69 | last = null; 70 | } else if (size == 2) { 71 | if (index == 0) { 72 | first = last; 73 | last.prev = null; 74 | } else { 75 | last = first; 76 | first.next = null; 77 | } 78 | } else if (index == 0) { 79 | first = first.next; 80 | first.prev = null; 81 | } else if (index == size - 1) { 82 | last = last.prev; 83 | last.next = null; 84 | } else { 85 | Node corruntNode = getNode(index); 86 | corruntNode.prev.next = corruntNode.next; 87 | corruntNode.next.prev = corruntNode.prev; 88 | } 89 | size--; 90 | } 91 | 92 | @Override 93 | public boolean remove(T element) { 94 | if (size == 0) { 95 | return false; 96 | } 97 | 98 | if (size == 1) { 99 | if (Objects.equals(first.element, element)) { 100 | first = null; 101 | last = null; 102 | size--; 103 | return true; 104 | } 105 | return false; 106 | } 107 | 108 | if (size == 2) { 109 | if (Objects.equals(first.element, element)) { 110 | first = last; 111 | last.prev = null; 112 | size--; 113 | return true; 114 | } else if (Objects.equals(last.element, element)) { 115 | last = first; 116 | first.next = null; 117 | size--; 118 | return true; 119 | } 120 | return false; 121 | } 122 | 123 | if (Objects.equals(first.element, element)) { 124 | first = first.next; 125 | first.prev = null; 126 | size--; 127 | return true; 128 | } else { 129 | Node previous = first; 130 | for (int i = 1; i < size; i++) { 131 | if (Objects.equals(previous.next.element, element)) { 132 | previous.next = previous.next.next; 133 | if (i == size - 1) { 134 | last = previous; 135 | } else { 136 | previous.next.prev = previous; 137 | } 138 | size--; 139 | return true; 140 | } 141 | previous = previous.next; 142 | } 143 | } 144 | return false; 145 | } 146 | 147 | @Override 148 | public T get(int index) { 149 | return getNode(index).element; 150 | } 151 | 152 | private Node getNode(int index) { 153 | if (index < 0 || index >= size) { 154 | throw new IllegalArgumentException("Not correct index"); 155 | } 156 | 157 | Node node; 158 | if (index < size / 2) { 159 | node = first; 160 | for (int i = 0; i < index; i++) { 161 | node = node.next; 162 | } 163 | } else { 164 | node = last; 165 | for (int i = size - 1; i > index; i--) { 166 | node = node.prev; 167 | } 168 | } 169 | return node; 170 | } 171 | 172 | @Override 173 | public void set(int index, T element) { 174 | Node node = getNode(index); 175 | node.element = element; 176 | } 177 | 178 | @Override 179 | public int indexOf(T element) { 180 | Node node = first; 181 | for (int i = 0; i < size; i++) { 182 | if (Objects.equals(node.element, element)) { 183 | return i; 184 | } 185 | node = node.next; 186 | } 187 | /*DoubleSegment segmentFirst = firstSegment; 188 | DoubleSegment segmentLast = lastSegment; 189 | for (int i = 0, j = sizeList - 1; i <= j; i++, j--) { 190 | if (Objects.equals(segmentFirst.element, element)) 191 | return i; 192 | if (Objects.equals(segmentLast.element, element)) 193 | return j; 194 | segmentFirst = segmentFirst.nextSegment; 195 | segmentLast = segmentLast.prevSegment; 196 | }*/ 197 | return -1; 198 | } 199 | 200 | @Override 201 | public void clear() { 202 | first = null; 203 | last = null; 204 | size = 0; 205 | } 206 | 207 | @Override 208 | public void sort(Comparator comparator) { 209 | 210 | } 211 | 212 | } 213 | -------------------------------------------------------------------------------- /src/main/java/io/sancta/sanctorum/structures/list/ArrayList.java: -------------------------------------------------------------------------------- 1 | package io.sancta.sanctorum.structures.list; 2 | 3 | import io.sancta.sanctorum.structures.AbstractCollection; 4 | 5 | import java.util.*; 6 | 7 | public class ArrayList extends AbstractCollection implements List { 8 | 9 | private Object[] items; 10 | private int size; 11 | private int start; 12 | 13 | public ArrayList() { 14 | items = new Object[10]; 15 | } 16 | 17 | public ArrayList(int capacity) { 18 | if (capacity < 1) { 19 | throw new IllegalArgumentException("Capacity must be greater than zero"); 20 | } 21 | items = new Object[capacity]; 22 | } 23 | 24 | @Override 25 | public int size() { 26 | return size; 27 | } 28 | 29 | @Override 30 | public void add(T element) { 31 | add(size, element); 32 | } 33 | 34 | @Override 35 | public void add(int index, T element) { 36 | if (index < 0 || index > size) 37 | throw new IllegalArgumentException("Not correct index"); 38 | 39 | if (size == 0) { 40 | items[start] = element; 41 | } else if (size < items.length) { // Резерв есть! 42 | if (index <= size / 2) { // Вставляем в первую половну списка 43 | if (start == 0) { // Нет резерва в начале массива 44 | // Добавить резерв слева, вставить элемент слева и весь список передвинуть вправо 45 | addLeftShift(index, element); 46 | } else { // Есть резерв в начале массива 47 | // Вставляем элемент влево и все что левее смещаем влево 48 | addLeft(index, element); 49 | } 50 | } else { // Вставляем во вторую половину списка 51 | if (start + size < items.length) { // Есть резерв в конце массива 52 | // Вставляем элемент вправо и остаток списка двигаем вправо 53 | addRight(index, element); 54 | } else { // Нет резерва в конце массива 55 | // Вставляем элемент слева, всё что левее его смещаем влево 56 | addRightShift(index, element); 57 | } 58 | } 59 | } else { // Резерва нет!! пересоздаение массива! 60 | recreateItems(index, element); 61 | } 62 | size++; 63 | } 64 | 65 | private void addLeftShift(int index, T element) { 66 | 67 | for (int i = size - 1; i >= index; i--) { 68 | items[start + i + 1] = items[i]; 69 | } 70 | items[start + index] = element; 71 | 72 | for (int i = index - 1; i >= 0; i--) { 73 | items[start + i] = items[i]; 74 | } 75 | Arrays.fill(items, 0, start, null); 76 | } 77 | 78 | private void addLeft(int index, T element) { 79 | for (int i = 0; i < index; i++) { 80 | items[start + i - 1] = items[start + i]; 81 | } 82 | start--; 83 | items[start + index] = element; 84 | } 85 | 86 | private void addRight(int index, T element) { 87 | for (int i = size; i > index; i--) { 88 | items[start + i] = items[start + i - 1]; 89 | } 90 | items[start + index] = element; 91 | } 92 | 93 | private void addRightShift(int index, T element) { 94 | int newStart = start / 2; 95 | for (int i = 0; i < index; i++) { 96 | items[newStart + i] = items[start + i]; 97 | } 98 | items[newStart + index] = element; 99 | 100 | if (newStart != start - 1) { 101 | for (int i = index; i < size; i++) { 102 | items[newStart + i + 1] = items[start + i]; 103 | } 104 | } 105 | start = newStart; 106 | Arrays.fill(items, start + size, items.length, null); 107 | } 108 | 109 | private void recreateItems(int index, T element) { 110 | int newStart = start; 111 | 112 | if (newStart == 0 && index <= size / 2) { 113 | newStart = (items.length * 2 - size) / 2; 114 | } 115 | Object[] newItems = new Object[items.length * 2]; 116 | 117 | for (int i = 0; i < index; i++) { 118 | newItems[newStart + i] = items[start + i]; 119 | }// if (index >= 0) System.arraycopy(items, start + 0, newItems, newStart + 0, index); 120 | 121 | newItems[newStart + index] = element; 122 | 123 | for (int i = index; i < size; i++) { 124 | newItems[newStart + i + 1] = items[start + i]; 125 | } 126 | items = newItems; 127 | start = newStart; 128 | } 129 | 130 | @Override 131 | public void remove(int index) { 132 | if (index < 0 || index >= size) 133 | throw new IllegalArgumentException("Not correct index"); 134 | 135 | if (items.length > size * 4) { 136 | recreateItems(index); 137 | } else { 138 | if (index <= size / 2) { 139 | for (int i = index; i > 0; i--) { 140 | items[start + i] = items[start + i - 1]; 141 | } 142 | items[start] = null; 143 | start++; 144 | } else { 145 | for (int i = index; i < size - 1; i++) { 146 | items[start + i] = items[start + i + 1]; 147 | } 148 | items[size] = null; 149 | } 150 | } 151 | size--; 152 | } 153 | 154 | private void recreateItems(int index) { 155 | int newStart = start; 156 | 157 | if (newStart == 0) { 158 | newStart = (items.length / 2 - size) / 2; 159 | } 160 | Object[] newItems = new Object[items.length / 2]; 161 | 162 | for (int i = 0; i < index; i++) { 163 | newItems[newStart + i] = items[start + i]; 164 | } 165 | for (int i = index; i < size - 1; i++) { 166 | newItems[newStart + i] = items[start + i + 1]; // проверить на ошибку 167 | } 168 | items = newItems; 169 | start = newStart; 170 | } 171 | 172 | @Override 173 | public boolean remove(T element) { 174 | int index = indexOf(element); 175 | if (index >= 0) { 176 | remove(index); 177 | return true; 178 | } 179 | return false; 180 | } 181 | 182 | @Override 183 | @SuppressWarnings("unchecked") 184 | public T get(int index) { 185 | if (index < 0 || index >= size) { 186 | throw new IllegalArgumentException("Not correct index"); 187 | } 188 | return (T) items[start + index]; 189 | } 190 | 191 | @Override 192 | public void set(int index, T element) { 193 | if (index < 0 || index >= size) { 194 | throw new IllegalArgumentException("Not correct index"); 195 | } 196 | items[start + index] = element; 197 | } 198 | 199 | @Override 200 | public int indexOf(T element) { 201 | for (int i = 0; i < size; i++) { 202 | if (Objects.equals(items[start + i], element)) { 203 | return i; 204 | } 205 | } 206 | return -1; 207 | } 208 | 209 | @Override 210 | public void clear() { 211 | Arrays.fill(items, null); 212 | size = 0; 213 | } 214 | 215 | @Override 216 | public void sort(Comparator comparator) { 217 | 218 | } 219 | } -------------------------------------------------------------------------------- /src/main/java/io/sancta/sanctorum/structures/tree/SimplyTree.java: -------------------------------------------------------------------------------- 1 | package io.sancta.sanctorum.structures.tree; 2 | 3 | import java.util.Iterator; 4 | import java.util.Random; 5 | 6 | public class SimplyTree> implements Tree { 7 | 8 | private Node root; 9 | private int size; 10 | 11 | @Override 12 | public int getSize() { 13 | return size; 14 | } 15 | 16 | @Override 17 | public boolean add(T element) { 18 | 19 | Node parent = findNode(element, true); 20 | 21 | if (parent == null) { 22 | root = new Node<>(); 23 | root.element = element; 24 | size++; 25 | return true; 26 | } else if (element.compareTo(parent.element) > 0) { 27 | parent.rightChild = new Node(); 28 | parent.rightChild.parent = parent; 29 | parent.rightChild.element = element; 30 | size++; 31 | return true; 32 | } else if (element.compareTo(parent.element) < 0) { 33 | parent.leftChild = new Node(); 34 | parent.leftChild.parent = parent; 35 | parent.leftChild.element = element; 36 | size++; 37 | return true; 38 | } else { 39 | return false; 40 | } 41 | } 42 | 43 | @Override 44 | public boolean remove(T element) { 45 | 46 | Node removeNode = findNode(element, false); 47 | 48 | if (removeNode == null) { 49 | return false; 50 | } else if (removeNode.leftChild == null && removeNode.rightChild == null) { 51 | if (removeNode == root) { 52 | root = null; 53 | } else if (removeNode.parent.leftChild == removeNode) { 54 | removeNode.parent.leftChild = null; 55 | } else { 56 | removeNode.parent.rightChild = null; 57 | } 58 | } else if (removeNode.leftChild != null && removeNode.rightChild == null) { 59 | removeWithOneChild(removeNode, true); 60 | } else if (removeNode.leftChild == null && removeNode.rightChild != null) { 61 | removeWithOneChild(removeNode, false); 62 | } else { 63 | if (removeNode == root) { 64 | if (new Random().nextBoolean()) { 65 | root = removeNode.leftChild; 66 | root.parent = null; 67 | hangRight(removeNode); 68 | } else { 69 | root = removeNode.rightChild; 70 | root.parent = null; 71 | hangLeft(removeNode); 72 | } 73 | } else if (removeNode.parent.leftChild == removeNode) { 74 | removeBothChildren(removeNode, true); 75 | } else { 76 | removeBothChildren(removeNode, false); 77 | } 78 | } 79 | size--; 80 | return true; 81 | } 82 | 83 | private void removeBothChildren(Node removeNode, boolean isLeft) { 84 | if (new Random().nextBoolean()) { 85 | if (isLeft) { 86 | removeNode.parent.leftChild = removeNode.leftChild; 87 | } else { 88 | removeNode.parent.rightChild = removeNode.leftChild; 89 | } 90 | 91 | removeNode.leftChild.parent = removeNode.parent; 92 | hangRight(removeNode); 93 | } else { 94 | if (isLeft) { 95 | removeNode.parent.leftChild = removeNode.rightChild; 96 | } else { 97 | removeNode.parent.rightChild = removeNode.rightChild; 98 | } 99 | removeNode.rightChild.parent = removeNode.parent; 100 | hangLeft(removeNode); 101 | } 102 | } 103 | 104 | private void hangLeft(Node removeNode) { 105 | Node left = mostChild(removeNode.rightChild, true); 106 | left.leftChild = removeNode.leftChild; 107 | removeNode.leftChild.parent = left; 108 | } 109 | 110 | private void hangRight(Node removeNode) { 111 | Node right = mostChild(removeNode.leftChild, false); 112 | right.rightChild = removeNode.rightChild; 113 | removeNode.rightChild.parent = right; 114 | } 115 | 116 | private void removeWithOneChild(Node removeNode, boolean isLeft) { 117 | if (removeNode == root) { 118 | root = (isLeft ? removeNode.leftChild : removeNode.rightChild); 119 | root.parent = null; 120 | } else if (removeNode.parent.leftChild == removeNode) { 121 | removeNode.parent.leftChild = (isLeft ? removeNode.leftChild : removeNode.rightChild); 122 | (isLeft ? removeNode.leftChild : removeNode.rightChild).parent = removeNode.parent; 123 | } else { 124 | removeNode.parent.rightChild = (isLeft ? removeNode.leftChild : removeNode.rightChild); 125 | (isLeft ? removeNode.leftChild : removeNode.rightChild).parent = removeNode.parent; 126 | } 127 | } 128 | 129 | @Override 130 | public boolean contains(T element) { 131 | return findNode(element, false) != null; 132 | } 133 | 134 | @Override 135 | public T getRoot() { 136 | return root.element; 137 | } 138 | 139 | @Override 140 | public Iterator iterator() { 141 | return new Iterator() { 142 | private int counter = 0; 143 | private Node currentNode = mostChild(root, true); 144 | 145 | @Override 146 | public boolean hasNext() { 147 | return counter < size; 148 | } 149 | 150 | @Override 151 | public T next() { 152 | Node result = currentNode; 153 | 154 | if (currentNode.rightChild == null) { 155 | if (currentNode.parent != null && currentNode.parent.leftChild == currentNode) { 156 | currentNode = currentNode.parent; 157 | } else { 158 | Node current = currentNode.parent; 159 | 160 | while (current != null && current.parent != null && current == current.parent.rightChild) { 161 | current = current.parent; 162 | } 163 | if (current != null) { 164 | current = current.parent; 165 | } 166 | currentNode = current; 167 | } 168 | } else { 169 | currentNode = mostChild(currentNode.rightChild, true); 170 | } 171 | 172 | counter++; 173 | return result.element; 174 | } 175 | }; 176 | } 177 | 178 | private Node mostChild(Node current, boolean isLeft) { 179 | while (current != null && (isLeft ? current.leftChild : current.rightChild) != null) { 180 | current = isLeft ? current.leftChild : current.rightChild; 181 | } 182 | return current; 183 | } 184 | 185 | private Node findNode(T element, boolean parent) { 186 | if (root == null) 187 | return null; 188 | 189 | Node current = root; 190 | Node parentNode; 191 | 192 | do { 193 | if (element.compareTo(current.element) > 0) { 194 | parentNode = current; 195 | current = current.rightChild; 196 | } else if (element.compareTo(current.element) < 0) { 197 | parentNode = current; 198 | current = current.leftChild; 199 | } else return current; 200 | } while (current != null); 201 | 202 | return parent ? parentNode : null; 203 | } 204 | } 205 | -------------------------------------------------------------------------------- /src/test/java/io/sancta/sanctorum/structures/list/ArrayListTest.java: -------------------------------------------------------------------------------- 1 | package io.sancta.sanctorum.structures.list; 2 | 3 | import org.junit.jupiter.api.BeforeEach; 4 | import org.junit.jupiter.api.DisplayName; 5 | import org.junit.jupiter.api.Test; 6 | 7 | import java.lang.reflect.Field; 8 | 9 | import static org.junit.jupiter.api.Assertions.*; 10 | 11 | class ArrayListTest { 12 | 13 | private ArrayList stringsList; 14 | 15 | @BeforeEach 16 | void init() { 17 | stringsList = new ArrayList<>(); 18 | } 19 | 20 | void fillListFourStrings() { 21 | stringsList.add("Привет"); 22 | stringsList.add("меня"); 23 | stringsList.add("зовут"); 24 | stringsList.add("Собака"); 25 | } 26 | 27 | void fillList5Strings() { 28 | stringsList.add("Привет"); 29 | stringsList.add(","); 30 | stringsList.add("меня"); 31 | stringsList.add("зовут"); 32 | stringsList.add("Собака"); 33 | } 34 | 35 | private void m() { 36 | assertAll("Проверка расположения элементов в листе", 37 | () -> assertEquals("Привет", stringsList.get(0)), 38 | () -> assertEquals("меня", stringsList.get(1)), 39 | () -> assertEquals("зовут", stringsList.get(2)), 40 | () -> assertEquals("Собака", stringsList.get(3)) 41 | ); 42 | } 43 | 44 | @Test 45 | @DisplayName("indexOf") 46 | void indexOf() { 47 | stringsList = new ArrayList<>(3); 48 | stringsList.add("меня"); 49 | stringsList.add("зовут"); 50 | stringsList.add("Собака"); 51 | stringsList.add(0, "Привет"); 52 | stringsList.add("!"); 53 | assertAll("Сценарий проверки метода indexOf()", 54 | () -> m(), 55 | () -> assertEquals(4, stringsList.indexOf("!")), 56 | () -> assertEquals(-1, stringsList.indexOf("Привет!")) 57 | ); 58 | } 59 | 60 | @Test 61 | @DisplayName("Проверка метода add с добавлением элемента в конец") 62 | void add() { 63 | fillListFourStrings(); 64 | assertAll("Сценарий проверки метода add()", 65 | () -> assertEquals(4, stringsList.size()), 66 | () -> assertEquals("Привет", stringsList.get(0)), 67 | () -> assertEquals("меня", stringsList.get(1)), 68 | () -> assertEquals("зовут", stringsList.get(2)), 69 | () -> assertEquals("Собака", stringsList.get(3)) 70 | ); 71 | } 72 | 73 | @Test 74 | @DisplayName("addWithCapacity") 75 | void addWithCapacity() { 76 | stringsList = new ArrayList<>(2); 77 | fillListFourStrings(); 78 | assertAll("Сценарий проверки метода add() с увеличением вместимости", 79 | () -> assertEquals(4, stringsList.size()), 80 | () -> assertEquals("Привет", stringsList.get(0)), 81 | () -> assertEquals("меня", stringsList.get(1)), 82 | () -> assertEquals("зовут", stringsList.get(2)), 83 | () -> assertEquals("Собака", stringsList.get(3)) 84 | ); 85 | } 86 | 87 | @Test 88 | @DisplayName("add проверка добавления в начало") 89 | void addWithRecreateLeft() { 90 | stringsList = new ArrayList<>(3); 91 | stringsList.add("меня"); 92 | stringsList.add("зовут"); 93 | stringsList.add("Собака"); 94 | stringsList.add(0, "Привет"); 95 | stringsList.add("!"); 96 | assertAll("Сценарий проверки метода add() со сдвигом элементов в лево", 97 | () -> assertEquals(5, stringsList.size()), 98 | () -> assertEquals("Привет", stringsList.get(0)), 99 | () -> assertEquals("меня", stringsList.get(1)), 100 | () -> assertEquals("зовут", stringsList.get(2)), 101 | () -> assertEquals("Собака", stringsList.get(3)), 102 | () -> assertEquals("!", stringsList.get(4)) 103 | ); 104 | } 105 | 106 | @Test 107 | @DisplayName("addWithLeftReserve") 108 | void addWithLeftReserve() { 109 | stringsList = new ArrayList<>(3); 110 | stringsList.add("зовут"); 111 | stringsList.add("Собака"); 112 | stringsList.add("!"); 113 | stringsList.add(0, "Привет"); 114 | stringsList.add(1, "меня"); 115 | assertAll(" ", 116 | () -> assertEquals(5, stringsList.size()), 117 | () -> assertEquals("Привет", stringsList.get(0)), 118 | () -> assertEquals("меня", stringsList.get(1)), 119 | () -> assertEquals("зовут", stringsList.get(2)), 120 | () -> assertEquals("Собака", stringsList.get(3)), 121 | () -> assertEquals("!", stringsList.get(4)) 122 | ); 123 | } 124 | 125 | @Test 126 | @DisplayName("addWithLeftShift") 127 | void addWithLeftShift() { 128 | stringsList = new ArrayList<>(4); 129 | stringsList.add("Привет"); 130 | stringsList.add("зовут"); 131 | stringsList.add("Собака"); 132 | stringsList.add(1, "меня"); 133 | assertAll(" ", 134 | () -> assertEquals(4, stringsList.size()), 135 | () -> assertEquals("Привет", stringsList.get(0)), 136 | () -> assertEquals("меня", stringsList.get(1)), 137 | () -> assertEquals("зовут", stringsList.get(2)), 138 | () -> assertEquals("Собака", stringsList.get(3)) 139 | ); 140 | } 141 | 142 | @Test 143 | @DisplayName("addWithRightShift") 144 | void addWithRightShift() { 145 | stringsList = new ArrayList<>(4); 146 | stringsList.add("меня"); 147 | stringsList.add("зовут"); 148 | stringsList.add(0, "Привет"); 149 | stringsList.add("Собака"); 150 | assertAll(" ", 151 | () -> assertEquals(4, stringsList.size()), 152 | () -> assertEquals("Привет", stringsList.get(0)), 153 | () -> assertEquals("меня", stringsList.get(1)), 154 | () -> assertEquals("зовут", stringsList.get(2)), 155 | () -> assertEquals("Собака", stringsList.get(3)) 156 | ); 157 | } 158 | 159 | @Test 160 | @DisplayName("removeLeft") 161 | void removeLeft() { 162 | fillList5Strings(); 163 | stringsList.remove(1); 164 | assertAll(" ", 165 | () -> assertEquals(4, stringsList.size()), 166 | () -> assertEquals("меня", stringsList.get(1)), 167 | () -> assertEquals("Привет", stringsList.get(0)), 168 | () -> assertEquals("зовут", stringsList.get(2)), 169 | () -> assertEquals("Собака", stringsList.get(3)) 170 | ); 171 | } 172 | 173 | @Test 174 | @DisplayName("removeRight") 175 | void removeRight() { 176 | fillList5Strings(); 177 | stringsList.remove(3); 178 | assertAll(" ", 179 | () -> assertEquals(4, stringsList.size()), 180 | () -> assertEquals("Привет", stringsList.get(0)), 181 | () -> assertEquals(",", stringsList.get(1)), 182 | () -> assertEquals("меня", stringsList.get(2)), 183 | () -> assertEquals("Собака", stringsList.get(3)) 184 | ); 185 | } 186 | 187 | @Test 188 | @DisplayName("remove") 189 | void remove() throws NoSuchFieldException, IllegalAccessException { 190 | stringsList = new ArrayList<>(100); 191 | fillList5Strings(); 192 | stringsList.remove(1); 193 | assertAll(" ", 194 | () -> assertEquals(4, stringsList.size()), 195 | () -> assertEquals("Привет", stringsList.get(0)), 196 | () -> assertEquals("меня", stringsList.get(1)), 197 | () -> assertEquals("зовут", stringsList.get(2)), 198 | () -> assertEquals("Собака", stringsList.get(3)) 199 | ); 200 | Field f = ArrayList.class.getDeclaredField("items"); 201 | f.setAccessible(true); 202 | assertEquals(50, ((Object[]) f.get(stringsList)).length); 203 | } 204 | 205 | @Test 206 | @DisplayName("clear") 207 | void clear() { 208 | stringsList = new ArrayList<>(); 209 | fillList5Strings(); 210 | stringsList.clear(); 211 | assertEquals(0, stringsList.size()); 212 | } 213 | } -------------------------------------------------------------------------------- /src/test/java/io/sancta/sanctorum/structures/list/DoubleLinkedListTest.java: -------------------------------------------------------------------------------- 1 | package io.sancta.sanctorum.structures.list; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import static org.junit.jupiter.api.Assertions.*; 6 | 7 | class DoubleLinkedListTest { 8 | 9 | @Test 10 | void add() { 11 | DoubleLinkedList list = new DoubleLinkedList<>(); 12 | list.add("Привет"); 13 | list.add("меня"); 14 | list.add("зовут"); 15 | list.add("Собака"); 16 | assertEquals(4, list.size()); 17 | assertEquals("Привет", list.get(0)); 18 | assertEquals("меня", list.get(1)); 19 | assertEquals("зовут", list.get(2)); 20 | assertEquals("Собака", list.get(3)); 21 | } 22 | 23 | @Test 24 | void addFirst(){ 25 | DoubleLinkedList list = new DoubleLinkedList<>(); 26 | list.add("меня"); 27 | list.add("зовут"); 28 | list.add("Собака"); 29 | list.add(0, "Привет"); 30 | assertEquals(4, list.size()); 31 | assertEquals("Привет", list.get(0)); 32 | assertEquals("меня", list.get(1)); 33 | assertEquals("зовут", list.get(2)); 34 | assertEquals("Собака", list.get(3)); 35 | } 36 | 37 | @Test 38 | void addFirstHalf(){ 39 | DoubleLinkedList list = new DoubleLinkedList<>(); 40 | list.add("Привет"); 41 | list.add("меня"); 42 | list.add("зовут"); 43 | list.add("Собака"); 44 | list.add(1, ","); 45 | assertEquals(5, list.size()); 46 | assertEquals("Привет", list.get(0)); 47 | assertEquals(",", list.get(1)); 48 | assertEquals("меня", list.get(2)); 49 | assertEquals("зовут", list.get(3)); 50 | assertEquals("Собака", list.get(4)); 51 | } 52 | 53 | @Test 54 | void addSecondHalf(){ 55 | DoubleLinkedList list = new DoubleLinkedList<>(); 56 | list.add("Привет"); 57 | list.add("меня"); 58 | list.add("зовут"); 59 | list.add("Собака"); 60 | list.add(3,","); 61 | assertEquals(5, list.size()); 62 | assertEquals("Привет", list.get(0)); 63 | assertEquals("меня", list.get(1)); 64 | assertEquals("зовут", list.get(2)); 65 | assertEquals(",", list.get(3)); 66 | assertEquals("Собака", list.get(4)); 67 | } 68 | 69 | @Test 70 | void indexOf(){ 71 | DoubleLinkedList list = new DoubleLinkedList<>(); 72 | list.add("Привет"); 73 | list.add("меня"); 74 | list.add("зовут"); 75 | list.add("Собака"); 76 | assertEquals(0, list.indexOf("Привет")); 77 | assertEquals(1, list.indexOf("меня")); 78 | assertEquals(2, list.indexOf("зовут")); 79 | assertEquals(3, list.indexOf("Собака")); 80 | assertEquals(-1, list.indexOf("Привет!")); 81 | } 82 | 83 | @Test 84 | void removeWrongIndex() { 85 | DoubleLinkedList list = new DoubleLinkedList<>(); 86 | list.add("Привет"); 87 | try { 88 | list.remove(10); 89 | fail("No error"); 90 | } 91 | catch (IllegalArgumentException ignore) { 92 | } 93 | } 94 | 95 | @Test 96 | void removeSingle () { 97 | DoubleLinkedList list = new DoubleLinkedList<>(); 98 | list.add("Привет"); 99 | list.remove(0); 100 | assertEquals(0, list.size()); 101 | list.add("Привет"); 102 | list.add("меня"); 103 | list.add("зовут"); 104 | list.add("Собака"); 105 | check(list); 106 | } 107 | 108 | void check (DoubleLinkedList list){ 109 | assertEquals("Привет", list.get(0)); 110 | assertEquals("меня", list.get(1)); 111 | assertEquals("зовут", list.get(2)); 112 | assertEquals("Собака", list.get(3)); 113 | assertEquals(4, list.size()); 114 | } 115 | 116 | @Test 117 | void removeFirstOf2 (){ 118 | DoubleLinkedList list = new DoubleLinkedList<>(); 119 | list.add("Привет"); 120 | list.add("меня"); 121 | list.remove(0); 122 | assertEquals(1, list.size()); 123 | assertEquals("меня", list.get(0)); 124 | list.add(0, "Привет"); 125 | list.add("зовут"); 126 | list.add("Собака"); 127 | check(list); 128 | } 129 | 130 | @Test 131 | void removeSecondOf2 (){ 132 | DoubleLinkedList list = new DoubleLinkedList<>(); 133 | list.add("Привет"); 134 | list.add("меня"); 135 | list.remove(1); 136 | assertEquals(1, list.size()); 137 | assertEquals("Привет", list.get(0)); 138 | list.add("меня"); 139 | list.add("зовут"); 140 | list.add("Собака"); 141 | check(list); 142 | } 143 | 144 | @Test 145 | void removeFirstOfMany() { 146 | DoubleLinkedList list = new DoubleLinkedList<>(); 147 | list.add("Привет"); 148 | list.add("меня"); 149 | list.add("зовут"); 150 | list.add("Собака"); 151 | list.remove(0); 152 | assertEquals(3,list.size()); 153 | assertEquals("меня",list.get(0)); 154 | assertEquals("зовут",list.get(1)); 155 | assertEquals("Собака",list.get(2)); 156 | list.add(0, "Привет"); 157 | check(list); 158 | } 159 | 160 | @Test 161 | void removeLastOfMany() { 162 | DoubleLinkedList list = new DoubleLinkedList<>(); 163 | list.add("Привет"); 164 | list.add("меня"); 165 | list.add("зовут"); 166 | list.add("Собака"); 167 | list.remove(3); 168 | assertEquals(3,list.size()); 169 | assertEquals("Привет", list.get(0)); 170 | assertEquals("меня",list.get(1)); 171 | assertEquals("зовут",list.get(2)); 172 | list.add("Собака"); 173 | check(list); 174 | } 175 | 176 | @Test 177 | void removeMiddleOfMany() { 178 | DoubleLinkedList list = new DoubleLinkedList<>(); 179 | list.add("Привет"); 180 | list.add(","); 181 | list.add("меня"); 182 | list.add("зовут"); 183 | list.add("Собака"); 184 | list.remove(1); 185 | check(list); 186 | } 187 | 188 | @Test 189 | void removeSingleElement() { 190 | DoubleLinkedList list = new DoubleLinkedList<>(); 191 | list.add("Привет"); 192 | assertTrue(list.remove("Привет")); 193 | assertEquals(0, list.size()); 194 | list.add("Привет"); 195 | list.add("меня"); 196 | list.add("зовут"); 197 | list.add("Собака"); 198 | check(list); 199 | } 200 | 201 | @Test 202 | void removeFirstOf2Elements (){ 203 | DoubleLinkedList list = new DoubleLinkedList<>(); 204 | list.add("Привет"); 205 | list.add("меня"); 206 | assertTrue(list.remove("Привет")); 207 | assertEquals(1, list.size()); 208 | assertEquals("меня", list.get(0)); 209 | list.add(0, "Привет"); 210 | list.add("зовут"); 211 | list.add("Собака"); 212 | check(list); 213 | } 214 | 215 | @Test 216 | void removeSecondOf2Elements (){ 217 | DoubleLinkedList list = new DoubleLinkedList<>(); 218 | list.add("Привет"); 219 | list.add("меня"); 220 | assertTrue(list.remove("меня")); 221 | assertEquals(1, list.size()); 222 | assertEquals("Привет", list.get(0)); 223 | list.add("меня"); 224 | list.add("зовут"); 225 | list.add("Собака"); 226 | check(list); 227 | } 228 | 229 | @Test 230 | void removeFirstOfManyElements() { 231 | DoubleLinkedList list = new DoubleLinkedList<>(); 232 | list.add("Привет"); 233 | list.add("меня"); 234 | list.add("зовут"); 235 | list.add("Собака"); 236 | assertTrue(list.remove("Привет")); 237 | assertEquals(3,list.size()); 238 | assertEquals("меня",list.get(0)); 239 | assertEquals("зовут",list.get(1)); 240 | assertEquals("Собака",list.get(2)); 241 | list.add(0, "Привет"); 242 | check(list); 243 | } 244 | 245 | @Test 246 | void removeLastOfManyElements() { 247 | DoubleLinkedList list = new DoubleLinkedList<>(); 248 | list.add("Привет"); 249 | list.add("меня"); 250 | list.add("зовут"); 251 | list.add("Собака"); 252 | assertTrue(list.remove("Собака")); 253 | assertEquals(3,list.size()); 254 | assertEquals("Привет", list.get(0)); 255 | assertEquals("меня",list.get(1)); 256 | assertEquals("зовут",list.get(2)); 257 | list.add("Собака"); 258 | check(list); 259 | } 260 | 261 | @Test 262 | void removeMiddleOfManyElements() { 263 | DoubleLinkedList list = new DoubleLinkedList<>(); 264 | list.add("Привет"); 265 | list.add(","); 266 | list.add("меня"); 267 | list.add("зовут"); 268 | list.add("Собака"); 269 | assertTrue(list.remove(",")); 270 | check(list); 271 | } 272 | 273 | @Test 274 | void removeZeroOfManyElements() { 275 | DoubleLinkedList list = new DoubleLinkedList<>(); 276 | list.add("Привет"); 277 | list.add("меня"); 278 | list.add("зовут"); 279 | list.add("Собака"); 280 | assertFalse(list.remove("Привет!")); 281 | check(list); 282 | } 283 | 284 | @Test 285 | void clear() { 286 | DoubleLinkedList list = new DoubleLinkedList<>(); 287 | list.add("Привет"); 288 | list.add("меня"); 289 | list.add("зовут"); 290 | list.add("Собака"); 291 | list.clear(); 292 | assertEquals(0, list.size()); 293 | } 294 | } -------------------------------------------------------------------------------- /src/main/java/io/sancta/sanctorum/structures/list/SingleLinkedList.java: -------------------------------------------------------------------------------- 1 | package io.sancta.sanctorum.structures.list; 2 | 3 | import io.sancta.sanctorum.structures.AbstractCollection; 4 | 5 | import java.util.*; 6 | import java.util.function.Consumer; 7 | 8 | public class SingleLinkedList extends AbstractCollection implements List { 9 | 10 | private Node first; 11 | private Node last; 12 | private int size; 13 | 14 | private static class Node { 15 | private T element; 16 | private Node next; 17 | } 18 | 19 | @Override 20 | public int size() { 21 | return size; 22 | } 23 | 24 | @Override 25 | public void add(T element) { 26 | add(size, element); 27 | } 28 | 29 | @Override 30 | public void add(int index, T element) { 31 | checkPositionIndex(index); 32 | 33 | Node node = new Node<>(); 34 | node.element = element; 35 | 36 | if (index == size) { 37 | if (size == 0) { 38 | first = node; 39 | } else { 40 | last.next = node; 41 | } 42 | 43 | last = node; 44 | size++; 45 | return; 46 | } 47 | 48 | if (index == 0) { 49 | node.next = first; 50 | first = node; 51 | size++; 52 | return; 53 | } 54 | Node previous = first; 55 | for (int i = 1; i < index; i++) { 56 | previous = previous.next; 57 | } 58 | node.next = previous.next; 59 | previous.next = node; 60 | size++; 61 | } 62 | 63 | public void addAll(Collection collection) { 64 | addAll(size, collection); 65 | } 66 | 67 | 68 | public void addAll(int index, Collection collection) { 69 | checkPositionIndex(index); 70 | } 71 | 72 | @Override 73 | public void remove(int index) { 74 | checkElementIndex(index); 75 | 76 | if (size == 1) { 77 | first = null; 78 | last = null; 79 | size--; 80 | return; 81 | } 82 | if (size == 2) { 83 | if (index == 0) { 84 | first = last; 85 | } else { 86 | last = first; 87 | first.next = null; 88 | } 89 | size--; 90 | return; 91 | } 92 | if (index == 0) { 93 | first = first.next; 94 | size--; 95 | return; 96 | } 97 | Node previous = first; 98 | for (int i = 1; i < index; i++) { 99 | previous = previous.next; 100 | } 101 | 102 | previous.next = previous.next.next; 103 | 104 | if (index == size - 1) { 105 | last = previous; 106 | } 107 | size--; 108 | } 109 | 110 | @Override 111 | public boolean remove(T element) { 112 | 113 | if (size == 0) { 114 | return false; 115 | } 116 | 117 | if (size == 1) { 118 | return removeWhenOne(element); 119 | } 120 | 121 | if (size == 2) { 122 | return removeWhenTwo(element); 123 | } 124 | 125 | return findAndRemove(element); 126 | } 127 | 128 | private boolean removeWhenOne(T element) { 129 | if (Objects.equals(first.element, element)) { 130 | first = null; 131 | last = null; 132 | size--; 133 | return true; 134 | } else { 135 | return false; 136 | } 137 | } 138 | 139 | private boolean removeWhenTwo(T element) { 140 | if (Objects.equals(first.element, element)) { 141 | first = last; 142 | size--; 143 | return true; 144 | } else if (Objects.equals(last.element, element)) { 145 | last = first; 146 | first.next = null; 147 | size--; 148 | return true; 149 | } else { 150 | return false; 151 | } 152 | } 153 | 154 | private boolean findAndRemove(T element) { 155 | 156 | if (Objects.equals(first.element, element)) { 157 | first = first.next; 158 | size--; 159 | return true; 160 | } 161 | 162 | Node previous = first; 163 | for (int i = 1; i < size; i++) { 164 | if (Objects.equals(previous.next.element, element)) { 165 | previous.next = previous.next.next; 166 | if (i == size - 1) 167 | last = previous; 168 | size--; 169 | return true; 170 | } 171 | previous = previous.next; 172 | } 173 | return false; 174 | } 175 | 176 | @Override 177 | public T get(int index) { 178 | checkElementIndex(index); 179 | 180 | Node node = first; 181 | for (int i = 0; i < index; i++) { 182 | node = node.next; 183 | } 184 | 185 | return node.element; 186 | } 187 | 188 | @Override 189 | public void set(int index, T element) { 190 | checkElementIndex(index); 191 | 192 | Node node = first; 193 | for (int i = 0; i < index; i++) { 194 | node = node.next; 195 | } 196 | node.element = element; 197 | } 198 | 199 | @Override 200 | public int indexOf(T element) { 201 | Node node = first; 202 | for (int i = 0; i < size; i++) { 203 | if (Objects.equals(node.element, element)) { 204 | return i; 205 | } 206 | node = node.next; 207 | } 208 | return -1; 209 | } 210 | 211 | @Override 212 | public void clear() { 213 | first = null; 214 | last = null; 215 | size = 0; 216 | } 217 | 218 | public boolean contains(T element) { 219 | return indexOf(element) >= 0; 220 | } 221 | 222 | public Object[] toArray() { 223 | Object[] result = new Object[size]; 224 | Node node = first; 225 | for (int i = 0; i < size; i++) { 226 | result[i] = node.element; 227 | node = node.next; 228 | } 229 | return result; 230 | } 231 | 232 | @Override 233 | public void sort(Comparator comparator) { 234 | 235 | Object[] array = this.toArray(); 236 | Arrays.sort(array, (Comparator) comparator); 237 | 238 | ListIterator iterator = this.listIterator(); 239 | 240 | for (Object object : array) { 241 | iterator.next(); 242 | iterator.set((T) object); 243 | } 244 | } 245 | 246 | /* дополниельный код */ 247 | 248 | int modCount = 0; 249 | 250 | Node node(int index) { 251 | 252 | Node node = first; 253 | for (int i = 0; i < index; i++) 254 | node = node.next; 255 | return node; 256 | } 257 | 258 | public ListIterator listIterator() { 259 | return listIterator(0); 260 | } 261 | 262 | public ListIterator listIterator(int index) { 263 | checkPositionIndex(index); 264 | return new ListItr(index); 265 | } 266 | 267 | private class ListItr implements ListIterator { 268 | private Node lastReturned; 269 | private Node next; 270 | private int nextIndex; 271 | private int expectedModCount = modCount; 272 | 273 | ListItr(int index) { 274 | // assert isPositionIndex(index); 275 | next = (index == size) ? null : node(index); 276 | nextIndex = index; 277 | } 278 | 279 | public boolean hasNext() { 280 | return nextIndex < size; 281 | } 282 | 283 | public T next() { 284 | checkForComodification(); 285 | if (!hasNext()) 286 | throw new NoSuchElementException(); 287 | 288 | lastReturned = next; 289 | next = next.next; 290 | nextIndex++; 291 | return lastReturned.element; 292 | } 293 | 294 | public boolean hasPrevious() { 295 | return nextIndex > 0; 296 | } 297 | 298 | public int nextIndex() { 299 | return nextIndex; 300 | } 301 | 302 | public int previousIndex() { 303 | return nextIndex - 1; 304 | } 305 | 306 | public void set(T e) { 307 | if (lastReturned == null) 308 | throw new IllegalStateException(); 309 | checkForComodification(); 310 | lastReturned.element = e; 311 | } 312 | 313 | public void forEachRemaining(Consumer action) { 314 | Objects.requireNonNull(action); 315 | while (modCount == expectedModCount && nextIndex < size) { 316 | action.accept(next.element); 317 | lastReturned = next; 318 | next = next.next; 319 | nextIndex++; 320 | } 321 | checkForComodification(); 322 | } 323 | 324 | final void checkForComodification() { 325 | if (modCount != expectedModCount) 326 | throw new ConcurrentModificationException(); 327 | } 328 | } 329 | 330 | private boolean isElementIndex(int index) { 331 | return index >= 0 && index < size; 332 | } 333 | 334 | private boolean isPositionIndex(int index) { 335 | return index >= 0 && index <= size; 336 | } 337 | 338 | 339 | private String outOfBoundsMsg(int index) { 340 | return "Index: " + index + ", Size: " + size; 341 | } 342 | 343 | private void checkElementIndex(int index) { 344 | if (!isElementIndex(index)) 345 | throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); 346 | } 347 | 348 | private void checkPositionIndex(int index) { 349 | if (!isPositionIndex(index)) 350 | throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); 351 | } 352 | } 353 | -------------------------------------------------------------------------------- /src/test/java/io/sancta/sanctorum/structures/list/SingleLinkedListTest.java: -------------------------------------------------------------------------------- 1 | package io.sancta.sanctorum.structures.list; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import static org.junit.jupiter.api.Assertions.*; 6 | 7 | class SingleLinkedListTest { 8 | 9 | @Test 10 | void add() { 11 | SingleLinkedList list = new SingleLinkedList<>(); 12 | list.add("Привет"); 13 | list.add("меня"); 14 | list.add("зовут"); 15 | list.add("Собака"); 16 | assertEquals(4, list.size()); 17 | assertEquals("Привет", list.get(0)); 18 | assertEquals("меня", list.get(1)); 19 | assertEquals("зовут", list.get(2)); 20 | assertEquals("Собака", list.get(3)); 21 | } 22 | 23 | @Test 24 | void addWithIndex() { 25 | SingleLinkedList list = new SingleLinkedList<>(); 26 | list.add("меня"); 27 | list.add("зовут"); 28 | list.add("Собака"); 29 | list.add(0, "Привет"); 30 | list.add(1, ","); 31 | assertEquals(5, list.size()); 32 | assertEquals("Привет", list.get(0)); 33 | assertEquals(",", list.get(1)); 34 | assertEquals("меня", list.get(2)); 35 | assertEquals("зовут", list.get(3)); 36 | assertEquals("Собака", list.get(4)); 37 | } 38 | 39 | @Test 40 | void addWrong() { 41 | SingleLinkedList list = new SingleLinkedList<>(); 42 | 43 | assertThrows(IllegalArgumentException.class, () -> list.add(2, " ")); 44 | } 45 | 46 | @Test 47 | void set() { 48 | SingleLinkedList list = new SingleLinkedList<>(); 49 | list.add("Привет"); 50 | list.add("меня"); 51 | list.add("зовут"); 52 | list.add("Собака"); 53 | list.set(3, "Кошка"); 54 | assertEquals(4, list.size()); 55 | assertEquals("Привет", list.get(0)); 56 | assertEquals("меня", list.get(1)); 57 | assertEquals("зовут", list.get(2)); 58 | assertEquals("Кошка", list.get(3)); 59 | } 60 | 61 | @Test 62 | void setWrong() { 63 | try { 64 | SingleLinkedList list = new SingleLinkedList<>(); 65 | list.set(3, " "); 66 | fail("No exception"); 67 | } catch (IndexOutOfBoundsException ignored) { 68 | } 69 | } 70 | 71 | @Test 72 | void indexOf() { 73 | SingleLinkedList list = new SingleLinkedList<>(); 74 | list.add("Привет"); 75 | list.add("меня"); 76 | list.add("зовут"); 77 | list.add("Собака"); 78 | assertEquals(3, list.indexOf("Собака")); 79 | assertEquals(-1, list.indexOf("Кошка")); 80 | } 81 | 82 | @Test 83 | void removeOneElement() { 84 | SingleLinkedList list = new SingleLinkedList<>(); 85 | list.add("Привет"); 86 | list.remove(0); 87 | assertEquals(0, list.size()); 88 | list.add("Привет"); 89 | list.add("меня"); 90 | list.add("зовут"); 91 | list.add("Собака"); 92 | assertEquals(4, list.size()); 93 | assertEquals("Привет", list.get(0)); 94 | assertEquals("меня", list.get(1)); 95 | assertEquals("зовут", list.get(2)); 96 | assertEquals("Собака", list.get(3)); 97 | } 98 | 99 | @Test 100 | void removeFirstOf2Elements() { 101 | SingleLinkedList list = new SingleLinkedList<>(); 102 | list.add("Привет"); 103 | list.add("меня"); 104 | list.remove(0); 105 | assertEquals(1, list.size()); 106 | assertEquals("меня", list.get(0)); 107 | list.add(0, "Привет"); 108 | list.add("зовут"); 109 | list.add("Собака"); 110 | assertEquals(4, list.size()); 111 | assertEquals("Привет", list.get(0)); 112 | assertEquals("меня", list.get(1)); 113 | assertEquals("зовут", list.get(2)); 114 | assertEquals("Собака", list.get(3)); 115 | } 116 | 117 | @Test 118 | void removeSecondOf2Elements() { 119 | SingleLinkedList list = new SingleLinkedList<>(); 120 | list.add("Привет"); 121 | list.add("меня"); 122 | list.remove(1); 123 | assertEquals(1, list.size()); 124 | assertEquals("Привет", list.get(0)); 125 | list.add(1, "меня"); 126 | list.add("зовут"); 127 | list.add("Собака"); 128 | assertEquals(4, list.size()); 129 | assertEquals("Привет", list.get(0)); 130 | assertEquals("меня", list.get(1)); 131 | assertEquals("зовут", list.get(2)); 132 | assertEquals("Собака", list.get(3)); 133 | } 134 | 135 | @Test 136 | void removeFirstOfMany() { 137 | SingleLinkedList list = new SingleLinkedList<>(); 138 | list.add("Привет"); 139 | list.add("меня"); 140 | list.add("зовут"); 141 | list.add("Собака"); 142 | list.remove(0); 143 | assertEquals(3, list.size()); 144 | assertEquals("меня", list.get(0)); 145 | assertEquals("зовут", list.get(1)); 146 | assertEquals("Собака", list.get(2)); 147 | list.add(0, "Привет"); 148 | assertEquals(4, list.size()); 149 | assertEquals("Привет", list.get(0)); 150 | assertEquals("меня", list.get(1)); 151 | assertEquals("зовут", list.get(2)); 152 | assertEquals("Собака", list.get(3)); 153 | } 154 | 155 | @Test 156 | void removeLastOfMany() { 157 | SingleLinkedList list = new SingleLinkedList<>(); 158 | list.add("Привет"); 159 | list.add("меня"); 160 | list.add("зовут"); 161 | list.add("Собака"); 162 | list.remove(3); 163 | assertEquals(3, list.size()); 164 | assertEquals("Привет", list.get(0)); 165 | assertEquals("меня", list.get(1)); 166 | assertEquals("зовут", list.get(2)); 167 | list.add(3, "Собака"); 168 | assertEquals(4, list.size()); 169 | assertEquals("Привет", list.get(0)); 170 | assertEquals("меня", list.get(1)); 171 | assertEquals("зовут", list.get(2)); 172 | assertEquals("Собака", list.get(3)); 173 | } 174 | 175 | @Test 176 | void removeOfMany() { 177 | SingleLinkedList list = new SingleLinkedList<>(); 178 | list.add("Привет"); 179 | list.add(","); 180 | list.add("меня"); 181 | list.add("зовут"); 182 | list.add("Собака"); 183 | list.remove(2); 184 | assertEquals(4, list.size()); 185 | assertEquals("Привет", list.get(0)); 186 | assertEquals(",", list.get(1)); 187 | assertEquals("зовут", list.get(2)); 188 | assertEquals("Собака", list.get(3)); 189 | } 190 | 191 | @Test 192 | void removeElementOfElement() { 193 | SingleLinkedList list = new SingleLinkedList<>(); 194 | list.add("Привет"); 195 | assertTrue(list.remove("Привет")); 196 | assertEquals(0, list.size()); 197 | list.add("Привет"); 198 | list.add("меня"); 199 | list.add("зовут"); 200 | list.add("Собака"); 201 | assertEquals(4, list.size()); 202 | assertEquals("Привет", list.get(0)); 203 | assertEquals("меня", list.get(1)); 204 | assertEquals("зовут", list.get(2)); 205 | assertEquals("Собака", list.get(3)); 206 | } 207 | 208 | @Test 209 | void removeFirstOf2ElementsOfElement() { 210 | SingleLinkedList list = new SingleLinkedList<>(); 211 | list.add("Привет"); 212 | list.add("меня"); 213 | assertTrue(list.remove("Привет")); 214 | assertEquals(1, list.size()); 215 | assertEquals("меня", list.get(0)); 216 | list.add(0, "Привет"); 217 | list.add("зовут"); 218 | list.add("Собака"); 219 | assertEquals(4, list.size()); 220 | assertEquals("Привет", list.get(0)); 221 | assertEquals("меня", list.get(1)); 222 | assertEquals("зовут", list.get(2)); 223 | assertEquals("Собака", list.get(3)); 224 | } 225 | 226 | @Test 227 | void removeSecondOf2ElementsOfElement() { 228 | SingleLinkedList list = new SingleLinkedList<>(); 229 | list.add("Привет"); 230 | list.add("меня"); 231 | assertTrue(list.remove("меня")); 232 | assertEquals(1, list.size()); 233 | assertEquals("Привет", list.get(0)); 234 | list.add(1, "меня"); 235 | list.add("зовут"); 236 | list.add("Собака"); 237 | assertEquals(4, list.size()); 238 | assertEquals("Привет", list.get(0)); 239 | assertEquals("меня", list.get(1)); 240 | assertEquals("зовут", list.get(2)); 241 | assertEquals("Собака", list.get(3)); 242 | } 243 | 244 | @Test 245 | void removeFirstOfManyOfElement() { 246 | SingleLinkedList list = new SingleLinkedList<>(); 247 | list.add("Привет"); 248 | list.add("меня"); 249 | list.add("зовут"); 250 | list.add("Собака"); 251 | assertTrue(list.remove("Привет")); 252 | assertEquals(3, list.size()); 253 | assertEquals("меня", list.get(0)); 254 | assertEquals("зовут", list.get(1)); 255 | assertEquals("Собака", list.get(2)); 256 | list.add(0, "Привет"); 257 | assertEquals(4, list.size()); 258 | assertEquals("Привет", list.get(0)); 259 | assertEquals("меня", list.get(1)); 260 | assertEquals("зовут", list.get(2)); 261 | assertEquals("Собака", list.get(3)); 262 | } 263 | 264 | @Test 265 | void removeLastOfManyOfElement() { 266 | SingleLinkedList list = new SingleLinkedList<>(); 267 | list.add("Привет"); 268 | list.add("меня"); 269 | list.add("зовут"); 270 | list.add("Собака"); 271 | assertTrue(list.remove("Собака")); 272 | assertEquals(3, list.size()); 273 | assertEquals("Привет", list.get(0)); 274 | assertEquals("меня", list.get(1)); 275 | assertEquals("зовут", list.get(2)); 276 | list.add(3, "Собака"); 277 | assertEquals(4, list.size()); 278 | assertEquals("Привет", list.get(0)); 279 | assertEquals("меня", list.get(1)); 280 | assertEquals("зовут", list.get(2)); 281 | assertEquals("Собака", list.get(3)); 282 | 283 | } 284 | 285 | @Test 286 | void removeOfManyOfElement() { 287 | SingleLinkedList list = new SingleLinkedList<>(); 288 | list.add("Привет"); 289 | list.add(","); 290 | list.add("меня"); 291 | list.add("зовут"); 292 | list.add("Собака"); 293 | assertTrue(list.remove("меня")); 294 | assertEquals(4, list.size()); 295 | assertEquals("Привет", list.get(0)); 296 | assertEquals(",", list.get(1)); 297 | assertEquals("зовут", list.get(2)); 298 | assertEquals("Собака", list.get(3)); 299 | } 300 | 301 | @Test 302 | void removeZeroElement() { 303 | SingleLinkedList list = new SingleLinkedList<>(); 304 | assertFalse(list.remove("Привет")); 305 | assertEquals(0, list.size()); 306 | list.add("Привет"); 307 | list.add("меня"); 308 | list.add("зовут"); 309 | list.add("Собака"); 310 | assertEquals(4, list.size()); 311 | assertEquals("Привет", list.get(0)); 312 | assertEquals("меня", list.get(1)); 313 | assertEquals("зовут", list.get(2)); 314 | assertEquals("Собака", list.get(3)); 315 | } 316 | 317 | @Test 318 | void removeZeroOfElement() { 319 | SingleLinkedList stringSingleLinkedList = new SingleLinkedList<>(); 320 | stringSingleLinkedList.add("Привет"); 321 | assertFalse(stringSingleLinkedList.remove("Привет!")); 322 | assertEquals(1, stringSingleLinkedList.size()); 323 | stringSingleLinkedList.add("меня"); 324 | stringSingleLinkedList.add("зовут"); 325 | stringSingleLinkedList.add("Собака"); 326 | assertEquals(4, stringSingleLinkedList.size()); 327 | assertEquals("Привет", stringSingleLinkedList.get(0)); 328 | assertEquals("меня", stringSingleLinkedList.get(1)); 329 | assertEquals("зовут", stringSingleLinkedList.get(2)); 330 | assertEquals("Собака", stringSingleLinkedList.get(3)); 331 | } 332 | 333 | @Test 334 | void removeZeroOf2ElementsOfElement() { 335 | SingleLinkedList stringSingleLinkedList = new SingleLinkedList<>(); 336 | stringSingleLinkedList.add("Привет"); 337 | stringSingleLinkedList.add("меня"); 338 | assertFalse(stringSingleLinkedList.remove("Привет!")); 339 | assertEquals(2, stringSingleLinkedList.size()); 340 | assertEquals("меня", stringSingleLinkedList.get(1)); 341 | stringSingleLinkedList.add("зовут"); 342 | stringSingleLinkedList.add("Собака"); 343 | assertEquals(4, stringSingleLinkedList.size()); 344 | assertEquals("Привет", stringSingleLinkedList.get(0)); 345 | assertEquals("меня", stringSingleLinkedList.get(1)); 346 | assertEquals("зовут", stringSingleLinkedList.get(2)); 347 | assertEquals("Собака", stringSingleLinkedList.get(3)); 348 | } 349 | 350 | @Test 351 | void removeZeroOfManyOfElement() { 352 | SingleLinkedList stringSingleLinkedList = new SingleLinkedList<>(); 353 | stringSingleLinkedList.add("Привет"); 354 | stringSingleLinkedList.add("меня"); 355 | stringSingleLinkedList.add("зовут"); 356 | stringSingleLinkedList.add("Собака"); 357 | assertFalse(stringSingleLinkedList.remove("Привет!")); 358 | assertEquals(4, stringSingleLinkedList.size()); 359 | assertEquals("Привет", stringSingleLinkedList.get(0)); 360 | assertEquals("меня", stringSingleLinkedList.get(1)); 361 | assertEquals("зовут", stringSingleLinkedList.get(2)); 362 | assertEquals("Собака", stringSingleLinkedList.get(3)); 363 | } 364 | 365 | @Test 366 | void clear() { 367 | SingleLinkedList list = new SingleLinkedList<>(); 368 | list.add("Привет"); 369 | list.add("меня"); 370 | list.add("зовут"); 371 | list.add("Собака"); 372 | list.clear(); 373 | assertEquals(0, list.size()); 374 | } 375 | } 376 | /* 377 | * test{Method}_Should{Do}_When{Condition} 378 | * 379 | * */ --------------------------------------------------------------------------------