├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── pom.xml └── src ├── main └── java │ └── rogeriogentil │ └── data │ └── structures │ ├── chapter01 │ ├── Creativity.java │ ├── CreditCard.java │ ├── GameEntry.java │ └── Reinforcement.java │ ├── chapter03 │ ├── BiNode.java │ ├── CircularyLinkedList.java │ ├── DoublyLinkedList.java │ ├── InsertionSort.java │ ├── Node.java │ ├── SinglyLinkedList.java │ ├── StringToArray.java │ └── reinforcement │ │ ├── Exercise01.java │ │ ├── Exercise02.java │ │ ├── Exercise05.java │ │ ├── Exercise06.java │ │ └── PseudoRandom.java │ ├── chapter05 │ ├── DiskUsage.java │ ├── DrawnerBrazilianRuler.java │ ├── Factorial.java │ ├── RecursionBinarySearch.java │ ├── RecursionFibonacci.java │ ├── RecursionSumArrayElements.java │ └── reinforcement │ │ ├── Exercise01.java │ │ ├── Exercise05.java │ │ ├── Exercise07.java │ │ ├── Exercise08.java │ │ └── Exercise10.java │ ├── chapter06 │ ├── ArrayCircularQueue.java │ ├── ArrayStack.java │ ├── ArrayUtil.java │ ├── CircularQueue.java │ ├── Deque.java │ ├── DoublyLinkedList.java │ ├── LinkedQueue.java │ ├── LinkedStack.java │ ├── MatchUtil.java │ ├── Queue.java │ ├── Stack.java │ └── reinforcement │ │ ├── Exercise01.txt │ │ ├── Exercise02.txt │ │ ├── Exercise03.txt │ │ ├── Exercise04.java │ │ ├── Exercise05.java │ │ ├── Exercise07.txt │ │ ├── Exercise08.txt │ │ ├── Exercise09.txt │ │ ├── Exercise10.java │ │ └── Exercise12.txt │ ├── chapter07 │ ├── ArrayList.java │ ├── LinkedPositionalList.java │ ├── List.java │ ├── Position.java │ ├── PositionalList.java │ └── reinforcement │ │ ├── Exercise01.txt │ │ ├── Exercise02.java │ │ ├── Exercise03.java │ │ ├── Exercise05.java │ │ └── Exercise10.java │ ├── chapter08 │ ├── AbstractBinaryTree.java │ ├── AbstractTree.java │ ├── BinaryTree.java │ ├── LinkedBinaryTree.java │ ├── Tree.java │ ├── TreeUtil.java │ └── reinforcement │ │ ├── Exercise01.txt │ │ ├── Exercise05.java │ │ ├── Exercise07.txt │ │ ├── Exercise12.txt │ │ ├── Exercise18.txt │ │ ├── Exercise19.txt │ │ ├── Exercise20.txt │ │ ├── Exercise22.txt │ │ └── Exercise24.txt │ ├── chapter09 │ ├── AbstractPriorityQueue.java │ ├── AdaptablePriorityQueue.java │ ├── DefaultComparator.java │ ├── Entry.java │ ├── HeapAdaptablePriorityQueue.java │ ├── HeapPriorityQueue.java │ ├── PriorityQueue.java │ ├── PriorityQueueUtils.java │ ├── SortedPriorityQueue.java │ ├── StringLengthComparator.java │ ├── UnsortedProrityQueue.java │ └── reinforcement │ │ ├── Exercise02.txt │ │ ├── Exercise03.txt │ │ ├── Exercise07.txt │ │ ├── Exercise08.txt │ │ ├── Exercise17.txt │ │ └── Exercise19.txt │ ├── chapter10 │ ├── AbstractMap.java │ ├── AbstractSortedMap.java │ ├── Map.java │ ├── SortedMap.java │ └── UnsortedTableMap.java │ ├── chapter11 │ ├── AVLTreeMap.java │ ├── RBTreeMap.java │ ├── SplayTreeMap.java │ ├── TreeMap.java │ └── reinforcement │ │ ├── Exercise01.txt │ │ ├── Exercise02.txt │ │ ├── Exercise03.txt │ │ ├── Exercise04.txt │ │ ├── Exercise05.txt │ │ ├── Exercise08.txt │ │ ├── Exercise09.txt │ │ ├── Exercise14.txt │ │ ├── Exercise15.txt │ │ └── Exercise17.txt │ ├── chapter12 │ ├── MergeSort.java │ ├── QuickSort.java │ └── reinforcement │ │ ├── Exercise01.txt │ │ ├── Exercise02.txt │ │ ├── Exercise04.txt │ │ └── Exercise05.txt │ └── chapter14 │ ├── AdjacencyMapGraph.java │ ├── Edge.java │ ├── Graph.java │ ├── GraphTraversals.java │ ├── Vertex.java │ └── reinforcement │ ├── Exercise05.txt │ ├── Exercise06.txt │ ├── Exercise07.txt │ ├── Exercise08.txt │ ├── Exercise11.txt │ └── Exercise13.txt └── test └── java └── rogeriogentil └── data └── structures ├── chapter03 ├── ArraysTest.java ├── CircularyLinkedListTest.java ├── DoublyLinkedListTest.java ├── InsertionSortTest.java └── SinglyLinkedListTest.java ├── chapter05 ├── FactorialTest.java ├── RecursionBinarySearchTest.java └── RecursionFibonacciTest.java ├── chapter06 ├── ArrayCircularQueueTest.java ├── ArrayStackTest.java ├── ArrayUtilTest.java ├── MatchUtilTest.java └── reinforcement │ ├── Exercise04Test.java │ ├── Exercise05Test.java │ └── Exercise10Test.java ├── chapter07 ├── ArrayListTest.java └── reinforcement │ ├── Exercise02Test.java │ ├── Exercise03Test.java │ └── Exercise10Test.java ├── chapter08 ├── TreeUtilTest.java └── reinforcement │ └── Exercise05Test.java ├── chapter09 ├── StringLengthComparatorTest.java └── UnsortedProrityQueueTest.java └── chapter12 ├── MergeSortTest.java └── QuickSortTest.java /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | *.jar 15 | *.war 16 | *.ear 17 | *.zip 18 | *.tar.gz 19 | *.rar 20 | 21 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 22 | hs_err_pid* 23 | 24 | # Maven compiled files folder 25 | target/ 26 | 27 | # Netbeans IDE folders and files 28 | nb-configuration.xml 29 | nbactions.xml 30 | nbproject/ 31 | 32 | # Eclipse IDE files and folders 33 | .classpath 34 | .project 35 | .settings/ 36 | 37 | # IntelliJ IDEA files and folders 38 | .idea/ 39 | *.iml 40 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | notifications: 3 | email: 4 | - rogerio_gentil@yahoo.com.br 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # data-structures-and-algorithms 2 | Codes and resolutions of the exercises of Goodrich, Tamassia & Goldwasser's Data Structures & Algorithms in Java Sixth Edition Book (2014). 3 | 4 | ## Status 5 | [![Build Status](https://travis-ci.org/rogeriogentil/data-structures-and-algorithms.svg?branch=master)](https://travis-ci.org/rogeriogentil/data-structures-and-algorithms) 6 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | rogeriogentil 8 | data-structures-and-algorithms 9 | 1.0.0-SNAPSHOT 10 | jar 11 | 12 | Data Structures and Algorithms in Java 13 | Codes and resolutions of the exercises of Goorich, Tamassia And Godwasser's Data Structures and Algorithms in Java Sixth Edition Book 14 | 2017 15 | 16 | 17 | UTF-8 18 | 1.8 19 | 1.8 20 | 21 | 22 | 23 | 24 | junit 25 | junit 26 | 4.12 27 | test 28 | 29 | 30 | org.hamcrest 31 | hamcrest-core 32 | 33 | 34 | 35 | 36 | 37 | org.hamcrest 38 | hamcrest-library 39 | 1.3 40 | test 41 | 42 | 43 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter01/Creativity.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter01; 2 | 3 | /** 4 | * 5 | * @author rogerio 6 | */ 7 | public class Creativity { 8 | 9 | public static void main(String[] args) { 10 | Creativity creativity = new Creativity(); 11 | 12 | // C-1.14 13 | int[] integers = {0, 2, 4, 6, 8}; 14 | int[] reverse = creativity.reverse(integers); 15 | 16 | System.out.print("{"); 17 | for(Integer i : reverse) { 18 | System.out.print(i + ", "); 19 | } 20 | System.out.println("}"); 21 | 22 | // C-1.15 23 | int smallest = creativity.smallest(integers); 24 | System.out.println("Smallest = " + smallest); 25 | 26 | int smallest2 = creativity.smallest(new int[5]); 27 | System.out.println("Smallest = " + smallest2); 28 | 29 | int[] ints = {-3, -1, 0, 1, 3}; 30 | int smallest3 = creativity.smallest(ints); 31 | System.out.println("Smallest = " + smallest3); 32 | } 33 | 34 | /** 35 | * C-1.14 36 | */ 37 | public int[] reverse(int[] array) { 38 | int[] reverse = new int[array.length]; 39 | 40 | int j = 0; 41 | for (int i = array.length - 1; i > 0; i--) { 42 | reverse[j++] = array[i]; 43 | } 44 | 45 | return reverse; 46 | } 47 | 48 | /** 49 | * C-1.15 50 | */ 51 | public int smallest(int[] array) { 52 | int smallest = array[0]; 53 | 54 | for (int i = 1; i < array.length; i++) { 55 | if (array[i] < smallest) { 56 | smallest = array[i]; 57 | } 58 | } 59 | 60 | return smallest; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter01/CreditCard.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter01; 2 | 3 | /** 4 | * 5 | * @author rogerio 6 | */ 7 | public class CreditCard { 8 | 9 | private String customer; 10 | private String bank; 11 | private String account; 12 | private int limit; 13 | protected double balance; 14 | 15 | public CreditCard(String customer, String bank, String account, int limit, double balance) { 16 | this.customer = customer; 17 | this.bank = bank; 18 | this.account = account; 19 | this.limit = limit; 20 | this.balance = balance; 21 | } 22 | 23 | public CreditCard(String customer, String bank, String account, int limit) { 24 | this(customer, bank, account, limit, 0.0); 25 | } 26 | 27 | public String getCustomer() { 28 | return customer; 29 | } 30 | 31 | public String getBank() { 32 | return bank; 33 | } 34 | 35 | public String getAccount() { 36 | return account; 37 | } 38 | 39 | public int getLimit() { 40 | return limit; 41 | } 42 | 43 | public double getBalance() { 44 | return balance; 45 | } 46 | 47 | public boolean charge(double price) { 48 | if (price + balance > limit) 49 | return false; 50 | 51 | balance += price; 52 | return true; 53 | } 54 | 55 | public void makePayment(double amount) { 56 | // R-1.12 57 | if (amount < 0) return; 58 | balance -= amount; 59 | } 60 | 61 | // R-1.11 62 | public void updateLimit(int newLimit) { 63 | this.limit = newLimit; 64 | } 65 | 66 | public static void printSummary(CreditCard card) { 67 | System.out.println("-------------------------------------"); 68 | System.out.println("Customer = " + card.customer); 69 | System.out.println("Bank = " + card.bank); 70 | System.out.println("Account = " + card.account); 71 | System.out.println("Balance = " + card.balance); 72 | System.out.println("Limit = " + card.limit); 73 | System.out.println("-------------------------------------"); 74 | } 75 | 76 | public static void main(String[ ] args) { 77 | CreditCard[ ] wallet = new CreditCard[3]; 78 | wallet[0] = new CreditCard("John Bowman", "California Savings", "5391 0375 9387 5309", 5000); 79 | wallet[1] = new CreditCard("John Bowman", "California Federal", "3485 0399 3395 1954", 3500); 80 | wallet[2] = new CreditCard("John Bowman", "California Finance", "5391 0375 9387 5309", 2500, 300); 81 | 82 | for (int val = 1; val <= 16; val++) { 83 | wallet[0].charge(3*val); 84 | wallet[1].charge(3*val);//wallet[1].charge(2*val); 85 | wallet[2].charge(3*val);//wallet[2].charge(val); 86 | } 87 | 88 | for (CreditCard card : wallet) { 89 | CreditCard.printSummary(card); 90 | while (card.getBalance( ) > 200.0) { 91 | card.makePayment(200); 92 | System.out.println("New balance = " + card.getBalance()); 93 | } 94 | } 95 | 96 | // R-1.11 97 | for (int i = 0; i < wallet.length; i++) { 98 | System.out.println("Old limit on wallet[" + i + "] = " + wallet[i].limit); 99 | 100 | int newLimit = wallet[i].limit * 2; 101 | wallet[i].updateLimit(newLimit); 102 | 103 | System.out.println("New limit on wallet[" + i + "] = " + wallet[i].limit); 104 | } 105 | 106 | // R-1.12 107 | for (CreditCard card : wallet) { 108 | card.makePayment(-100); 109 | System.out.println("New balance = " + card.getBalance()); 110 | } 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter01/GameEntry.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter01; 2 | 3 | /** 4 | * 5 | * @author rogerio 6 | */ 7 | public class GameEntry implements Cloneable { 8 | 9 | public int score; 10 | 11 | public GameEntry(int score) { 12 | this.score = score; 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter01/Reinforcement.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter01; 2 | 3 | /** 4 | * 5 | * @author rogerio 6 | */ 7 | public class Reinforcement { 8 | 9 | public static void main(String[] args) { 10 | Reinforcement r = new Reinforcement(); 11 | 12 | // R-1.3 13 | System.out.println(r.isMultiple(2, 6)); 14 | System.out.println(r.isMultiple(3, 6)); 15 | System.out.println(r.isMultiple(4, 9)); 16 | 17 | // R-1.5 18 | System.out.println("R-1.5"); 19 | System.out.println(r.sumInts(3)); 20 | System.out.println(r.sumInts(5)); 21 | // System.out.println(r.sumInts(-1)); 22 | 23 | // R-1.6 24 | System.out.println("R-1.6"); 25 | System.out.println(r.sumOdds(3)); 26 | System.out.println(r.sumOdds(4)); 27 | System.out.println(r.sumOdds(5)); 28 | 29 | // R-1.7 30 | System.out.println("R-1.7"); 31 | System.out.println(r.sumSquaers(2)); 32 | System.out.println(r.sumSquaers(3)); 33 | 34 | // R-1.8 35 | System.out.println("R-1.8"); 36 | System.out.println(r.countVowels("")); 37 | System.out.println(r.countVowels("aeiou")); 38 | System.out.println(r.countVowels("Rogerio")); 39 | System.out.println(r.countVowels("PAULA")); 40 | 41 | } 42 | 43 | /** 44 | * R-1.3 45 | * 46 | * @param n 47 | * @param m 48 | * @return 49 | */ 50 | public boolean isMultiple(long n, long m) { 51 | return m % n == 0; 52 | } 53 | 54 | /** 55 | * R-1.4 - This method cannot use the multiplication, modulus, or division operators. 56 | */ 57 | public boolean isEven(int i) { 58 | return false; 59 | } 60 | 61 | /** 62 | * R-1.5 Write a short Java method that takes an integer n and returns the sum of all positive integers less than or 63 | * equal to n. 64 | */ 65 | public long sumInts(int n) { 66 | if (n < 0) { 67 | throw new RuntimeException("Não é possível somar números negativos."); 68 | } 69 | 70 | long sum = 0; 71 | for (int i = n; i > 0; --i) { 72 | sum += i; 73 | } 74 | 75 | return sum; 76 | } 77 | 78 | /** 79 | * R-1.6 Write a short Java method that takes an integer n and returns the sum of all the odd positive integers less 80 | * than or equal to n. 81 | */ 82 | public long sumOdds(int n) { 83 | if (n < 0) { 84 | throw new RuntimeException("Não é possível somar números negativos."); 85 | } 86 | 87 | long sum = 0; 88 | for (int i = n; i > 0; --i) { 89 | if (i % 2 == 1) { 90 | sum += i; 91 | } 92 | } 93 | 94 | return sum; 95 | } 96 | 97 | /** 98 | * R-1.7 Write a short Java method that takes an integer n and returns the sum of the squares of all positive 99 | * integers less than or equal to n. 100 | */ 101 | public long sumSquaers(int n) { 102 | if (n < 0) { 103 | throw new RuntimeException("Não é possível somar números negativos."); 104 | } 105 | 106 | long sum = 0; 107 | for (int i = n; i > 0; --i) { 108 | sum += i * i; 109 | } 110 | 111 | return sum; 112 | } 113 | 114 | /** 115 | * R-1.8 Write a short Java method that counts the number of vowels in a given character string. 116 | */ 117 | public int countVowels(String s) { 118 | int count = 0; 119 | String sl = s.toLowerCase(); 120 | 121 | for (int i = 0; i < s.length(); i++) { 122 | char c = sl.charAt(i); 123 | switch(c) { 124 | case 'a': count++; break; 125 | case 'e': count++; break; 126 | case 'i': count++; break; 127 | case 'o': count++; break; 128 | case 'u': count++; break; 129 | } 130 | } 131 | 132 | return count; 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter03/BiNode.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter03; 2 | 3 | /** 4 | * 5 | * @author rogerio 6 | * @param 7 | */ 8 | public class BiNode { 9 | 10 | private BiNode previous; 11 | private E element; 12 | private BiNode next; 13 | 14 | public BiNode() { 15 | } 16 | 17 | public BiNode(E element) { 18 | this.element = element; 19 | } 20 | 21 | public BiNode getPrevious() { 22 | return previous; 23 | } 24 | 25 | public void setPrevious(BiNode previous) { 26 | this.previous = previous; 27 | } 28 | 29 | public E getElement() { 30 | return element; 31 | } 32 | 33 | public void setElement(E element) { 34 | this.element = element; 35 | } 36 | 37 | public BiNode getNext() { 38 | return next; 39 | } 40 | 41 | public void setNext(BiNode next) { 42 | this.next = next; 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter03/CircularyLinkedList.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter03; 2 | 3 | /** 4 | * 5 | * @author rogerio 6 | * @param 7 | */ 8 | public class CircularyLinkedList { 9 | 10 | private int size; 11 | private Node tailNode; 12 | 13 | public int getSize() { 14 | return size; 15 | } 16 | 17 | public Node getHeadNode() { 18 | return tailNode.getNext(); 19 | } 20 | 21 | public Node getTailNode() { 22 | return tailNode; 23 | } 24 | 25 | public boolean isEmpty() { 26 | return size == 0; 27 | } 28 | 29 | public E first() { 30 | if (this.isEmpty()) 31 | return null; 32 | 33 | return getTailNode().getNext().getElement(); 34 | } 35 | 36 | public E last() { 37 | if (this.isEmpty()) 38 | return null; 39 | 40 | return getTailNode().getNext().getElement(); 41 | } 42 | 43 | public void addFirst(E element) { 44 | Node newest = new Node<>(element); 45 | 46 | if (isEmpty()) { 47 | tailNode = newest; 48 | } else { 49 | newest.setNext(tailNode.getNext()); 50 | } 51 | 52 | tailNode.setNext(newest); 53 | 54 | size++; 55 | } 56 | 57 | public void addLast(E element) { 58 | Node newest = new Node<>(element); 59 | 60 | if (this.isEmpty()) { 61 | tailNode = newest; 62 | tailNode.setNext(newest); 63 | newest.setNext(tailNode); 64 | } else { 65 | newest.setNext(tailNode.getNext()); 66 | tailNode.setNext(newest); 67 | tailNode = newest; 68 | } 69 | 70 | size++; 71 | } 72 | 73 | public void rotate() { 74 | if (!isEmpty()) { 75 | tailNode = tailNode.getNext(); 76 | } 77 | } 78 | } -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter03/DoublyLinkedList.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter03; 2 | 3 | /** 4 | * 5 | * @author rogerio 6 | * @param 7 | */ 8 | public class DoublyLinkedList { 9 | 10 | private int size; 11 | private BiNode header; 12 | private BiNode trailer; 13 | 14 | public DoublyLinkedList() { 15 | header = new BiNode<>(); 16 | trailer = new BiNode<>(); 17 | 18 | header.setNext(trailer); 19 | trailer.setPrevious(header); 20 | } 21 | 22 | public int getSize() { 23 | return size; 24 | } 25 | 26 | public BiNode getHeader() { 27 | return header; 28 | } 29 | 30 | public BiNode getTrailer() { 31 | return trailer; 32 | } 33 | 34 | public boolean isEmpty() { 35 | return this.size == 0; 36 | } 37 | 38 | public void addFirst(E element) { 39 | BiNode node = new BiNode<>(element); 40 | node.setPrevious(header); 41 | node.setNext(header.getNext()); 42 | 43 | header.getNext().setPrevious(node); 44 | header.setNext(node); 45 | 46 | size++; 47 | } 48 | 49 | public E first() { 50 | return this.header.getNext().getElement(); 51 | } 52 | 53 | public void addLast(E element) { 54 | BiNode node = new BiNode<>(element); 55 | node.setPrevious(trailer.getPrevious()); 56 | node.setNext(trailer); 57 | 58 | trailer.getPrevious().setNext(node); 59 | trailer.setPrevious(node); 60 | size++; 61 | } 62 | 63 | public E last() { 64 | return trailer.getPrevious().getElement(); 65 | } 66 | 67 | public void removeFirst() { 68 | if (isEmpty()) return; 69 | 70 | header.setNext(header.getNext().getNext()); 71 | header.getNext().getNext().setPrevious(header); 72 | size--; 73 | } 74 | 75 | public void removeLast() { 76 | if (isEmpty()) return; 77 | 78 | trailer.setPrevious(trailer.getPrevious().getPrevious()); 79 | trailer.getPrevious().getPrevious().setNext(trailer); 80 | size--; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter03/InsertionSort.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter03; 2 | 3 | /** 4 | * 5 | * @author rogerio 6 | */ 7 | public class InsertionSort { 8 | 9 | public Integer[] sort(Integer[] array) { 10 | 11 | for (int i = 1; i < array.length; i++) { 12 | int valorAtual = array[i]; 13 | int j = i; 14 | 15 | while (j > 0 && valorAtual < array[j - 1]) { 16 | array[j] = array[j -1]; 17 | j--; 18 | } 19 | 20 | array[j] = valorAtual; 21 | } 22 | 23 | return array; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter03/Node.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter03; 2 | 3 | /** 4 | * 5 | * @author rogerio 6 | */ 7 | public class Node { 8 | 9 | private E element; 10 | private Node next; 11 | 12 | public Node() { 13 | } 14 | 15 | public Node(E element) { 16 | this.element = element; 17 | } 18 | 19 | public E getElement() { 20 | return element; 21 | } 22 | 23 | public void setElement(E element) { 24 | this.element = element; 25 | } 26 | 27 | public Node getNext() { 28 | return next; 29 | } 30 | 31 | public void setNext(Node next) { 32 | this.next = next; 33 | } 34 | } 35 | 36 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter03/SinglyLinkedList.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter03; 2 | 3 | /** 4 | * 5 | * @author rogerio 6 | */ 7 | public class SinglyLinkedList { 8 | 9 | private int size; 10 | private Node headNode; 11 | private Node tailNode; 12 | 13 | public Node getHead() { 14 | return headNode; 15 | } 16 | 17 | public Node getTail() { 18 | return tailNode; 19 | } 20 | 21 | public int getSize() { 22 | return size; 23 | } 24 | 25 | public void addFirst(E element) { 26 | Node newest = new Node(element); 27 | newest.setNext(headNode); 28 | headNode = newest; 29 | 30 | if (this.isEmpty()) { 31 | tailNode = headNode; 32 | } 33 | 34 | size++; 35 | } 36 | 37 | public void addLast(E element) { 38 | Node newest = new Node(element); 39 | 40 | if (this.isEmpty()) { 41 | headNode = newest; 42 | tailNode = headNode; 43 | } else { 44 | tailNode.setNext(newest); 45 | tailNode = newest; 46 | } 47 | 48 | size++; 49 | } 50 | 51 | public E removeFist() { 52 | if (this.isEmpty()) { 53 | return null; 54 | } 55 | 56 | E element = headNode.getElement(); 57 | headNode = headNode.getNext(); 58 | // headNode.setNext(null); 59 | size--; 60 | 61 | return element; 62 | } 63 | 64 | public boolean isEmpty() { 65 | return this.size == 0; 66 | } 67 | 68 | public E first() { 69 | return headNode.getElement(); 70 | } 71 | } 72 | 73 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter03/StringToArray.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter03; 2 | 3 | /** 4 | * 5 | * @author rogerio 6 | */ 7 | public class StringToArray { 8 | 9 | public static void main(String[] args) { 10 | String bird = "black bird"; 11 | char[] characters = bird.toCharArray(); 12 | 13 | for (int i = 0; i < characters.length; i++) { 14 | System.out.println("c[" + i + "]: " + characters[i]); 15 | } 16 | 17 | String newBird = new String(characters); 18 | System.out.println(newBird); 19 | 20 | char t = 'T'; 21 | System.out.println(t); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter03/reinforcement/Exercise01.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter03.reinforcement; 2 | 3 | /** 4 | * Give the next five pseudorandom numbers generated by the process described on 5 | * page 113: 6 | * 7 | * next = (a ∗ cur + b) % n; 8 | * 9 | * , with a = 12, b = 5, and n = 100, and 92 as the seed for cur. 10 | * 11 | * @author Rogerio J. Gentil 12 | */ 13 | public class Exercise01 { 14 | 15 | public static void main(String[] args) { 16 | int seed = 92; 17 | 18 | PseudoRandom pseudoRandom = new PseudoRandom(seed); 19 | double first = pseudoRandom.next(); 20 | double second = pseudoRandom.next(); 21 | double third = pseudoRandom.next(); 22 | double fourth = pseudoRandom.next(); 23 | double fifth = pseudoRandom.next(); 24 | 25 | System.out.println("1º: " + first); 26 | System.out.println("2º: " + second); 27 | System.out.println("3º: " + third); 28 | System.out.println("4º: " + fourth); 29 | System.out.println("5º: " + fifth); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter03/reinforcement/Exercise02.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter03.reinforcement; 2 | 3 | import java.util.Date; 4 | import java.util.Random; 5 | 6 | /** 7 | * Write a Java method that repeatedly selects and removes a random entry from 8 | * an array until the array holds no more entries. 9 | * 10 | * @author Rogerio J. Gentil 11 | */ 12 | public class Exercise02 { 13 | 14 | private static int capacidade = 20; 15 | private static Double[] doubleArray = new Double[capacidade]; 16 | 17 | public static void main(String[] args) { 18 | PseudoRandom pseudoRandom = new PseudoRandom(new Date().getTime()); 19 | 20 | for (int i = 0; i < capacidade; i++) { 21 | doubleArray[i] = pseudoRandom.next(); 22 | System.out.println(i + ". " + doubleArray[i]); 23 | } 24 | 25 | while (doubleArray.length > 0) { // Testar todas as entradas == null ou total de elemento == 0? 26 | remove(); 27 | } 28 | } 29 | 30 | public static void remove() { 31 | Random random = new Random(); 32 | int index = random.nextInt(capacidade); 33 | 34 | if (doubleArray[index] == null) { 35 | return; 36 | } 37 | 38 | double valor = doubleArray[index]; 39 | doubleArray[index] = null; 40 | 41 | System.out.println("removeu no index " + index + ": " + valor); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter03/reinforcement/Exercise05.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter03.reinforcement; 2 | 3 | /** 4 | * Ver método remofirst(); 5 | * 6 | * @author rogerio 7 | */ 8 | public class Exercise05 { 9 | 10 | private class SinglyLinkedList { 11 | 12 | private int size; 13 | private Node headNode; 14 | private Node tailNode; 15 | 16 | public Node getHead() { 17 | return headNode; 18 | } 19 | 20 | public Node getTail() { 21 | return tailNode; 22 | } 23 | 24 | public int getSize() { 25 | return size; 26 | } 27 | 28 | public void addFirst(E element) { 29 | Node newest = new Node(element); 30 | newest.setNext(headNode); 31 | headNode = newest; 32 | 33 | if (this.isEmpty()) { 34 | tailNode = headNode; 35 | } 36 | 37 | size++; 38 | } 39 | 40 | public void addLast(E element) { 41 | Node newest = new Node(element); 42 | 43 | if (this.isEmpty()) { 44 | headNode = newest; 45 | tailNode = headNode; 46 | } else { 47 | tailNode.setNext(newest); 48 | tailNode = newest; 49 | } 50 | 51 | size++; 52 | } 53 | 54 | public E removeFirst() { // removes and returns the first element 55 | if (isEmpty()) { 56 | return null; // nothing to remove 57 | } 58 | E answer = headNode.getElement(); 59 | headNode = headNode.getNext(); // will become null if list had only one node 60 | size--; 61 | 62 | /* 63 | What are the consequences if we were to remove those two lines from the 64 | code? Explain why the class would or would not work with such a modification. 65 | 66 | R: Caso essas duas próximas linhas fosse removidas, quando se removesse 67 | o primeiro elemento de um lista com apenas 1 elemento o ponteiro ponteiro 68 | do 'tail' ainda permaneceria ligado ao objeto do elemento a ser removido. 69 | Logo, o GC não recolheria o objeto apontado para 'tail'. 70 | */ 71 | if (size == 0) { 72 | tailNode = null; // special case as list is now empty 73 | } 74 | return answer; 75 | } 76 | 77 | public boolean isEmpty() { 78 | return this.size == 0; 79 | } 80 | } 81 | 82 | private class Node { 83 | 84 | private E element; 85 | private Node next; 86 | 87 | public Node() { 88 | } 89 | 90 | public Node(E element) { 91 | this.element = element; 92 | } 93 | 94 | public E getElement() { 95 | return element; 96 | } 97 | 98 | public void setElement(E element) { 99 | this.element = element; 100 | } 101 | 102 | public Node getNext() { 103 | return next; 104 | } 105 | 106 | public void setNext(Node next) { 107 | this.next = next; 108 | } 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter03/reinforcement/Exercise06.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter03.reinforcement; 2 | 3 | /** 4 | * @author rogerio 5 | */ 6 | public class Exercise06 { 7 | 8 | private class SinglyLinkedList { 9 | 10 | private int size; 11 | private Node headNode; 12 | private Node tailNode; 13 | 14 | public Node getHead() { 15 | return headNode; 16 | } 17 | 18 | public Node getTail() { 19 | return tailNode; 20 | } 21 | 22 | public int getSize() { 23 | return size; 24 | } 25 | 26 | public void addFirst(E element) { 27 | Node newest = new Node(element); 28 | newest.setNext(headNode); 29 | headNode = newest; 30 | 31 | if (this.isEmpty()) { 32 | tailNode = headNode; 33 | } 34 | 35 | size++; 36 | } 37 | 38 | public void addLast(E element) { 39 | Node newest = new Node(element); 40 | 41 | if (this.isEmpty()) { 42 | headNode = newest; 43 | tailNode = headNode; 44 | } else { 45 | tailNode.setNext(newest); 46 | tailNode = newest; 47 | } 48 | 49 | size++; 50 | } 51 | 52 | public void removeFist() { 53 | if (this.isEmpty()) { 54 | return; 55 | } 56 | headNode = headNode.getNext(); 57 | headNode.setNext(null); 58 | size--; 59 | } 60 | 61 | public E removeFirst() { // removes and returns the first element 62 | if (isEmpty()) { 63 | return null; // nothing to remove 64 | } 65 | E answer = headNode.getElement(); 66 | headNode = headNode.getNext(); // will become null if list had only one node 67 | size--; 68 | 69 | if (size == 0) { 70 | tailNode = null; // special case as list is now empty 71 | } 72 | return answer; 73 | } 74 | 75 | public boolean isEmpty() { 76 | return this.size == 0; 77 | } 78 | } 79 | 80 | private class Node { 81 | 82 | private E element; 83 | private Node next; 84 | 85 | public Node() { 86 | } 87 | 88 | public Node(E element) { 89 | this.element = element; 90 | } 91 | 92 | public E getElement() { 93 | return element; 94 | } 95 | 96 | public void setElement(E element) { 97 | this.element = element; 98 | } 99 | 100 | public Node getNext() { 101 | return next; 102 | } 103 | 104 | public void setNext(Node next) { 105 | this.next = next; 106 | } 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter03/reinforcement/PseudoRandom.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter03.reinforcement; 2 | 3 | /** 4 | * 5 | * @author Rogerio J. Gentil 6 | */ 7 | public class PseudoRandom { 8 | 9 | private double current; 10 | private final int a = 12; 11 | private final int b = 5; 12 | private final int n = 100; 13 | 14 | public PseudoRandom(long seed) { 15 | this.current = seed; 16 | } 17 | 18 | public double next() { 19 | double next = (a * current + b) % n; 20 | this.current = next; 21 | return next; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter05/DiskUsage.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter05; 2 | 3 | import java.io.File; 4 | 5 | /** 6 | * 7 | * @author rogerio 8 | */ 9 | public class DiskUsage { 10 | 11 | public static long analysis(File path) { 12 | // System.out.println("File or directory: " + path.getName()); 13 | 14 | long total = path.length(); 15 | 16 | if (path.isDirectory()) { 17 | for (File file : path.listFiles()) { 18 | total += analysis(file); 19 | } 20 | } 21 | 22 | System.out.println(total + "\t" + path); 23 | return total; 24 | } 25 | 26 | public static void main(String[] args) { 27 | String path = "/home/rogerio/tmp"; 28 | File file = new File(path); 29 | 30 | System.out.println("Disk usage in " + path + ": " + analysis(file) + " bytes"); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter05/DrawnerBrazilianRuler.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter05; 2 | 3 | /** 4 | * 5 | * @author rogerio 6 | */ 7 | public class DrawnerBrazilianRuler { 8 | 9 | public static void drawRuler(int nroCentimetros, int majorLenth) { 10 | drawLine(majorLenth, 0); 11 | for (int j = 1; j <= nroCentimetros; j++) { 12 | drawInterval(majorLenth - 1); 13 | drawLine(majorLenth, j); 14 | } 15 | } 16 | 17 | public static void drawInterval(int centralLength) { 18 | if (centralLength >= 1) { 19 | drawInterval(centralLength - 1); 20 | drawLine(centralLength); 21 | drawInterval(centralLength - 1); 22 | } 23 | } 24 | 25 | public static void drawLine(int tickLength) { 26 | drawLine(tickLength, - 1); 27 | } 28 | 29 | public static void drawLine(int tickLength, int tickLabel) { 30 | for (int j = 0; j < tickLength; j++) { 31 | System.out.print("-"); 32 | } 33 | 34 | if (tickLabel >= 0) { 35 | System.out.print(" " + tickLabel); 36 | } 37 | 38 | System.out.print("\n"); 39 | } 40 | 41 | public static void main(String[] args) { 42 | DrawnerBrazilianRuler.drawRuler(5, 3); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter05/Factorial.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter05; 2 | 3 | /** 4 | * 5 | * @author rogerio 6 | */ 7 | public class Factorial { 8 | 9 | public static long factorial(int n) { 10 | if (n <= 0) 11 | return 1; 12 | 13 | return n * factorial(n - 1); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter05/RecursionBinarySearch.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter05; 2 | 3 | /** 4 | * 5 | * @author rogerio 6 | */ 7 | public class RecursionBinarySearch { 8 | 9 | public static int search(int n, int[] array, int indexLowest, int indexHighest) { 10 | if (indexLowest > indexHighest) { 11 | return -1; 12 | } 13 | 14 | int middle = (indexHighest + indexLowest) / 2; 15 | int number = array[middle]; 16 | 17 | if (n == number) { 18 | return middle; 19 | } 20 | 21 | if (n < number) { 22 | return search(n, array, indexLowest, middle - 1); 23 | } else { 24 | return search(n, array, middle + 1, indexHighest); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter05/RecursionFibonacci.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter05; 2 | 3 | /** 4 | * 5 | * @author rogerio 6 | */ 7 | public class RecursionFibonacci { 8 | 9 | public static int get(int thElement) { 10 | if (thElement <= 1) { 11 | return 1; 12 | } else { 13 | return get(thElement - 1) + get(thElement - 2); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter05/RecursionSumArrayElements.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter05; 2 | 3 | /** 4 | * 5 | * @author rogerio 6 | */ 7 | public class RecursionSumArrayElements { 8 | 9 | public static int sum(int[] array, int index) { 10 | int total = 0; 11 | 12 | if (array.length == 0 || index == array.length - 1) { 13 | return total; 14 | } 15 | 16 | return total + sum(array, index + 1); 17 | } 18 | 19 | public static void main(String[] args) { 20 | int[] array = {2, 1, 3, 5}; 21 | int total = sum(array, 0); 22 | System.out.println("Total: " + total); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter05/reinforcement/Exercise01.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter05.reinforcement; 2 | 3 | /** 4 | * Describe a recursive algorithm for finding the maximum element in an array, A, of n elements. 5 | * What is your running time and space usage? 6 | * 7 | * @author rogerio 8 | */ 9 | public class Exercise01 { 10 | 11 | public int maximumElement(int[] A, int index) { 12 | if (A.length == 1) { 13 | return A[0]; 14 | } 15 | 16 | if (A[index] > A[index + 1]) { 17 | return A[index]; 18 | } 19 | 20 | return maximumElement(A, index + 1); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter05/reinforcement/Exercise05.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter05.reinforcement; 2 | 3 | /** 4 | * 5 | * @author rogerio 6 | */ 7 | public class Exercise05 { 8 | 9 | public static int[] reverseArray(int[] array, int beginIndex, int endIndex) { 10 | if (beginIndex > endIndex) { 11 | return array; 12 | } 13 | 14 | int aux = array[beginIndex]; 15 | array[beginIndex] = array[endIndex]; 16 | array[endIndex] = aux; 17 | 18 | return reverseArray(array, beginIndex + 1, endIndex - 1); 19 | } 20 | 21 | public static void main(String[] args) { 22 | int[] data = {4, 3, 6, 2, 6}; 23 | int[] dataReverse = reverseArray(data, 0, 4); 24 | 25 | for (int i = 0; i < dataReverse.length; i++) { 26 | System.out.print(dataReverse[i] + " "); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter05/reinforcement/Exercise07.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter05.reinforcement; 2 | 3 | /** 4 | * 5 | * @author rogerio 6 | */ 7 | public class Exercise07 { 8 | 9 | /** 10 | * Somatória 1/k, k = 1 até n 11 | * 12 | * ex: 1 + 1/2 + 1/3 + 1/4 + ... 13 | * 14 | * @return 15 | */ 16 | public static double getNthHarmonicNumber(int nth) { 17 | if (nth < 1) { 18 | throw new IllegalArgumentException("Parâmetro não pode ser menor que 1"); 19 | } 20 | 21 | if (nth == 1) 22 | return 1; 23 | 24 | return (double) 1 / nth + getNthHarmonicNumber(nth - 1); 25 | } 26 | 27 | public static void main(String[] args) { 28 | double n = getNthHarmonicNumber(2); 29 | System.out.println("n = " + n); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter05/reinforcement/Exercise08.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter05.reinforcement; 2 | 3 | /** 4 | * 5 | * @author rogerio 6 | */ 7 | public class Exercise08 { 8 | 9 | public static int toInt(String s) { 10 | char[] array = s.toCharArray(); 11 | 12 | return 10498; 13 | } 14 | 15 | public static void main(String[] args) { 16 | String numero = "010498"; 17 | Integer n = toInt(numero); 18 | System.out.println("n é inteiro? " + (n instanceof Integer)); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter05/reinforcement/Exercise10.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter05.reinforcement; 2 | 3 | /** 4 | * Describe a way to use recursion to compute the sum of all the elements in an n × n (two-dimensional) array of integers. 5 | * 6 | * @author rogerio 7 | */ 8 | public class Exercise10 { 9 | 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter06/ArrayCircularQueue.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter06; 2 | 3 | /** 4 | * 5 | * @author rogerio 6 | */ 7 | public class ArrayCircularQueue implements Queue { 8 | 9 | private static final int CAPACITY = 1000; 10 | private int front; 11 | private int storedSize; 12 | private E[] array; 13 | 14 | public ArrayCircularQueue() { 15 | this(CAPACITY); 16 | } 17 | 18 | public ArrayCircularQueue(final int capacity) { 19 | array = (E[]) new Object[capacity]; 20 | } 21 | 22 | @Override 23 | public void enqueue(E element) { 24 | if (this.storedSize == this.array.length) { 25 | throw new IllegalStateException("Queue is full!"); 26 | } 27 | 28 | int avail = (this.front + this.storedSize) % array.length; 29 | array[avail] = element; 30 | this.storedSize++; 31 | } 32 | 33 | @Override 34 | public E dequeue() { 35 | if (isEmpty()) { 36 | return null; 37 | } 38 | 39 | E element = first(); 40 | array[front] = null; 41 | this.front = (this.front + 1) % array.length; 42 | this.storedSize--; 43 | return element; 44 | } 45 | 46 | @Override 47 | public int size() { 48 | return this.storedSize; 49 | } 50 | 51 | @Override 52 | public boolean isEmpty() { 53 | return this.storedSize == 0; 54 | } 55 | 56 | @Override 57 | public E first() { 58 | if (isEmpty()) { 59 | return null; 60 | } 61 | 62 | return array[front]; 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter06/ArrayStack.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter06; 2 | 3 | /** 4 | * 5 | * @author rogerio 6 | */ 7 | public class ArrayStack implements Stack { 8 | 9 | private static final int CAPACITY = 1000; 10 | private int top = -1; 11 | private E[] array; 12 | 13 | public ArrayStack() { 14 | this(CAPACITY); 15 | } 16 | 17 | public ArrayStack(final int capacity) { 18 | this.array = (E[]) new Object[capacity]; // safe cast; compiler may give warning 19 | } 20 | 21 | @Override 22 | public void push(E e) { 23 | if (array.length == size()) { 24 | throw new IllegalStateException("Stack is full"); 25 | } 26 | 27 | top++; 28 | array[top] = e; 29 | } 30 | 31 | @Override 32 | public E pop() { 33 | if (this.isEmpty()) { 34 | return null; 35 | } 36 | 37 | E e = array[top]; 38 | array[top] = null; 39 | top--; 40 | return e; 41 | } 42 | 43 | @Override 44 | public E top() { 45 | if (this.isEmpty()) { 46 | return null; 47 | } 48 | 49 | return array[top]; 50 | } 51 | 52 | @Override 53 | public int size() { 54 | return this.top + 1; 55 | } 56 | 57 | @Override 58 | public boolean isEmpty() { 59 | return this.top == -1; 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter06/ArrayUtil.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter06; 2 | 3 | /** 4 | * 5 | * @author Rogerio J. Gentil 6 | */ 7 | public class ArrayUtil { 8 | 9 | private ArrayUtil() {} 10 | 11 | public static void reverse(E[] array) { 12 | Stack stack = new ArrayStack<>(array.length); 13 | 14 | for (int i = 0; i < array.length; i++) { 15 | stack.push(array[i]); 16 | } 17 | 18 | for (int i = 0; i < array.length; i++) { 19 | array[i] = stack.pop(); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter06/CircularQueue.java: -------------------------------------------------------------------------------- 1 | 2 | package rogeriogentil.data.structures.chapter06; 3 | 4 | /** 5 | * 6 | * @author Rogerio J. Gentil 7 | */ 8 | public interface CircularQueue extends Queue { 9 | 10 | /** 11 | * Rotates the front element of the queue to the back of the queue. 12 | * This does nothing if the queue is empty. 13 | */ 14 | void rotate( ); 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter06/Deque.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter06; 2 | 3 | /** 4 | * 5 | * @author Rogerio J. Gentil 6 | * @param 7 | */ 8 | public interface Deque { 9 | 10 | /** 11 | * Inserts an element at the front of the deque. 12 | * @param element 13 | */ 14 | void addFirst(E element); 15 | 16 | /** 17 | * Inserts an element at the back of the deque. 18 | * @param element 19 | */ 20 | void addLast(E element); 21 | 22 | /** 23 | * Removes and returns the first element of the deque (null if empty). 24 | * @return 25 | */ 26 | E removeFirst(); 27 | 28 | /** 29 | * Removes and returns the last element of the deque (null if empty). 30 | * @return 31 | */ 32 | E removeLast(); 33 | 34 | /** 35 | * Returns, but does not remove, the first element of the deque (null if empty). 36 | * @return 37 | */ 38 | E first(); 39 | 40 | /** 41 | * Returns, but does not remove, the last element of the deque (null if empty). 42 | * @return 43 | */ 44 | E last(); 45 | 46 | /** 47 | * Returns the number of elements in the deque. 48 | * @return 49 | */ 50 | int size(); 51 | 52 | /** 53 | * Tests whether the deque is empty. 54 | * @return {@code true} or {@code false} 55 | */ 56 | boolean isEmpty(); 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter06/DoublyLinkedList.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter06; 2 | 3 | import rogeriogentil.data.structures.chapter03.*; 4 | 5 | /** 6 | * Copied class of the chapter 3. 7 | * 8 | * @author rogerio 9 | * @param 10 | */ 11 | public class DoublyLinkedList implements Deque { 12 | 13 | private int size; 14 | private BiNode header; 15 | private BiNode trailer; 16 | 17 | public DoublyLinkedList() { 18 | header = new BiNode<>(); 19 | trailer = new BiNode<>(); 20 | 21 | header.setNext(trailer); 22 | trailer.setPrevious(header); 23 | } 24 | 25 | public BiNode getHeader() { 26 | return header; 27 | } 28 | 29 | public BiNode getTrailer() { 30 | return trailer; 31 | } 32 | 33 | @Override 34 | public boolean isEmpty() { 35 | return this.size == 0; 36 | } 37 | 38 | @Override 39 | public void addFirst(E element) { 40 | BiNode node = new BiNode<>(element); 41 | node.setPrevious(header); 42 | node.setNext(header.getNext()); 43 | 44 | header.getNext().setPrevious(node); 45 | header.setNext(node); 46 | 47 | size++; 48 | } 49 | 50 | @Override 51 | public E first() { 52 | return this.header.getNext().getElement(); 53 | } 54 | 55 | @Override 56 | public void addLast(E element) { 57 | BiNode node = new BiNode<>(element); 58 | node.setPrevious(trailer.getPrevious()); 59 | node.setNext(trailer); 60 | 61 | trailer.getPrevious().setNext(node); 62 | trailer.setPrevious(node); 63 | size++; 64 | } 65 | 66 | @Override 67 | public E last() { 68 | return trailer.getPrevious().getElement(); 69 | } 70 | 71 | @Override 72 | public E removeFirst() { 73 | if (isEmpty()) { 74 | return null; 75 | } 76 | 77 | E element = header.getNext().getElement(); 78 | header.setNext(header.getNext().getNext()); 79 | header.getNext().getNext().setPrevious(header); 80 | size--; 81 | return element; 82 | } 83 | 84 | @Override 85 | public E removeLast() { 86 | if (isEmpty()) { 87 | return null; 88 | } 89 | 90 | E element = trailer.getPrevious().getElement(); 91 | trailer.setPrevious(trailer.getPrevious().getPrevious()); 92 | trailer.getPrevious().getPrevious().setNext(trailer); 93 | size--; 94 | return element; 95 | } 96 | 97 | @Override 98 | public int size() { 99 | return size; 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter06/LinkedQueue.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter06; 2 | 3 | import rogeriogentil.data.structures.chapter03.SinglyLinkedList; 4 | import rogeriogentil.data.structures.chapter06.Queue; 5 | 6 | /** 7 | * 8 | * @author rogerio 9 | */ 10 | public class LinkedQueue implements Queue { 11 | 12 | private SinglyLinkedList list = new SinglyLinkedList<>(); 13 | 14 | @Override 15 | public void enqueue(E element) { 16 | list.addLast(element); 17 | } 18 | 19 | @Override 20 | public E dequeue() { 21 | return list.removeFist(); 22 | } 23 | 24 | @Override 25 | public E first() { 26 | return list.first(); 27 | } 28 | 29 | @Override 30 | public int size() { 31 | return list.getSize(); 32 | } 33 | 34 | @Override 35 | public boolean isEmpty() { 36 | return list.isEmpty(); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter06/LinkedStack.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter06; 2 | 3 | import rogeriogentil.data.structures.chapter03.SinglyLinkedList; 4 | 5 | /** 6 | * 7 | * @author Rogerio J. Gentil 8 | */ 9 | public class LinkedStack implements Stack { 10 | 11 | private SinglyLinkedList list = new SinglyLinkedList<>(); 12 | 13 | @Override 14 | public void push(E e) { 15 | list.addFirst(e); 16 | } 17 | 18 | @Override 19 | public E pop() { 20 | return list.removeFist(); 21 | } 22 | 23 | @Override 24 | public E top() { 25 | return list.first(); 26 | } 27 | 28 | @Override 29 | public int size() { 30 | return list.getSize(); 31 | } 32 | 33 | @Override 34 | public boolean isEmpty() { 35 | return list.isEmpty(); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter06/MatchUtil.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter06; 2 | 3 | /** 4 | * 5 | * @author rogerio 6 | */ 7 | public class MatchUtil { 8 | 9 | public static boolean isMatched(String expression) { 10 | final String opening = "{[("; 11 | final String closing = "}])"; 12 | 13 | Stack buffer = new LinkedStack<>(); 14 | 15 | for (char c : expression.toCharArray()) { 16 | if (opening.indexOf(c) != -1) { 17 | buffer.push(c); 18 | } else if (closing.indexOf(c) != -1) { 19 | if (buffer.isEmpty()) { 20 | return false; 21 | } 22 | 23 | if (closing.indexOf(c) != opening.indexOf(buffer.pop())) { 24 | return false; 25 | } 26 | } 27 | } 28 | 29 | return buffer.isEmpty(); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter06/Queue.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter06; 2 | 3 | /** 4 | * 5 | * @author rogerio 6 | */ 7 | public interface Queue { 8 | 9 | /** 10 | * Adds element e to the back of queue. 11 | * @param e 12 | */ 13 | void enqueue(E element); 14 | 15 | /** 16 | * Removes and returns the first element from the queue (or null if the queue is empty). 17 | * @return E 18 | */ 19 | E dequeue(); 20 | 21 | /** 22 | * Returns the first element of the queue, without removing it (or null if the queue is empty). 23 | * @return The first element of the queue 24 | */ 25 | E first(); 26 | 27 | /** 28 | * Returns the number of elements in the queue. 29 | * @return 30 | */ 31 | int size(); 32 | 33 | /** 34 | * Returns a boolean indicating whether the queue is empty. 35 | * @return {@code true} or {@code false} 36 | */ 37 | boolean isEmpty(); 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter06/Stack.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter06; 2 | 3 | /** 4 | * 5 | * @author rogerio 6 | */ 7 | public interface Stack { 8 | 9 | /** 10 | * Adds element e to the top of the stack. 11 | * 12 | * @param e E 13 | */ 14 | void push(E e); 15 | 16 | /** 17 | * Removes and returns the top element from the stack (or null if the stack is empty). 18 | * 19 | * @return E 20 | */ 21 | E pop(); 22 | 23 | /** 24 | * Returns the top element of the stack, without removing it (or null if the stack is empty). 25 | * 26 | * @return 27 | */ 28 | E top(); 29 | 30 | /** 31 | * Returns the number of elements in the stack. 32 | * 33 | * @return Size of stack 34 | */ 35 | int size(); 36 | 37 | /** 38 | * Returns a boolean indicating whether the stack is empty. 39 | * 40 | * @return {@code true} or {@code false} 41 | */ 42 | boolean isEmpty(); 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter06/reinforcement/Exercise01.txt: -------------------------------------------------------------------------------- 1 | R-6.1 Suppose an initially empty stack S has performed a total of 25 push operations, 12 top operations, and 10 pop 2 | operations, 3 of which returned null to indicate an empty stack. What is the current size of S? 3 | 4 | Answer (pt-BR): 5 | -------------- 6 | 7 | Se foram realizadas 25 chamadas para o método push(e) - adiciona um elemento a pilha, 8 | 12 chamadas para top() - obtém o elemento apenas sem removê-lo, 9 | 10 chamadas para pop() - obtém o elemento no topo da pilha e remove-o - 10 | sendo que 3 chamadas para pop() retornaram 'null' - indicando que a pilha estava vazia, 11 | logo essas 3 chamadas que retornaram 'null' foram realizadas antes das chamadas para o método 'push(e)'. 12 | Portanto, conclui-se que o tamanho atual da pilha é 18 => 25 - (10 - 3). 13 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter06/reinforcement/Exercise02.txt: -------------------------------------------------------------------------------- 1 | R-6.2 Had the stack of the previous problem been an instance of the ArrayStack class, from Code Fragment 6.2, what 2 | would be the final value of the instance variable t? 3 | 4 | Answer (pt-BR) 5 | -------------- 6 | 7 | Tendo a situação exercício anterior e usando levando em conta que foi usada uma instância da classe 8 | ArrayStack, o valor final da variável de instância 't' seria 14. 9 | 10 | inicial: t = -1 11 | final: size() = 15 12 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter06/reinforcement/Exercise03.txt: -------------------------------------------------------------------------------- 1 | R-6.3 What values are returned during the following series of stack operations, if executed upon an initially empty 2 | stack? push(5), push(3), pop(), push(2), push(8), pop(), pop(), push(9), push(1), pop(), push(7), push(6), pop(), 3 | pop(), push(4), pop(), pop(). 4 | 5 | Answer (pt-BR) 6 | -------------- 7 | 8 | Para uma pilha inicialmente vazia, são retornados os seguintes valores: 9 | 10 | Performed Returned Actually 11 | --------- -------- -------- 12 | push(5) - (5) 13 | push(3) - (5, 3) 14 | pop() 3 (5) 15 | push(2) - (5, 2) 16 | push(8) - (5, 2, 8) 17 | pop() 8 (5, 2) 18 | pop() 2 (5) 19 | push(9) - (5, 9) 20 | push(1) - (5, 9, 1) 21 | pop() 1 (5, 9) 22 | push(7) - (5, 9, 7) 23 | push(6) - (5, 9, 7, 6) 24 | pop() 6 (5, 9, 7) 25 | pop() 7 (5, 9) 26 | push(4) - (5, 9, 4) 27 | pop() 4 (5, 9) 28 | pop() 9 (5) 29 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter06/reinforcement/Exercise04.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter06.reinforcement; 2 | 3 | import rogeriogentil.data.structures.chapter06.Stack; 4 | 5 | /** 6 | * R-6.4 Implement a method with signature transfer(S, T ) that transfers all elements from stack S onto stack T , so 7 | * that the element that starts at the top of S is the first to be inserted onto T , and the element at the bottom of 8 | * S ends up at the top of T. 9 | * 10 | * @author Rogerio J. Gentil 11 | */ 12 | public class Exercise04 { 13 | 14 | public static void transfer(Stack s, Stack t) { 15 | if (s.isEmpty()) { 16 | throw new IllegalStateException("Stack S is empty!"); 17 | } 18 | 19 | while (s.top() != null) { 20 | t.push(s.pop()); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter06/reinforcement/Exercise05.java: -------------------------------------------------------------------------------- 1 | 2 | package rogeriogentil.data.structures.chapter06.reinforcement; 3 | 4 | import rogeriogentil.data.structures.chapter06.Stack; 5 | 6 | /** 7 | * R-6.5 Give a recursive method for removing all the elements from a stack. 8 | * 9 | * @author Rogerio J. Gentil 10 | * @param 11 | */ 12 | public class Exercise05 { 13 | 14 | public void removeAll(Stack stack) { 15 | if (stack.pop() == null) { 16 | return; 17 | } 18 | stack.pop(); 19 | removeAll(stack); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter06/reinforcement/Exercise07.txt: -------------------------------------------------------------------------------- 1 | R-6.7 Suppose an initially empty queue Q has performed a total of 32 enqueue operations, 10 first operations, 2 | and 15 dequeue operations, 5 of which returned null to indicate an empty queue. What is the current size of Q? 3 | 4 | Answer 5 | ------ 6 | If 5 dequeue operations returned null, so only 10 dequeue operations remove some element of the queue. Thus, 7 | the current size of Q is 22. 8 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter06/reinforcement/Exercise08.txt: -------------------------------------------------------------------------------- 1 | R-6.8 Had the queue of the previous problem been an instance of the ArrayQueue class, from Code Fragment 6.10, with 2 | capacity 30 never exceeded, what would be the final value of the instance variable f? 3 | 4 | Answer 5 | ------ 6 | 7 | The previous problem: R-6.7 8 | - 32 enqueue operations, 9 | - 10 first operations, and 10 | - 15 dequeue operations, 5 of which returned null to indicate an empty queue. 11 | 12 | Therefore, 13 | - the first operation don't change the variable f 14 | - only 10 (15 - 5) operations dequeue has removed some element of the queue 15 | 16 | The instance variable f that indicates the index of the front element was just changed when performed the dequeue 17 | operation. Thus, the final value of the variable f is 10. -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter06/reinforcement/Exercise09.txt: -------------------------------------------------------------------------------- 1 | R-6.9 What values are returned during the following sequence of queue operations, if executed on an initially empty 2 | queue? enqueue(5), enqueue(3), dequeue(), enqueue(2), enqueue(8), dequeue(), dequeue(), enqueue(9), enqueue(1), 3 | dequeue(), enqueue(7), enqueue(6), dequeue(), dequeue(), enqueue(4), dequeue(), dequeue(). 4 | 5 | Answer 6 | ------ 7 | 8 | Operation Returned value Contents queue 9 | --------- -------------- -------------- 10 | enqueue(5) - (5) 11 | enqueue(3) - (5, 3) 12 | dequeue() 5 (3) 13 | enqueue(2) - (3, 2) 14 | enqueue(8) - (3, 2, 8) 15 | dequeue() 3 (2, 8) 16 | dequeue() 2 (8) 17 | enqueue(9) - (8, 9) 18 | enqueue(1) - (8, 9, 1) 19 | dequeue() 8 (9, 1) 20 | enqueue(7) - (9, 1, 7) 21 | enqueue(6) - (9, 1, 7, 6) 22 | dequeue() 9 (1, 7, 6) 23 | dequeue() 1 (7, 6) 24 | enqueue(4) - (7, 6, 4) 25 | dequeue() 7 (6, 4) 26 | dequeue() 6 (4) 27 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter06/reinforcement/Exercise10.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter06.reinforcement; 2 | 3 | import rogeriogentil.data.structures.chapter06.Deque; 4 | import rogeriogentil.data.structures.chapter06.DoublyLinkedList; 5 | import rogeriogentil.data.structures.chapter06.Stack; 6 | 7 | /** 8 | * R-6.10 Give a simple adapter that implements the stack ADT while using an instance of a deque for storage. 9 | * 10 | * @author Rogerio J. Gentil 11 | * @param 12 | */ 13 | public class Exercise10 implements Stack { 14 | 15 | private Deque deque; 16 | 17 | public Exercise10() { 18 | this.deque = new DoublyLinkedList<>(); 19 | } 20 | 21 | @Override 22 | public void push(E e) { 23 | this.deque.addLast(e); 24 | } 25 | 26 | @Override 27 | public E pop() { 28 | return this.deque.removeLast(); 29 | } 30 | 31 | @Override 32 | public E top() { 33 | return this.deque.last(); 34 | } 35 | 36 | @Override 37 | public int size() { 38 | return this.deque.size(); 39 | } 40 | 41 | @Override 42 | public boolean isEmpty() { 43 | return this.deque.isEmpty(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter06/reinforcement/Exercise12.txt: -------------------------------------------------------------------------------- 1 | R-6.12 What values are returned during the following sequence of deque ADT operations, on an initially empty deque? 2 | addFirst(3), addLast(8), addLast(9), addFirst(1), last( ), isEmpty( ), addFirst(2), removeLast( ), addLast(7), 3 | first( ), last( ), addLast(4), size( ), removeFirst( ), removeFirst( ). 4 | 5 | Answer 6 | ------ 7 | 8 | Operation Returned value Content of the deque 9 | ----------- -------------- -------------------- 10 | addFirst(3) - (3) 11 | addLast(8) - (3, 8) 12 | addLast(9) - (3, 8, 9) 13 | addFirst(1) - (1, 3, 8, 9) 14 | last() 9 (1, 3, 8, 9) 15 | isEmpty() false (1, 3, 8, 9) 16 | addFirst(2) - (2, 1, 3, 8, 9) 17 | removeLast() 9 (2, 1, 3, 8) 18 | addLast(7) - (2, 1, 3, 8, 7) 19 | first() 2 (2, 1, 3, 8, 7) 20 | last() 7 (2, 1, 3, 8, 7) 21 | addLast(4) - (2, 1, 3, 8, 7, 4) 22 | size() 6 (2, 1, 3, 8, 7, 4) 23 | removeFirst() 2 (1, 3, 8, 7, 4) 24 | removeFirst() 1 (3, 8, 7, 4) 25 | 26 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter07/ArrayList.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter07; 2 | 3 | /** 4 | * 5 | * @author Rogerio J. Gentil 6 | * @param 7 | */ 8 | public class ArrayList implements List { 9 | 10 | private static final int CAPACITY = 16; 11 | private int size = 0; 12 | private E[] data; 13 | 14 | public ArrayList(final int capacity) { 15 | data = (E[]) new Object[capacity]; 16 | } 17 | 18 | public ArrayList() { 19 | this(CAPACITY); 20 | } 21 | 22 | protected void checkIndex(int i) { 23 | if (i < 0 || i > data.length) { 24 | throw new IndexOutOfBoundsException("Invalid index."); 25 | } 26 | } 27 | 28 | @Override 29 | public E get(int i) throws IndexOutOfBoundsException { 30 | checkIndex(i); 31 | return data[i]; 32 | } 33 | 34 | @Override 35 | public E set(int i, E e) throws IndexOutOfBoundsException { 36 | checkIndex(i); 37 | E removed = data[i]; 38 | data[i] = e; 39 | return removed; 40 | } 41 | 42 | @Override 43 | public void add(int i, E e) throws IndexOutOfBoundsException, IllegalStateException { 44 | checkIndex(i); 45 | 46 | if (size == data.length) { 47 | // throw new IllegalStateException("ArrayList is full!"); // before create resize method 48 | resize(data.length * 2); 49 | } 50 | 51 | for (int k = size - 1; k >= i; k--) { 52 | data[k+1] = data[k]; 53 | } 54 | 55 | data[i] = e; 56 | size++; 57 | } 58 | 59 | @Override 60 | public E remove(int i) throws IndexOutOfBoundsException { 61 | checkIndex(i); 62 | E removed = data[i]; 63 | 64 | for (int k = i; k < size - 1; k++) { 65 | data[k] = data[k+1]; 66 | } 67 | 68 | data[size - 1] = null; // help GC 69 | size--; 70 | return removed; 71 | } 72 | 73 | @Override 74 | public int size() { 75 | return this.size; 76 | } 77 | 78 | @Override 79 | public boolean isEmpty() { 80 | return this.size == 0; 81 | } 82 | 83 | protected void resize(final int capacity) { 84 | E[] temp = (E[]) new Object[capacity]; 85 | for (int i = 0; i < size; i++) { 86 | temp[i] = data[i]; 87 | } 88 | data = temp; // sustitui a referência do array 89 | } 90 | 91 | // ----- Method added on resolution of the exercise R-7.5 92 | public void trimToSize() { 93 | E[] temp = (E[]) new Object[this.size()]; 94 | 95 | for (int i = 0; i < this.size(); i++) { 96 | temp[i] = this.data[i]; 97 | } 98 | 99 | // Alternative to 'for' 100 | // System.arraycopy(this.data, 0, temp, 0, this.size()); 101 | 102 | this.data = temp; 103 | temp = null; // GC helper 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter07/List.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter07; 2 | 3 | /** 4 | * 5 | * @author Rogerio J. Gentil 6 | */ 7 | public interface List { 8 | 9 | 10 | /** 11 | * Returns (but does not remove) the element at index i 12 | * @param i 13 | * @return 14 | * @throws IndexOutOfBoundsException 15 | */ 16 | E get(int i) throws IndexOutOfBoundsException; 17 | 18 | /** 19 | * Replaces the element at index i with e, and returns the replaced element. 20 | * @param i 21 | * @param e 22 | * @return 23 | * @throws IndexOutOfBoundsException 24 | */ 25 | E set(int i, E e) throws IndexOutOfBoundsException; 26 | 27 | /** 28 | * Inserts element e to be at index i, shifting all subsequent elements later. 29 | * @param i 30 | * @param e 31 | * @throws IndexOutOfBoundsException 32 | */ 33 | void add(int i, E e) throws IndexOutOfBoundsException; 34 | 35 | /** 36 | * Removes/returns the element at index i, shifting subsequent elements earlier. 37 | * @param i 38 | * @return 39 | * @throws IndexOutOfBoundsException 40 | */ 41 | E remove(int i) throws IndexOutOfBoundsException; 42 | 43 | /** 44 | * Returns the number of elements in this list. 45 | * @return 46 | */ 47 | int size(); 48 | 49 | /** 50 | * Returns whether the list is empty. 51 | * @return 52 | */ 53 | boolean isEmpty(); 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter07/Position.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter07; 2 | 3 | /** 4 | * 5 | * @author Rogerio J. Gentil 6 | */ 7 | public interface Position { 8 | 9 | /** 10 | * Returns the element stored at this position. 11 | * 12 | * @return An element 13 | * @throws IllegalStateException if position no longer valid 14 | */ 15 | E getElement() throws IllegalStateException; 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter07/PositionalList.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter07; 2 | 3 | /** 4 | * 5 | * @author Rogerio J. Gentil 6 | */ 7 | public interface PositionalList { 8 | 9 | Position first(); 10 | 11 | Position last(); 12 | 13 | /** 14 | * Returns the Position immediately before Position p (or null, if p is first). 15 | * @param p 16 | * @return 17 | * @throws IllegalStateException 18 | */ 19 | Position before(Position p) throws IllegalStateException; 20 | 21 | /** 22 | * Returns the Position immediately after Position p (or null, if p is last). 23 | * @param p 24 | * @return 25 | * @throws IllegalStateException 26 | */ 27 | Position after(Position p) throws IllegalStateException; 28 | 29 | /** 30 | * Inserts element e at the front of the list and returns its new Position. 31 | * @param element 32 | * @return 33 | */ 34 | Position addFirst(E element); 35 | 36 | /** 37 | * Inserts element e at the back of the list and returns its new Position. 38 | * @param element 39 | * @return 40 | */ 41 | Position addLast(E element); 42 | 43 | /** 44 | * Inserts element e immediately before Position p and returns its new Position. 45 | * @param p 46 | * @param element 47 | * @return 48 | * @throws IllegalStateException 49 | */ 50 | Position addBefore(Position p, E element) throws IllegalStateException; 51 | 52 | /** 53 | * Inserts element e immediately after Position p and returns its new Position. 54 | * @param p 55 | * @param element 56 | * @return 57 | * @throws IllegalStateException 58 | */ 59 | Position addAfter(Position p, E element) throws IllegalStateException; 60 | 61 | /** 62 | * Replaces the element stored at Position p and returns the replaced element. 63 | * @param p 64 | * @param element 65 | * @return 66 | * @throws IllegalStateException 67 | */ 68 | E set(Position p, E element) throws IllegalStateException; 69 | 70 | /** 71 | * Removes the element stored at Position p and returns it (invalidating p). 72 | * @param p 73 | * @return 74 | * @throws IllegalArgumentException 75 | */ 76 | E remove(Position p) throws IllegalArgumentException; 77 | 78 | int size(); 79 | 80 | boolean isEmpty(); 81 | } 82 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter07/reinforcement/Exercise01.txt: -------------------------------------------------------------------------------- 1 | Q: Draw a representation, akin to Example 7.1, of an initially empty list L after per- 2 | forming the following sequence of operations: add(0, 4), add(0, 3), add(0, 2), 3 | add(2, 1), add(1, 5), add(1, 6), add(3, 7), add(0, 8). 4 | 5 | add(0, 4) - (4) 6 | add(0, 3) - (3, 4) 7 | add(0, 2) - (2, 3, 4) 8 | add(2, 1) - (2, 3, 1, 4) 9 | add(1, 5) - (2, 5, 3, 1, 4) 10 | add(1, 6) - (2, 6, 5, 3, 1, 4) 11 | add(3, 7) - (2, 6, 5, 7, 3, 1, 4) 12 | add(0, 8) - (8, 2, 6, 5, 7, 3, 1, 4) -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter07/reinforcement/Exercise02.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter07.reinforcement; 2 | 3 | import rogeriogentil.data.structures.chapter06.Stack; 4 | import rogeriogentil.data.structures.chapter07.ArrayList; 5 | 6 | /** 7 | * 8 | * @author Rogerio J. Gentil 9 | */ 10 | public class Exercise02 { 11 | } 12 | 13 | /** 14 | * R-7.2 Give an implementation of the stack ADT using an array list for storage. 15 | */ 16 | class StackArrayList implements Stack { 17 | 18 | private static final int CAPACITY = 16; 19 | private ArrayList data; 20 | 21 | public StackArrayList(final int capacity) { 22 | data = new ArrayList<>(capacity); 23 | } 24 | 25 | public StackArrayList() { 26 | this(CAPACITY); 27 | } 28 | 29 | @Override 30 | public E top() { 31 | return data.get(this.size() - 1); 32 | } 33 | 34 | @Override 35 | public E pop() { 36 | return data.remove(this.size() - 1); 37 | } 38 | 39 | @Override 40 | public void push(E element) { 41 | data.add(size(), element); 42 | } 43 | 44 | @Override 45 | public boolean isEmpty() { 46 | return this.data.size() == 0; 47 | } 48 | 49 | @Override 50 | public int size() { 51 | return this.data.size(); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter07/reinforcement/Exercise03.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter07.reinforcement; 2 | 3 | import rogeriogentil.data.structures.chapter06.Deque; 4 | import rogeriogentil.data.structures.chapter07.ArrayList; 5 | 6 | /** 7 | * 8 | * @author Rogerio J. Gentil 9 | */ 10 | public class Exercise03 { 11 | } 12 | 13 | /** 14 | * R-7.3 Give an implementation of the deque ADT using an array list for storage. 15 | * 16 | * @author rogerio 17 | */ 18 | class DequeArrayList implements Deque { 19 | 20 | private static final int CAPACITY = 32; 21 | private ArrayList data; 22 | 23 | public DequeArrayList(final int capacity) { 24 | data = new ArrayList<>(capacity); 25 | } 26 | 27 | public DequeArrayList() { 28 | this(CAPACITY); 29 | } 30 | 31 | @Override 32 | public void addFirst(E element) { 33 | this.data.add(0, element); 34 | } 35 | 36 | @Override 37 | public void addLast(E element) { 38 | this.data.add(this.data.size(), element); 39 | } 40 | 41 | @Override 42 | public E removeFirst() { 43 | return this.data.remove(0); 44 | } 45 | 46 | @Override 47 | public E removeLast() { 48 | return this.data.remove(this.data.size() - 1); 49 | } 50 | 51 | @Override 52 | public E first() { 53 | return this.data.get(0); 54 | } 55 | 56 | @Override 57 | public E last() { 58 | return this.data.get(this.data.size() - 1); 59 | } 60 | 61 | @Override 62 | public int size() { 63 | return this.data.size(); 64 | } 65 | 66 | @Override 67 | public boolean isEmpty() { 68 | return this.data.size() == 0; 69 | } 70 | 71 | } -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter07/reinforcement/Exercise05.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter07.reinforcement; 2 | 3 | import rogeriogentil.data.structures.chapter07.ArrayList; 4 | 5 | /** 6 | * R-7.5 The java.util.ArrayList includes a method, trimToSize(), that replaces 7 | * the underlying array with one whose capacity precisely equals the number of 8 | * elements currently in the list. Implement such a method for our dynamic 9 | * version of the ArrayList class from Section 7.2. 10 | * 11 | * Details: https://docs.oracle.com/javase/9/docs/api/java/util/ArrayList.html#trimToSize-- 12 | * 13 | * @author Rogerio J. Gentil 14 | * @param 15 | */ 16 | public class Exercise05 { 17 | 18 | /** 19 | * See the method trimToSize() in the class ArrayList 20 | */ 21 | public void trimToSize() { 22 | ArrayList list = new ArrayList<>(); 23 | list.trimToSize(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter07/reinforcement/Exercise10.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter07.reinforcement; 2 | 3 | import rogeriogentil.data.structures.chapter06.Stack; 4 | import rogeriogentil.data.structures.chapter07.ArrayList; 5 | 6 | /** 7 | * R-7.10 Reimplement the ArrayStack class, from Section 6.1.2, using dynamic 8 | * arrays to support unlimited capacity. 9 | * 10 | * @author Rogerio J. Gentil 11 | */ 12 | public class Exercise10 {} 13 | 14 | class ArrayStack implements Stack { 15 | 16 | private ArrayList data; 17 | 18 | public ArrayStack() { 19 | this.data = new ArrayList(); 20 | } 21 | 22 | @Override 23 | public void push(E e) { 24 | this.data.add(this.size(), e); 25 | } 26 | 27 | @Override 28 | public E pop() { 29 | return this.data.remove(size() - 1); 30 | } 31 | 32 | @Override 33 | public E top() { 34 | int i = this.size() - 1; 35 | return this.data.get(i); 36 | } 37 | 38 | @Override 39 | public int size() { 40 | return this.data.size(); 41 | } 42 | 43 | @Override 44 | public boolean isEmpty() { 45 | return this.data.isEmpty(); 46 | } 47 | } -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter08/AbstractBinaryTree.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter08; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import rogeriogentil.data.structures.chapter07.Position; 6 | 7 | /** 8 | * 9 | * @author Rogerio J. Gentil 10 | * @param 11 | */ 12 | public abstract class AbstractBinaryTree extends AbstractTree implements BinaryTree { 13 | 14 | @Override 15 | public Position sibling(Position position) throws IllegalArgumentException { 16 | Position parent = parent(position); 17 | 18 | if (parent == null) { 19 | return null; // p must be the root 20 | } 21 | 22 | if (position == left(parent)) { 23 | return right(parent); 24 | } 25 | 26 | return left(parent); 27 | } 28 | 29 | @Override 30 | public int numChildren(Position position) { 31 | int count = 0; 32 | 33 | if (left(position) != null) { 34 | count++; 35 | } 36 | 37 | if (right(position) != null) { 38 | count++; 39 | } 40 | 41 | return count; 42 | } 43 | 44 | @Override 45 | public Iterable> children(Position position) { 46 | List> snapshot = new ArrayList<>(2); // max capacity of 2 47 | 48 | if (left(position) != null) { 49 | snapshot.add(left(position)); 50 | } 51 | 52 | if (right(position) != null) { 53 | snapshot.add(right(position)); 54 | } 55 | 56 | return snapshot; 57 | } 58 | 59 | /** 60 | * Adds positions of the subtree rooted at a position to the given snapshot. 61 | * 62 | * @param position 63 | * @param snapshot 64 | */ 65 | private void inOrderSubtree(Position position, List> snapshot) { 66 | if (left(position) != null) { 67 | inOrderSubtree(left(position), snapshot); 68 | } 69 | 70 | snapshot.add(position); 71 | 72 | if (right(position) != null) { 73 | inOrderSubtree(right(position), snapshot); 74 | } 75 | } 76 | 77 | /** 78 | * Returns an iterable collection of positions of the tree, reported in inorder. 79 | * 80 | * @return 81 | */ 82 | public Iterable> inOrder() { 83 | List> snapshot = new ArrayList<>(); 84 | 85 | if (!isEmpty()) { 86 | inOrderSubtree(root(), snapshot); // fill the snapshot recursively 87 | } 88 | 89 | return snapshot; 90 | } 91 | 92 | @Override 93 | public Iterable> positions() { 94 | return inOrder(); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter08/AbstractTree.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter08; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import rogeriogentil.data.structures.chapter06.LinkedQueue; 6 | import rogeriogentil.data.structures.chapter06.Queue; 7 | import rogeriogentil.data.structures.chapter07.Position; 8 | 9 | /** 10 | * 11 | * @author Rogerio J. Gentil 12 | * @param 13 | */ 14 | public abstract class AbstractTree implements Tree { 15 | 16 | @Override 17 | public boolean isInternal(Position position) throws IllegalStateException { 18 | return numChildren(position) > 0; 19 | } 20 | 21 | @Override 22 | public boolean isExternal(Position position) throws IllegalStateException { 23 | return numChildren(position) == 0; 24 | } 25 | 26 | @Override 27 | public boolean isRoot(Position position) throws IllegalStateException { 28 | return position == root(); 29 | } 30 | 31 | @Override 32 | public boolean isEmpty() { 33 | return size() == 0; 34 | } 35 | 36 | public int depth(Position position) { 37 | if (isRoot(position)) { 38 | return 0; 39 | } 40 | 41 | return 1 + depth(parent(position)); 42 | } 43 | 44 | /** 45 | * Returns the height of the subtree rooted at Position p. 46 | * 47 | * @param position 48 | * @return 49 | */ 50 | public int height(Position position) { 51 | int height = 0; 52 | 53 | for (Position child : children(position)) { 54 | height = Math.max(height, 1 + height(child)); 55 | } 56 | 57 | return height; 58 | } 59 | 60 | /** 61 | * Returns the height of the tree. 62 | * 63 | * @return 64 | */ 65 | private int heightBad() { // works, but quadratic worst-case time 66 | int height = 0; 67 | for (Position position : positions()) { 68 | if (isExternal(position)) { 69 | height = Math.max(height, depth(position)); 70 | } 71 | } 72 | 73 | return height; 74 | } 75 | 76 | /** 77 | * Adds positions of the subtree rooted at position to the given snapshot. 78 | * 79 | * @param position 80 | * @param snapshot 81 | */ 82 | private void preOrderSubtree(Position position, List> snapshot) { 83 | snapshot.add(position); // for preorder, we add position before exploring subtrees 84 | 85 | for (Position child : children(position)) { 86 | preOrderSubtree(child, snapshot); 87 | } 88 | } 89 | 90 | /** 91 | * Returns an iterable collection of positions of the tree, reported in preorder. 92 | * 93 | * @return 94 | */ 95 | public Iterable> preOrder() { 96 | List> snapshot = new ArrayList<>(); 97 | if (!isEmpty()) { 98 | preOrderSubtree(root(), snapshot); 99 | } 100 | 101 | return snapshot; 102 | } 103 | 104 | /** 105 | * Adds positions of the subtree rooted at Position p to the given snapshot. 106 | * @param position 107 | * @param snapshot 108 | */ 109 | private void postOrderSubtree(Position position, List> snapshot) { 110 | for (Position child : children(position)) { 111 | postOrderSubtree(child, snapshot); 112 | } 113 | 114 | snapshot.add(position); // for preorder, we add position before exploring subtrees 115 | } 116 | 117 | public Iterable> postOrder() { 118 | List> snapshot = new ArrayList<>(); 119 | if (!isEmpty()) { 120 | postOrderSubtree(root(), snapshot); 121 | } 122 | 123 | return snapshot; 124 | } 125 | 126 | /** 127 | * Returns an iterable collection of positions of the tree in breadth-first order. 128 | * 129 | * @return 130 | */ 131 | public Iterable> breathFirst() { 132 | List> snapshot = new ArrayList<>(); 133 | 134 | if (!isEmpty()) { 135 | Queue> fringe = new LinkedQueue<>(); 136 | fringe.enqueue(root()); 137 | 138 | while (!fringe.isEmpty()) { 139 | Position position = fringe.dequeue(); 140 | snapshot.add(position); 141 | 142 | for (Position child : children(position)) { 143 | fringe.enqueue(child); 144 | } 145 | } 146 | } 147 | 148 | return snapshot; 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter08/BinaryTree.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter08; 2 | 3 | import rogeriogentil.data.structures.chapter07.Position; 4 | 5 | /** 6 | * 7 | * @author Rogerio J. Gentil 8 | * @param 9 | */ 10 | public interface BinaryTree extends Tree { 11 | 12 | /** 13 | * Returns the Position of p's left child (or null if no child exists). 14 | * @param position 15 | * @return 16 | * @throws IllegalArgumentException 17 | */ 18 | Position left(Position position) throws IllegalArgumentException; 19 | 20 | /** 21 | * Returns the Position of p's right child (or null if no child exists). 22 | * @param position 23 | * @return 24 | * @throws IllegalArgumentException 25 | */ 26 | Position right(Position position) throws IllegalArgumentException; 27 | 28 | /** 29 | * Returns the Position of p's sibling (or null if no sibling exists). 30 | * @param position 31 | * @return 32 | * @throws IllegalArgumentException 33 | */ 34 | Position sibling(Position position) throws IllegalArgumentException; 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter08/Tree.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter08; 2 | 3 | import java.util.Iterator; 4 | import rogeriogentil.data.structures.chapter07.Position; 5 | 6 | /** 7 | * 8 | * @author Rogerio J. Gentil 9 | * @param 10 | */ 11 | public interface Tree extends Iterable { 12 | 13 | /** 14 | * Returns the position of the root of the tree (or null if empty). 15 | * @return 16 | */ 17 | Position root(); 18 | 19 | /** 20 | * Returns the position of the parent of position p (or null if p is the root). 21 | * @param position 22 | * @return 23 | */ 24 | Position parent(Position position) throws IllegalStateException; 25 | 26 | /** 27 | * Returns an iterable collection containing the children of position p (if any). 28 | * @param position 29 | * @return 30 | */ 31 | Iterable> children(Position position) throws IllegalStateException; 32 | 33 | /** 34 | * Returns the number of children of position p. 35 | * @param position 36 | * @return 37 | */ 38 | int numChildren(Position position) throws IllegalStateException; 39 | 40 | /** 41 | * Returns true if position p has at least one child. 42 | * @param position 43 | * @return 44 | */ 45 | boolean isInternal(Position position) throws IllegalStateException; 46 | 47 | /** 48 | * Returns true if position p does not have any children. 49 | * @param position 50 | * @return 51 | */ 52 | boolean isExternal(Position position) throws IllegalStateException; 53 | 54 | /** 55 | * Returns true if position p is the root of the tree. 56 | * @param position 57 | * @return 58 | */ 59 | boolean isRoot(Position position) throws IllegalStateException; 60 | 61 | int size(); 62 | 63 | boolean isEmpty(); 64 | 65 | /** 66 | * Returns an iterator for all elements in the tree (so that the tree itself is Iterable). 67 | * @return 68 | */ 69 | @Override 70 | Iterator iterator(); 71 | 72 | /** 73 | * Returns an iterable collection of all positions of the tree. 74 | * @return 75 | */ 76 | Iterable> positions(); 77 | 78 | } 79 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter08/TreeUtil.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter08; 2 | 3 | import java.util.List; 4 | import rogeriogentil.data.structures.chapter07.Position; 5 | 6 | /** 7 | * 8 | * @author Rogerio J. Gentil 9 | */ 10 | public class TreeUtil { 11 | 12 | /** 13 | * Prints preorder representation of subtree of a tree rooted at a position having a depth. 14 | * 15 | * @param 16 | * @param tree 17 | * @param position 18 | * @param depth 19 | */ 20 | public static void printPreOrderIndent(Tree tree, Position position, int depth) { 21 | System.out.println(spaces(2 * depth) + position.getElement()); 22 | 23 | for (Position child : tree.children(position)) { 24 | printPreOrderIndent(tree, child, depth + 1); // child depth is d+1 25 | } 26 | } 27 | 28 | /** 29 | * Prints labeled representation of subtree of the tree rooted at a position having a depth. 30 | * 31 | * @param 32 | * @param tree 33 | * @param position 34 | * @param path 35 | */ 36 | public static void printPreOrderLabeled(Tree tree, Position position, List path) { 37 | int depth = path.size(); // depth equals the length of the path 38 | System.out.print(spaces(2 * depth)); 39 | 40 | for (int j = 0; j < depth; j++) { 41 | System.out.print(path.get(j) + (j == depth - 1 ? " " : ".")); 42 | } 43 | 44 | System.out.println(position.getElement()); 45 | 46 | path.add(1); // add path entry for first child 47 | 48 | for (Position child : tree.children(position)) { 49 | printPreOrderLabeled(tree, child, path); 50 | path.set(depth, 1 + path.get(depth)); // increment last entry of path 51 | } 52 | 53 | path.remove(depth); 54 | } 55 | 56 | /** 57 | * Prints parenthesized representation of subtree of the tree rooted at a position 58 | * 59 | * @param 60 | * @param tree 61 | * @param position 62 | */ 63 | public static void paranthesize(Tree tree, Position position) { 64 | System.out.println(position.getElement()); 65 | 66 | if (tree.isInternal(position)) { 67 | boolean firstTime = true; 68 | 69 | for (Position child : tree.children(position)) { 70 | System.out.println(firstTime ? "(" : ", "); 71 | firstTime = false; 72 | paranthesize(tree, child); 73 | } 74 | 75 | System.out.println(")"); 76 | } 77 | } 78 | 79 | private static String spaces(int n) { 80 | StringBuilder sb = new StringBuilder(); 81 | for (int i = 0; i < n; i++) { 82 | sb.append(" "); 83 | } 84 | return sb.toString(); 85 | } 86 | 87 | /** 88 | * Recursive method for computing coordinates at which to draw positions of a binary tree. We assume that the element 89 | * type for the tree supports setX and setY methods. The initial call should be layout(T, T.root( ), 0, 0). 90 | * 91 | * @param 92 | * @param binaryTree 93 | * @param position 94 | * @param depth 95 | * @param x 96 | * @return 97 | */ 98 | // public static int layout(BinaryTree binaryTree, Position position, int depth, int x) { 99 | // if (binaryTree.left(position) != null) { 100 | // x = layout(binaryTree, binaryTree.left(position), depth + 1, x); // resulting x will be increased 101 | // } 102 | // 103 | // position.getElement().setX(x++); 104 | // position.getElement().setY(depth); 105 | // 106 | // if (binaryTree.right(position) != null) { 107 | // x = layout(binaryTree, binaryTree.right(position), depth + 1, x); // resulting x will be increased 108 | // } 109 | // 110 | // return x; 111 | // } 112 | } 113 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter08/reinforcement/Exercise01.txt: -------------------------------------------------------------------------------- 1 | R-8.1 The following questions refer to the tree of Figure 8.3. 2 | a. Which node is the root? 3 | /user/rt/courses/ 4 | 5 | b. What are the internal nodes? 6 | /user/rt/courses/ 7 | cs016/ 8 | homeworks/ 9 | programs/ 10 | cs252/ 11 | projects/ 12 | papers/ 13 | demos/ 14 | 15 | c. How many descendants does node cs016/ have? 16 | Does have 9 descendants 17 | 18 | d. How many ancestors does node cs016/ have? 19 | Just one ancestor: "/user/rt/courses/" 20 | 21 | e. What are the siblings of node homeworks/? 22 | "grades" and "programs/" 23 | 24 | f. Which nodes are in the subtree rooted at node projects/? 25 | papers/ 26 | buylow 27 | sellhigh 28 | market 29 | demos/ 30 | 31 | g. What is the depth of node papers/? 32 | The depth is 3 33 | 34 | h. What is the height of the tree? 35 | The height is 4 -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter08/reinforcement/Exercise05.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter08.reinforcement; 2 | 3 | import rogeriogentil.data.structures.chapter07.Position; 4 | import rogeriogentil.data.structures.chapter08.BinaryTree; 5 | 6 | /** 7 | * R-8.5 Describe an algorithm, relying only on the BinaryTree operations, that counts the number of leaves in a binary 8 | * tree that are the left child of their respective parent. 9 | * 10 | * @author Rogerio J. Gentil 11 | */ 12 | public class Exercise05 { 13 | 14 | public static int countLeftLeaves(BinaryTree binaryTree, Position position) { 15 | int count = 0; 16 | 17 | if (binaryTree.isEmpty() || binaryTree.size() == 1) { 18 | return count; 19 | } 20 | 21 | Position parent = binaryTree.parent(position); 22 | 23 | if (binaryTree.isExternal(position) && binaryTree.left(parent) == position) { 24 | return count + 1; 25 | } else { 26 | if (binaryTree.left(position) != null) { 27 | count += countLeftLeaves(binaryTree, binaryTree.left(position)); 28 | } 29 | 30 | if (binaryTree.right(position) != null) { 31 | count += countLeftLeaves(binaryTree, binaryTree.right(position)); 32 | } 33 | 34 | } 35 | 36 | return count; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter08/reinforcement/Exercise07.txt: -------------------------------------------------------------------------------- 1 | R-8.7 What are the minimum and maximum number of internal and external nodes in 2 | an improper binary tree with n nodes? 3 | 4 | Answer: 5 | - Minimum internal nodes: 1 node 6 | - Minimum external nodes: 1 node 7 | - Maximum internal nodes: 8 | - Maximum external nodes: 9 | 10 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter08/reinforcement/Exercise12.txt: -------------------------------------------------------------------------------- 1 | R-8.12 Draw the binary tree representation of the following arithmetic expression: 2 | "(((5 + 2) ∗ (2 − 1))/((2 + 9) + ((7 − 2) − 1)) ∗ 8)" 3 | 4 | Answer: 5 | / 6 | 7 | * + 8 | 9 | + - + * 10 | 11 | 5 2 2 1 2 9 8 - 12 | 13 | 1 - 14 | 15 | 7 2 -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter08/reinforcement/Exercise18.txt: -------------------------------------------------------------------------------- 1 | R-8.18 In what order are positions visited during a preorder traversal of the 2 | tree of Figure 8.6? 3 | 4 | Answer 5 | ------ 6 | 7 | -, /, *, +, 3, 1, 3, +, -, 9, 5, 2, +, *, 3, -, 7, 4, 6 8 | 9 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter08/reinforcement/Exercise19.txt: -------------------------------------------------------------------------------- 1 | R-8.19 In what order are positions visited during a postorder traversal of the 2 | tree of Figure 8.6? 3 | 4 | Answer 5 | ------ 6 | 7 | 3, 1, +, 3, *, 9, 5, -, 2, +, /, 3, 7, 4, -, *, 6, +, - 8 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter08/reinforcement/Exercise20.txt: -------------------------------------------------------------------------------- 1 | R-8.20 Let T be an ordered tree with more than one node. Is it possible that the 2 | preorder traversal of T visits the nodes in the same order as the postorder 3 | traversal of T? If so, give an example; otherwise, explain why this cannot occur. 4 | Likewise, is it possible that the preorder traversal of T visits the nodes in the 5 | reverse order of the postorder traversal of T? If so, give an example; otherwise, 6 | explain why this cannot occur. 7 | 8 | Answers 9 | ------- 10 | "Is it possible that the preorder traversal of T visits the nodes in the same 11 | order as the postorder traversal of T?" 12 | A: No. Because, given a tree with two nodes, for instance, in the preorder the 13 | first node visited is the root whereas in the postorder the first node visited 14 | is a child. 15 | 16 | "is it possible that the preorder traversal of T visits the nodes in the reverse 17 | order of the postorder traversal of T?" 18 | A: Yes, but only when a tree has two nodes. -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter08/reinforcement/Exercise22.txt: -------------------------------------------------------------------------------- 1 | R-8.22 Draw a binary tree T that simultaneously satisfies the following: 2 | • Each internal node of T stores a single character. 3 | • A preorder traversal of T yields EXAMFUN. 4 | • An inorder traversal of T yields MAFXUEN. 5 | 6 | Answer 7 | ------ 8 | E 9 | 10 | X N 11 | 12 | A U 13 | 14 | M F -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter08/reinforcement/Exercise24.txt: -------------------------------------------------------------------------------- 1 | R-8.24 Give the output of the method parenthesize(T, T.root( )), as described in 2 | Code Fragment 8.26, when T is the tree of Figure 8.6. 3 | 4 | Answer 5 | ------ 6 | 7 | -(/(*(+(3,1),3),+(-(9,5),2)),+(*(3,-(7,4)),6)) 8 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter09/AbstractPriorityQueue.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter09; 2 | 3 | import java.util.Comparator; 4 | 5 | /** 6 | * 7 | * @author Rogerio J. Gentil 8 | * @param 9 | * @param 10 | */ 11 | public abstract class AbstractPriorityQueue implements PriorityQueue { 12 | 13 | private Comparator comparator; 14 | 15 | protected AbstractPriorityQueue(Comparator c) { 16 | this.comparator = c; 17 | } 18 | 19 | protected AbstractPriorityQueue() { 20 | this(new DefaultComparator()); 21 | } 22 | 23 | /** 24 | * Method for comparing two entries according to key 25 | * 26 | * @param a 27 | * @param b 28 | * @return 29 | */ 30 | protected int compare(Entry a, Entry b) { 31 | return comparator.compare(a.getKey(), b.getKey()); 32 | } 33 | 34 | /** 35 | * Determines whether a key is valid. 36 | * 37 | * @param key 38 | * @return 39 | * @throws IllegalArgumentException 40 | */ 41 | protected boolean checkKey(K key) throws IllegalArgumentException { 42 | try { 43 | return comparator.compare(key, key) == 0; // see if key can be compared to itself 44 | } catch (ClassCastException e) { 45 | throw new IllegalArgumentException("Incompatible key"); 46 | } 47 | } 48 | 49 | @Override 50 | public boolean isEmpty() { 51 | return size() == 0; 52 | } 53 | 54 | //---------------- nested PQEntry class --------------- 55 | protected static class PQEntry implements Entry { 56 | 57 | private K key; 58 | private V value; 59 | 60 | public PQEntry(K key, V value) { 61 | this.key = key; 62 | this.value = value; 63 | } 64 | 65 | @Override 66 | public K getKey() { 67 | return this.key; 68 | } 69 | 70 | @Override 71 | public V getvalue() { 72 | return this.value; 73 | } 74 | 75 | // utilities not exposed as part of the Entry interface 76 | protected void setKey(K key) { 77 | this.key = key; 78 | } 79 | 80 | protected void setValue(V value) { 81 | this.value = value; 82 | } 83 | } 84 | //------------ end of nested PQEntry class ------------ 85 | } 86 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter09/AdaptablePriorityQueue.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter09; 2 | 3 | /** 4 | * 5 | * @author Rogerio J. Gentil 6 | */ 7 | interface AdaptablePriorityQueue { 8 | 9 | void remove(Entry entry); 10 | 11 | void replaceKey(Entry entry, K key); 12 | 13 | void replaceValue(Entry entry, V value); 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter09/DefaultComparator.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter09; 2 | 3 | import java.util.Comparator; 4 | 5 | /** 6 | * 7 | * @author Rogerio J. Gentil 8 | */ 9 | public class DefaultComparator implements Comparator { 10 | 11 | @Override 12 | public int compare(E a, E b) throws ClassCastException { 13 | return ((Comparable) a).compareTo(b); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter09/Entry.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter09; 2 | 3 | /** 4 | * Interface for a key-value pair 5 | * 6 | * @author Rogerio J. Gentil 7 | * @param key 8 | * @param value 9 | */ 10 | public interface Entry { 11 | 12 | /** 13 | * Returns the key stored in this entry 14 | * 15 | * @return 16 | */ 17 | K getKey(); 18 | 19 | /** 20 | * Returns the value stored in this entry 21 | * 22 | * @return 23 | */ 24 | V getvalue(); 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter09/HeapPriorityQueue.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter09; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Comparator; 5 | 6 | /** 7 | * 8 | * @author Rogerio J. Gentil 9 | * @param 10 | * @param 11 | */ 12 | public class HeapPriorityQueue extends AbstractPriorityQueue { 13 | 14 | protected ArrayList> heap = new ArrayList<>(); 15 | 16 | public HeapPriorityQueue() { 17 | } 18 | 19 | public HeapPriorityQueue(Comparator c) { 20 | super(c); 21 | } 22 | 23 | public HeapPriorityQueue(K[] keys, V[] values) { 24 | super(); 25 | for (int j = 0; j < Math.min(keys.length, values.length); j++) { 26 | heap.add(new PQEntry<>(keys[j], values[j])); 27 | } 28 | heapify(); 29 | } 30 | 31 | // protected utilities 32 | protected int parent(int j) { 33 | return (j - 1) / 2; 34 | } 35 | 36 | protected int left(int j) { 37 | return 2 * j + 1; 38 | } 39 | 40 | protected int right(int j) { 41 | return 2 * j + 2; 42 | } 43 | 44 | protected boolean hasLeft(int j) { 45 | return this.left(j) < heap.size(); 46 | } 47 | 48 | protected boolean hasRight(int j) { 49 | return this.right(j) < heap.size(); 50 | } 51 | 52 | /** 53 | * Exchanges the entries at indices i and j of the array list. 54 | * 55 | * @param i 56 | * @param j 57 | */ 58 | protected void swap(int i, int j) { 59 | Entry temp = heap.get(i); 60 | heap.set(i, heap.get(j)); 61 | heap.set(j, temp); 62 | } 63 | 64 | /** 65 | * Moves the entry at index j higher, if necessary, to restore the heap 66 | * property. 67 | * 68 | * @param j 69 | */ 70 | protected void upHeap(int j) { 71 | while (j > 0) { // continue until reaching root (or break statement) 72 | int p = parent(j); 73 | 74 | if (compare(heap.get(j), heap.get(p)) >= 0) { 75 | break; 76 | } 77 | 78 | swap(j, p); 79 | j = p; // continue from the parent's location 80 | } 81 | } 82 | 83 | /** 84 | * Moves the entry at index j lower, if necessary, to restore the heap 85 | * property. 86 | * 87 | * @param j 88 | */ 89 | protected void downHeap(int j) { 90 | while (hasLeft(j)) { // continue to bottom (or break statement) 91 | int leftIndex = left(j); 92 | int smallChildIndex = leftIndex; // although right may be smaller 93 | 94 | if (hasRight(j)) { 95 | int rightIndex = right(j); 96 | if (compare(heap.get(leftIndex), heap.get(rightIndex)) > 0) { 97 | smallChildIndex = rightIndex; 98 | } 99 | } 100 | 101 | if (compare(heap.get(smallChildIndex), heap.get(j)) >= 0) { 102 | break; 103 | } 104 | 105 | swap(j, smallChildIndex); 106 | j = smallChildIndex; 107 | } 108 | } 109 | 110 | @Override 111 | public int size() { 112 | return heap.size(); 113 | } 114 | 115 | @Override 116 | public Entry min() { 117 | if (heap.isEmpty()) { 118 | return null; 119 | } 120 | 121 | return heap.get(0); 122 | } 123 | 124 | @Override 125 | public Entry insert(K key, V value) throws IllegalArgumentException { 126 | checkKey(key); 127 | Entry newest = new PQEntry<>(key, value); 128 | heap.add(newest); 129 | upHeap(heap.size() - 1); 130 | return newest; 131 | } 132 | 133 | @Override 134 | public Entry removeMin() { 135 | if (heap.isEmpty()) { 136 | return null; 137 | } 138 | 139 | Entry temp = heap.get(0); 140 | swap(0, heap.size() - 1); 141 | heap.remove(heap.size() - 1); 142 | downHeap(0); 143 | return temp; 144 | } 145 | 146 | /** 147 | * Performs a bottom-up construction of the heap in linear time. 148 | */ 149 | protected void heapify() { 150 | int startIndex = parent(size() - 1); // start at PARENT of last entry 151 | for (int j = startIndex; j >= 0; j--) { // loop until processing the root 152 | downHeap(j); 153 | } 154 | } 155 | 156 | } 157 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter09/PriorityQueue.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter09; 2 | 3 | /** 4 | * Interface for the priority queue ADT. 5 | * 6 | * @author Rogerio J. Gentil 7 | * @param 8 | * @param 9 | */ 10 | public interface PriorityQueue { 11 | 12 | int size(); 13 | 14 | boolean isEmpty(); 15 | 16 | Entry insert(K key, V value) throws IllegalArgumentException; 17 | 18 | Entry min(); 19 | 20 | Entry removeMin(); 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter09/PriorityQueueUtils.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter09; 2 | 3 | import rogeriogentil.data.structures.chapter07.PositionalList; 4 | 5 | /** 6 | * 7 | * @author Rogerio J. Gentil 8 | * @param 9 | */ 10 | public class PriorityQueueUtils { 11 | 12 | /** 13 | * Sorts sequence using initially empty priority queue to produce the order. 14 | * 15 | * @param 16 | * @param sequence 17 | * @param priorityQueue 18 | */ 19 | public static void pqSort(PositionalList sequence, PriorityQueue priorityQueue) { 20 | int n = sequence.size(); 21 | 22 | for (int i = 0; i < n; i++) { 23 | E element = sequence.remove(sequence.first()); 24 | priorityQueue.insert(element, null); // element is key; null value 25 | } 26 | 27 | for (int i = 0; i < n; i++) { 28 | E element = priorityQueue.removeMin().getKey(); 29 | sequence.addLast(element); // the smallest key in Priority Queye is next placed in Sequence 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter09/SortedPriorityQueue.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter09; 2 | 3 | import java.util.Comparator; 4 | import rogeriogentil.data.structures.chapter07.LinkedPositionalList; 5 | import rogeriogentil.data.structures.chapter07.Position; 6 | 7 | /** 8 | * 9 | * @author Rogerio J. Gentil 10 | * @param key 11 | * @param value 12 | */ 13 | public class SortedPriorityQueue extends AbstractPriorityQueue { 14 | 15 | private LinkedPositionalList> list = new LinkedPositionalList<>(); 16 | 17 | public SortedPriorityQueue() { 18 | } 19 | 20 | public SortedPriorityQueue(Comparator c) { 21 | super(c); 22 | } 23 | 24 | @Override 25 | public Entry insert(K key, V value) throws IllegalArgumentException { 26 | if (!checkKey(key)) { 27 | throw new IllegalArgumentException(); 28 | } 29 | 30 | Entry newest = new PQEntry<>(key, value); 31 | 32 | Position> walk = list.last(); 33 | 34 | while (walk != null && compare(newest, walk.getElement()) < 0) { 35 | walk = list.before(walk); 36 | 37 | if (walk == null) { 38 | list.addFirst(newest); 39 | } else { 40 | list.addAfter(walk, newest); 41 | } 42 | } 43 | 44 | return newest; 45 | } 46 | 47 | @Override 48 | public Entry min() { 49 | if (list.isEmpty()) { 50 | return null; 51 | } 52 | 53 | return list.first().getElement(); 54 | } 55 | 56 | @Override 57 | public Entry removeMin() { 58 | if (list.isEmpty()) { 59 | return null; 60 | } 61 | 62 | return list.remove(list.first()); 63 | } 64 | 65 | @Override 66 | public int size() { 67 | return list.size(); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter09/StringLengthComparator.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter09; 2 | 3 | import java.util.Comparator; 4 | 5 | /** 6 | * 7 | * @author Rogerio J. Gentil 8 | */ 9 | public class StringLengthComparator implements Comparator { 10 | 11 | /** 12 | * Compares two strings according to their lengths. 13 | * 14 | * @param s1 15 | * @param s2 16 | * @return 17 | */ 18 | @Override 19 | public int compare(String s1, String s2) { 20 | if (s1.length() < s2.length()) { 21 | return -1; 22 | } else if (s1.length() == s2.length()) { 23 | return 0; 24 | } else { 25 | return 1; 26 | } 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter09/UnsortedProrityQueue.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter09; 2 | 3 | import java.util.Comparator; 4 | import rogeriogentil.data.structures.chapter07.LinkedPositionalList; 5 | import rogeriogentil.data.structures.chapter07.Position; 6 | 7 | /** 8 | * An implementation of a priority queue with an unsorted list. 9 | * 10 | * @author Rogerio J. Gentil 11 | * @param 12 | * @param 13 | */ 14 | public class UnsortedProrityQueue extends AbstractPriorityQueue { 15 | 16 | private LinkedPositionalList> list = new LinkedPositionalList<>(); 17 | 18 | /** 19 | * Creates an empty priority queue based on the natural ordering of its keys. 20 | */ 21 | public UnsortedProrityQueue() { 22 | super(); 23 | } 24 | 25 | /** 26 | * Creates an empty priority queue using the given comparator to order keys 27 | * 28 | * @param c 29 | */ 30 | public UnsortedProrityQueue(Comparator c) { 31 | super(c); 32 | } 33 | 34 | /** 35 | * Returns the Position of an entry having minimal key. 36 | * 37 | * @return 38 | */ 39 | private Position> findMin() { 40 | Position> small = list.first(); 41 | 42 | for (Position> walk : list.positions()) { 43 | if (compare(walk.getElement(), walk.getElement()) < 0) { 44 | small = walk; 45 | } 46 | } 47 | 48 | return small; 49 | } 50 | 51 | /** 52 | * Inserts a key-value pair and returns the entry created. 53 | * 54 | * @param key 55 | * @param value 56 | * @return 57 | * @throws IllegalArgumentException 58 | */ 59 | @Override 60 | public Entry insert(K key, V value) throws IllegalArgumentException { 61 | checkKey(key); // auxiliary key-checking method (could throw exception) 62 | Entry newest = new PQEntry<>(key, value); 63 | list.addLast(newest); 64 | return newest; 65 | } 66 | 67 | /** 68 | * Returns (but does not remove) an entry with minimal key. 69 | * 70 | * @return 71 | */ 72 | @Override 73 | public Entry min() { 74 | if (list.isEmpty()) { 75 | return null; 76 | } 77 | 78 | Position> position = findMin(); 79 | return position.getElement(); 80 | } 81 | 82 | /** 83 | * Removes and returns an entry with minimal key. 84 | * 85 | * @return 86 | */ 87 | @Override 88 | public Entry removeMin() { 89 | if (list.isEmpty()) { 90 | return null; 91 | } 92 | 93 | Position> position = findMin(); 94 | Entry entry = list.remove(position); 95 | return entry; 96 | } 97 | 98 | @Override 99 | public int size() { 100 | return list.size(); 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter09/reinforcement/Exercise02.txt: -------------------------------------------------------------------------------- 1 | R-9.2 Suppose you set the key for each position p of a binary tree T equal to 2 | its preorder rank. Under what circumstances is T a heap? 3 | 4 | Answer 5 | ------ 6 | T is a heap when any parent position is lesser or equal the value position 7 | and it is a complete binary tree. 8 | 9 | Example 1 (proper and complete binary tree): 10 | 11 | 1 12 | 2 5 13 | 3 4 6 7 14 | 15 | 16 | Example 2 (proper and complete binary tree yet): 17 | 18 | 1 19 | 2 4 20 | 3 5 -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter09/reinforcement/Exercise03.txt: -------------------------------------------------------------------------------- 1 | R-9.3 What does each removeMin call return within the following sequence of priority 2 | queue ADT operations: insert(5, A), insert(4, B), insert(7, F), insert(1, D), 3 | removeMin( ), insert(3, J), insert(6, L), removeMin( ), 4 | removeMin( ), insert(8, G), removeMin( ), insert(2, H), removeMin( ), 5 | removeMin( )? 6 | 7 | Answer: 8 | ------ 9 | 10 | Operation Returned Priority Queue Contents 11 | insert(5, A) { (5,A) } 12 | insert(4, B) { (4,B), (5,A) } 13 | insert(7, F) { (4,B), (5,A), (7,F) } 14 | insert(1, D) { (1,D), (4,B), (5,A), (7,F) } 15 | removeMin( ) (1,D) { (4,B), (5,A), (7,F) } 16 | insert(3, J) { (3,J), (4,B), (5,A), (7,F) } 17 | insert(6, L) { (3,J), (4,B), (5,A), (6,L), (7,F) } 18 | removeMin( ) (3,J) { (4,B), (5,A), (6,L), (7,F) } 19 | removeMin( ) (4,B) { (5,A), (6,L), (7,F) } 20 | insert(8, G) { (5,A), (6,L), (7,F), (8,G) } 21 | removeMin( ) (5,A) { (6,L), (7,F), (8,G) } 22 | insert(2, H) { (2,H), (6,L), (7,F), (8,G) } 23 | removeMin( ) (2,H) { (6,L), (7,F), (8,G) } 24 | removeMin( ) (6,L) { (7,F), (8,G) } -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter09/reinforcement/Exercise07.txt: -------------------------------------------------------------------------------- 1 | R-9.7 Illustrate the execution of the selection-sort algorithm on the following 2 | input sequence: (22, 15, 36, 44, 10, 3, 9, 13, 29, 25). 3 | 4 | Answer: 5 | ------ 6 | 7 | 8 | Sequence Priority Queue 9 | Input (22, 15, 36, 44, 10, 3, 9, 13, 29, 25) () 10 | ------- 11 | Phase 1 12 | (15, 36, 44, 10, 3, 9, 13, 29, 25) (22) 13 | (36, 44, 10, 3, 9, 13, 29, 25) (22, 15) 14 | (44, 10, 3, 9, 13, 29, 25) (22, 15, 36) 15 | (10, 3, 9, 13, 29, 25) (22, 15, 36, 44) 16 | (3, 9, 13, 29, 25) (22, 15, 36, 44, 10) 17 | (9, 13, 29, 25) (22, 15, 36, 44, 10, 3) 18 | (13, 29, 25) (22, 15, 36, 44, 10, 3, 9) 19 | (29, 25) (22, 15, 36, 44, 10, 3, 9, 13) 20 | (25) (22, 15, 36, 44, 10, 3, 9, 13, 29) 21 | () (22, 15, 36, 44, 10, 3, 9, 13, 29, 25) 22 | ------- 23 | Phase 2 24 | (3) (22, 15, 36, 44, 10, 9, 13, 29, 25) 25 | (3, 9) (22, 15, 36, 44, 10, 13, 29, 25) 26 | (3, 9, 10) (22, 15, 36, 44, 13, 29, 25) 27 | (3, 9, 10, 13) (22, 15, 36, 44, 29, 25) 28 | (3, 9, 10, 13, 15) (22, 36, 44, 29, 25) 29 | (3, 9, 10, 13, 15, 22) (36, 44, 29, 25) 30 | (3, 9, 10, 13, 15, 22, 25) (36, 44, 29) 31 | (3, 9, 10, 13, 15, 22, 25, 29) (36, 44) 32 | (3, 9, 10, 13, 15, 22, 25, 29, 36) (44) 33 | (3, 9, 10, 13, 15, 22, 25, 29, 36, 44) () -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter09/reinforcement/Exercise08.txt: -------------------------------------------------------------------------------- 1 | R-9.8 Illustrate the execution of the insertion-sort algorithm on the input 2 | sequence of the previous problem. 3 | 4 | Answer: 5 | ------ 6 | 7 | 8 | Sequence Priority Queue 9 | Input (22, 15, 36, 44, 10, 3, 9, 13, 29, 25) () 10 | ------- 11 | Phase 1 12 | (15, 36, 44, 10, 3, 9, 13, 29, 25) (22) 13 | (36, 44, 10, 3, 9, 13, 29, 25) (15, 22) 14 | (44, 10, 3, 9, 13, 29, 25) (15, 22, 36) 15 | (10, 3, 9, 13, 29, 25) (15, 22, 36, 44) 16 | (3, 9, 13, 29, 25) (10, 15, 22, 36, 44) 17 | (9, 13, 29, 25) (3, 10, 15, 22, 36, 44) 18 | (13, 29, 25) (3, 9, 10, 15, 22, 36, 44) 19 | (29, 25) (3, 9, 10, 13, 15, 22, 36, 44) 20 | (25) (3, 9, 10, 13, 15, 22, 29, 36, 44) 21 | () (3, 9, 10, 13, 15, 22, 25, 29, 36, 44) 22 | ------- 23 | Phase 2 24 | (3) (9, 10, 13, 15, 22, 25, 29, 36, 44) 25 | (3, 9) (10, 13, 15, 22, 25, 29, 36, 44) 26 | (3, 9, 10) (13, 15, 22, 25, 29, 36, 44) 27 | (3, 9, 10, 13) (15, 22, 25, 29, 36, 44) 28 | (3, 9, 10, 13, 15) (22, 25, 29, 36, 44) 29 | (3, 9, 10, 13, 15, 22) (25, 29, 36, 44) 30 | (3, 9, 10, 13, 15, 22, 25) (29, 36, 44) 31 | (3, 9, 10, 13, 15, 22, 25, 29) (36, 44) 32 | (3, 9, 10, 13, 15, 22, 25, 29, 36) (44) 33 | (3, 9, 10, 13, 15, 22, 25, 29, 36, 44) () 34 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter09/reinforcement/Exercise17.txt: -------------------------------------------------------------------------------- 1 | R-9.17 Let H be a heap storing 15 entries using the array-based representation of a 2 | complete binary tree. What is the sequence of indices of the array that are visited 3 | in a preorder traversal of H? What about an inorder traversal of H? What about a 4 | postorder traversal of H? 5 | 6 | Answers 7 | ------- 8 | 9 | Heap H (example): 10 | 1 11 | 2 3 12 | 4 5 6 7 13 | 8 9 10 11 12 13 14 15 14 | 15 | Preorder: 1, 2, 4, 8, 9, 5, 10, 11, 3, 6, 12, 13, 7, 14, 15 16 | Inoder: 8, 4, 9, 2, 10, 5, 11, 1, 12, 6, 13, 3, 14, 7, 15 17 | Postorder: 8, 9, 4, 10, 11, 5, 2, 12, 13, 6, 14, 15, 7, 3, 1 -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter09/reinforcement/Exercise19.txt: -------------------------------------------------------------------------------- 1 | R-9.19 Bill claims that a preorder traversal of a heap will list its keys in nondecreasing 2 | order. Draw an example of a heap that proves him wrong. 3 | 4 | Answer: 5 | ------ 6 | Example based on Figure 9.4: 7 | 8 | 4 9 | 5 6 10 | 15 9 7 20 11 | 12 | Preorder traversal: 4, 5, 15, 9, 6, 7, 20 13 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter10/AbstractMap.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter10; 2 | 3 | import java.util.Iterator; 4 | import rogeriogentil.data.structures.chapter09.Entry; 5 | 6 | /** 7 | * 8 | * @author Rogerio J. Gentil 9 | * @param Key 10 | * @param Value 11 | */ 12 | public abstract class AbstractMap implements Map { 13 | 14 | //---------------- nested MapEntry class ---------------- 15 | protected static class MapEntry implements Entry { 16 | 17 | private K key; 18 | private V value; 19 | 20 | public MapEntry(K key, V value) { 21 | this.key = key; 22 | this.value = value; 23 | } 24 | 25 | @Override 26 | public K getKey() { 27 | throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. 28 | } 29 | 30 | @Override 31 | public V getvalue() { 32 | throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. 33 | } 34 | 35 | public void setKey(K key) { 36 | this.key = key; 37 | } 38 | 39 | public V setValue(V value) { 40 | V old = this.value; 41 | this.value = value; 42 | return old; 43 | } 44 | } 45 | //----------- end of nested MapEntry class ----------- 46 | 47 | // ---------- Key 48 | private class KeyIterator implements Iterator { 49 | 50 | private Iterator> entries = entrySet().iterator(); // reuse entrySet 51 | 52 | @Override 53 | public boolean hasNext() { 54 | return entries.hasNext(); 55 | } 56 | 57 | @Override 58 | public K next() { 59 | return entries.next().getKey(); // return key! 60 | } 61 | } 62 | 63 | private class KeyIterable implements Iterable { 64 | 65 | @Override 66 | public Iterator iterator() { 67 | return new KeyIterator(); 68 | } 69 | } 70 | 71 | @Override 72 | public Iterable keySet() { 73 | return new KeyIterable(); 74 | } 75 | 76 | // ---------- Value 77 | private class ValueIterator implements Iterator { 78 | 79 | private Iterator> entries = entrySet().iterator(); 80 | 81 | @Override 82 | public boolean hasNext() { 83 | return entries.hasNext(); 84 | } 85 | 86 | @Override 87 | public V next() { 88 | return entries.next().getvalue(); // return value! 89 | } 90 | } 91 | 92 | private class ValueIterable implements Iterable { 93 | 94 | @Override 95 | public Iterator iterator() { 96 | return new ValueIterator(); 97 | } 98 | } 99 | 100 | @Override 101 | public Iterable values() { 102 | return new ValueIterable(); 103 | } 104 | 105 | @Override 106 | public boolean isEmpty() { 107 | return this.size() == 0; 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter10/AbstractSortedMap.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014, Michael T. Goodrich, Roberto Tamassia, Michael H. Goldwasser 3 | * 4 | * Developed for use with the book: 5 | * 6 | * Data Structures and Algorithms in Java, Sixth Edition 7 | * Michael T. Goodrich, Roberto Tamassia, and Michael H. Goldwasser 8 | * John Wiley & Sons, 2014 9 | * 10 | * This program is free software: you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by 12 | * the Free Software Foundation, either version 3 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program. If not, see . 22 | */ 23 | package rogeriogentil.data.structures.chapter10; 24 | 25 | import java.util.Comparator; 26 | import rogeriogentil.data.structures.chapter09.DefaultComparator; 27 | import rogeriogentil.data.structures.chapter09.Entry; 28 | 29 | /** 30 | * An abstract base class to ease the implementation of the SortedMap interface. 31 | * 32 | * The base class provides four means of support: 33 | * 1) It defines a PQEntry class as a concrete implementation of the 34 | * entry interface 35 | * 2) It provides an instance variable for a general Comparator and 36 | * protected methods, compare(a, b), that can compare either two 37 | * entries or two keys using the comparator. 38 | * 3) It provides a boolean checkKey method that verifies that a given key 39 | * is appropriate for use with the comparator 40 | * 41 | * @author Michael T. Goodrich 42 | * @author Roberto Tamassia 43 | * @author Michael H. Goldwasser 44 | */ 45 | public abstract class AbstractSortedMap extends AbstractMap implements SortedMap { 46 | 47 | // instance variable for an AbstractSortedMap 48 | /** The comparator defining the ordering of keys in the map. */ 49 | private Comparator comp; 50 | 51 | /** 52 | * Initializes the comparator for the map. 53 | * @param c comparator defining the order of keys in the map 54 | */ 55 | protected AbstractSortedMap(Comparator c) { 56 | comp = c; 57 | } 58 | 59 | /** Initializes the map with a default comparator. */ 60 | protected AbstractSortedMap() { 61 | this(new DefaultComparator()); // default comparator uses natural ordering 62 | } 63 | 64 | /** Method for comparing two entries according to key */ 65 | protected int compare(Entry a, Entry b) { 66 | return comp.compare(a.getKey(), b.getKey()); 67 | } 68 | 69 | /** Method for comparing a key and an entry's key */ 70 | protected int compare(K a, Entry b) { 71 | return comp.compare(a, b.getKey()); 72 | } 73 | 74 | /** Method for comparing a key and an entry's key */ 75 | protected int compare(Entry a, K b) { 76 | return comp.compare(a.getKey(), b); 77 | } 78 | 79 | /** Method for comparing two keys */ 80 | protected int compare(K a, K b) { 81 | return comp.compare(a, b); 82 | } 83 | 84 | /** Determines whether a key is valid. */ 85 | protected boolean checkKey(K key) throws IllegalArgumentException { 86 | try { 87 | return (comp.compare(key,key)==0); // see if key can be compared to itself 88 | } catch (ClassCastException e) { 89 | throw new IllegalArgumentException("Incompatible key"); 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter10/Map.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter10; 2 | 3 | import rogeriogentil.data.structures.chapter09.Entry; 4 | 5 | /** 6 | * 7 | * @author Rogerio J. Gentil 8 | * @param K 9 | * @param V 10 | */ 11 | public interface Map { 12 | 13 | V get(K key); 14 | 15 | V put(K key, V value); 16 | 17 | V remove(K key); 18 | 19 | int size(); 20 | 21 | boolean isEmpty(); 22 | 23 | Iterable keySet(); 24 | 25 | Iterable values(); 26 | 27 | Iterable> entrySet(); 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter10/SortedMap.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014, Michael T. Goodrich, Roberto Tamassia, Michael H. Goldwasser 3 | * 4 | * Developed for use with the book: 5 | * 6 | * Data Structures and Algorithms in Java, Sixth Edition 7 | * Michael T. Goodrich, Roberto Tamassia, and Michael H. Goldwasser 8 | * John Wiley & Sons, 2014 9 | * 10 | * This program is free software: you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by 12 | * the Free Software Foundation, either version 3 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program. If not, see . 22 | */ 23 | package rogeriogentil.data.structures.chapter10; 24 | 25 | import rogeriogentil.data.structures.chapter09.Entry; 26 | 27 | /** 28 | * A map with additional support for keys from a total ordering. 29 | * 30 | * The total ordering is the natural ordering of keys, by default, 31 | * or it can be defined by providing an optional Comparator. 32 | * 33 | * All iterations will be in sorted order relative to the keys, 34 | * and additional methods provide for non-exact searches. 35 | * This interface is a simple variant that blends features of 36 | * java.util.SortedMap and java.util.NavigableMap. 37 | * 38 | * @author Michael T. Goodrich 39 | * @author Roberto Tamassia 40 | * @author Michael H. Goldwasser 41 | */ 42 | public interface SortedMap extends Map{ 43 | 44 | /** 45 | * Returns the entry having the least key (or null if map is empty). 46 | * @return entry with least key (or null if map is empty) 47 | */ 48 | Entry firstEntry(); 49 | 50 | /** 51 | * Returns the entry having the greatest key (or null if map is empty). 52 | * @return entry with greatest key (or null if map is empty) 53 | */ 54 | Entry lastEntry(); 55 | 56 | /** 57 | * Returns the entry with least key greater than or equal to given key 58 | * (or null if no such key exists). 59 | * @return entry with least key greater than or equal to given (or null if no such entry) 60 | * @throws IllegalArgumentException if the key is not compatible with the map 61 | */ 62 | Entry ceilingEntry(K key) throws IllegalArgumentException; 63 | 64 | /** 65 | * Returns the entry with greatest key less than or equal to given key 66 | * (or null if no such key exists). 67 | * @return entry with greatest key less than or equal to given (or null if no such entry) 68 | * @throws IllegalArgumentException if the key is not compatible with the map 69 | */ 70 | Entry floorEntry(K key) throws IllegalArgumentException; 71 | 72 | /** 73 | * Returns the entry with greatest key strictly less than given key 74 | * (or null if no such key exists). 75 | * @return entry with greatest key strictly less than given (or null if no such entry) 76 | * @throws IllegalArgumentException if the key is not compatible with the map 77 | */ 78 | Entry lowerEntry(K key) throws IllegalArgumentException; 79 | 80 | /** 81 | * Returns the entry with least key strictly greater than given key 82 | * (or null if no such key exists). 83 | * @return entry with least key strictly greater than given (or null if no such entry) 84 | * @throws IllegalArgumentException if the key is not compatible with the map 85 | */ 86 | Entry higherEntry(K key) throws IllegalArgumentException; 87 | 88 | /** 89 | * Returns an iterable containing all keys in the range from 90 | * fromKey inclusive to toKey exclusive. 91 | * @return iterable with keys in desired range 92 | * @throws IllegalArgumentException if fromKey or toKey is not compatible with the map 93 | */ 94 | Iterable> subMap(K fromKey, K toKey) throws IllegalArgumentException; 95 | } 96 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter10/UnsortedTableMap.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter10; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Iterator; 5 | import java.util.NoSuchElementException; 6 | import rogeriogentil.data.structures.chapter09.Entry; 7 | 8 | /** 9 | * 10 | * @author Rogerio J. Gentil 11 | * @param Key 12 | * @param Value 13 | */ 14 | public class UnsortedTableMap extends AbstractMap { 15 | 16 | private ArrayList> table = new ArrayList<>(); 17 | 18 | public UnsortedTableMap() { 19 | } 20 | 21 | // -------------- private utility --------------- 22 | /** 23 | * Returns the index of an entry with equal key, or −1 if none found. 24 | * 25 | * @param key 26 | * @return 27 | */ 28 | private int findIndex(K key) { 29 | int n = table.size(); 30 | 31 | for (int i = 0; i < n; i++) { 32 | if (table.get(i).getKey().equals(key)) { 33 | return i; 34 | } 35 | } 36 | 37 | return -1; // special value denotes that key was not found 38 | } 39 | 40 | @Override 41 | public int size() { 42 | return table.size(); 43 | } 44 | 45 | /** 46 | * Returns the value associated with the specified key (or else null). 47 | * 48 | * @param key 49 | * @return 50 | */ 51 | @Override 52 | public V get(K key) { 53 | int index = this.findIndex(key); 54 | 55 | if (index == -1) { 56 | return null; // not found 57 | } 58 | 59 | return table.get(index).getvalue(); 60 | } 61 | 62 | /** 63 | * Associates given value with given key, replacing a previous value (if 64 | * any) 65 | * 66 | * @param key 67 | * @param value 68 | * @return 69 | */ 70 | @Override 71 | public V put(K key, V value) { 72 | int index = this.findIndex(key); 73 | 74 | if (index == -1) { 75 | table.add(new MapEntry<>(key, value)); 76 | return null; // not found 77 | } else { 78 | V old = table.get(index).getvalue(); 79 | table.get(index).setValue(value); 80 | return old; 81 | } 82 | } 83 | 84 | /** 85 | * Removes the entry with the specified key (if any) and returns its value. 86 | * 87 | * @param key 88 | * @return 89 | */ 90 | @Override 91 | public V remove(K key) { 92 | int index = this.findIndex(key); 93 | int n = table.size(); 94 | 95 | if (index == -1) { 96 | return null; // not found 97 | } 98 | 99 | V value = table.get(index).getvalue(); 100 | 101 | if (index != n - 1) { 102 | table.set(index, table.get(n - 1)); // relocate last entry to ’hole’ created by removal 103 | } 104 | 105 | table.remove(n - 1); // remove last entry of table 106 | return value; 107 | } 108 | 109 | /** 110 | * Returns an iterable collection of all key-value entries of the map. 111 | * 112 | * @return 113 | */ 114 | @Override 115 | public Iterable> entrySet() { 116 | return new EntryIterable(); 117 | } 118 | 119 | // Support for public entrySet method (above) 120 | private class EntryIterator implements Iterator> { 121 | 122 | private int j = 0; 123 | 124 | @Override 125 | public boolean hasNext() { 126 | return j < table.size(); 127 | } 128 | 129 | @Override 130 | public Entry next() { 131 | if (j == table.size()) { 132 | throw new NoSuchElementException(); 133 | } 134 | 135 | return table.get(j++); 136 | } 137 | } 138 | 139 | private class EntryIterable implements Iterable> { 140 | 141 | @Override 142 | public Iterator> iterator() { 143 | return new EntryIterator(); 144 | } 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter11/AVLTreeMap.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter11; 2 | 3 | import java.util.Comparator; 4 | import rogeriogentil.data.structures.chapter07.Position; 5 | import rogeriogentil.data.structures.chapter09.Entry; 6 | 7 | /** 8 | * An implementation of a sorted map using an AVL tree. 9 | * 10 | * @author Rogerio J. Gentil 11 | * @param Key 12 | * @param Value 13 | */ 14 | public class AVLTreeMap extends TreeMap { 15 | 16 | public AVLTreeMap() { 17 | } 18 | 19 | public AVLTreeMap(Comparator comp) { 20 | super(comp); 21 | } 22 | 23 | protected int height(Position> position) { 24 | return tree.getAux(position); 25 | } 26 | 27 | /** 28 | * Recomputes the height of the given position based on its children's heights. 29 | * 30 | * @param position 31 | */ 32 | protected void recomputeHeight(Position> position) { 33 | tree.setAux(position, 1 + Math.max(height(left(position)), height(right(position)))); 34 | } 35 | 36 | /** 37 | * Returns whether a position has balance factor between −1 and 1 inclusive. 38 | * 39 | * @param position 40 | * @return 41 | */ 42 | protected boolean isBalacend(Position> position) { 43 | return Math.abs(height(left(position)) - height(right(position))) <= 1; 44 | } 45 | 46 | /** 47 | * Returns a child of p with height no smaller than that of the other child. 48 | * 49 | * @param position 50 | * @return 51 | */ 52 | protected Position> tallerChild(Position> position) { 53 | if (height(left(position)) > height(right(position))) { 54 | return left(position); 55 | } 56 | 57 | if (height(left(position)) < height(right(position))) { 58 | return right(position); 59 | } 60 | 61 | // equal height children; break tie while matching parent's orientation 62 | if (isRoot(position)) { // choice is irrelevant 63 | return left(position); // return aligned child 64 | } else { 65 | return right(position); 66 | } 67 | } 68 | 69 | /** 70 | * Utility used to rebalance after an insert or removal operation. This traverses the path upward from position, 71 | * performing a trinode restructuring when imbalance is found, continuing until balance is restored. 72 | * 73 | * @param position 74 | */ 75 | protected void rebalance(Position> position) { 76 | int oldHeight, newHeight; 77 | do { 78 | oldHeight = height(position); // not yet recalculated if internal 79 | if (!isBalacend(position)) { // imbalance detected 80 | 81 | /* 82 | perform trinode restructuring, setting position to resulting root, 83 | and recompute new local heights after the restructuring. 84 | */ 85 | position = restructure(tallerChild(tallerChild(position))); 86 | recomputeHeight(left(position)); 87 | recomputeHeight(right(position)); 88 | } 89 | 90 | recomputeHeight(position); 91 | newHeight = height(position); 92 | position = parent(position); 93 | } while (oldHeight != newHeight && position != null); 94 | } 95 | 96 | /** 97 | * Overrides the TreeMap rebalancing hook that is called after an insertion. 98 | * 99 | * @param position 100 | */ 101 | @Override 102 | protected void rebalanceInsert(Position> position) { 103 | rebalance(position); 104 | } 105 | 106 | /** 107 | * Overrides the TreeMap rebalancing hook that is called after a deletion. 108 | * 109 | * @param position 110 | */ 111 | @Override 112 | protected void rebalanceDelete(Position> position) { 113 | rebalance(position); 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter11/SplayTreeMap.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter11; 2 | 3 | import java.util.Comparator; 4 | import rogeriogentil.data.structures.chapter07.Position; 5 | import rogeriogentil.data.structures.chapter09.Entry; 6 | 7 | /** 8 | * An implementation of a sorted map using a splay tree. 9 | * 10 | * @author Rogerio J. Gentil 11 | * @param Key 12 | * @param Value 13 | */ 14 | public class SplayTreeMap extends TreeMap { 15 | 16 | public SplayTreeMap() { 17 | } 18 | 19 | public SplayTreeMap(Comparator comp) { 20 | super(comp); 21 | } 22 | 23 | /** 24 | * Utility used to rebalance after a map operation. 25 | * 26 | * @param position 27 | */ 28 | private void splay(Position> position) { 29 | while (!isRoot(position)) { 30 | Position> parent = parent(position); 31 | Position> grand = parent(parent); 32 | 33 | if (grand == null) { // zig case 34 | rotate(position); 35 | } else if ((parent == left(grand)) == (position == left(parent))) { // zig-zig case 36 | rotate(parent); // move PARENT upward 37 | rotate(position); // then move position upward 38 | } else { // zig-zag case 39 | rotate(position); // move p upward 40 | rotate(position); // move p upward again 41 | } 42 | } 43 | } 44 | 45 | // override the various TreeMap rebalancing hooks to perform the appropriate splay 46 | @Override 47 | protected void rebalanceAccess(Position> position) { 48 | if (isExternal(position)) { 49 | position = parent(position); 50 | } 51 | 52 | if (position != null) { 53 | splay(position); 54 | } 55 | } 56 | 57 | @Override 58 | protected void rebalanceInsert(Position> position) { 59 | splay(position); 60 | } 61 | 62 | @Override 63 | protected void rebalanceDelete(Position> position) { 64 | if (!isRoot(position)) { 65 | splay(parent(position)); 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter11/reinforcement/Exercise01.txt: -------------------------------------------------------------------------------- 1 | R-11.1 If we insert the entries (1, A), (2, B), (3, C), (4, D), and (5, E), in this order, 2 | into an initially empty binary search tree, what will it look like? 3 | 4 | 1st Insertion -> (1, A) 5 | ============ 6 | (1, A) 7 | 8 | 2nd Insertion -> (2, B) 9 | ============ 10 | (1, A) 11 | \ 12 | (2, B) 13 | 14 | 3rd Insertion -> (3, C) 15 | ============ 16 | (1, A) 17 | \ 18 | (2, B) 19 | \ 20 | (3, C) 21 | 22 | 4th Insertion -> (4, D) 23 | ============ 24 | (1, A) 25 | \ 26 | (2, B) 27 | \ 28 | (3, C) 29 | \ 30 | (4, D) 31 | 32 | 5th (and final) Insertion -> (5, E) 33 | ========================= 34 | (1, A) 35 | \ 36 | (2, B) 37 | \ 38 | (3, C) 39 | \ 40 | (4, D) 41 | \ 42 | (5, E) -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter11/reinforcement/Exercise02.txt: -------------------------------------------------------------------------------- 1 | R-11.2 Insert, into an empty binary search tree, entries with keys 30, 40, 24, 2 | 58, 48, 26, 11, 13 (in this order). Draw the tree after each insertion. 3 | 4 | 1st Insertion -> 30 5 | ============= 6 | 30 7 | 8 | 2nd Insertion -> 40 9 | ============= 10 | 30 11 | \ 12 | 40 13 | 14 | 3rd Insertion -> 24 15 | ============= 16 | 30 17 | / \ 18 | 24 40 19 | 20 | 4th Insertion -> 58 21 | ============= 22 | 30 23 | / \ 24 | 24 40 25 | \ 26 | 58 27 | 28 | 5th Insertion -> 48 29 | ============= 30 | 30 31 | / \ 32 | 24 40 33 | \ 34 | 58 35 | / 36 | 48 37 | 38 | 6th Insertion -> 26 39 | ============= 40 | 30 41 | / \ 42 | 24 40 43 | \ \ 44 | 26 58 45 | / 46 | 48 47 | 48 | 7th Insertion -> 11 49 | ============= 50 | 30 51 | / \ 52 | 24 40 53 | / \ \ 54 | 11 26 58 55 | / 56 | 48 57 | 58 | 8th Insertion -> 13 59 | ============= 60 | 30 61 | / \ 62 | 24 40 63 | / \ \ 64 | 11 26 58 65 | \ / 66 | 13 48 -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter11/reinforcement/Exercise03.txt: -------------------------------------------------------------------------------- 1 | R-11.3 How many different binary search trees can store the keys {1, 2, 3}? 2 | 3 | - 1st sequence insertion: {1, 2, 3} 4 | Result: 5 | 1 6 | \ 7 | 2 8 | \ 9 | 3 10 | 11 | - 2nd sequence insertion: {2, 1, 3} 12 | Result: 13 | 2 14 | / \ 15 | 1 3 16 | 17 | - 3rd sequence insertion: {3, 1, 2} 18 | Result: 19 | 3 20 | / 21 | 1 22 | \ 23 | 2 24 | 25 | - 4th sequence insertion: {3, 2, 1} 26 | Result: 27 | 3 28 | / 29 | 2 30 | / 31 | 1 32 | 33 | - 5th sequence insertion: {1, 3, 2} 34 | Result: 35 | 1 36 | \ 37 | 3 38 | / 39 | 2 40 | 41 | - 6th sequence insertion: {2, 3, 1} 42 | Result (identical to the 2nd): 43 | 2 44 | / \ 45 | 1 3 46 | 47 | Answer: 48 | ====== 49 | 5 different binary search tree can store the keys {1, 2, 3} -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter11/reinforcement/Exercise04.txt: -------------------------------------------------------------------------------- 1 | R-11.4 Dr. Amongus claims that the order in which a fixed set of entries is inserted 2 | into a binary search tree does not matter—the same tree results every time. Give a 3 | small example that proves he is wrong. 4 | 5 | Answer: 6 | ====== 7 | Given a set of keys: 8 | {1, 2, 3} 9 | 10 | Given two insertion sequences: 11 | 1st -> 1, 2, 3 12 | 2nd -> 3, 2, 1 13 | 14 | The respective results are: 15 | 16 | 1st 17 | --- 18 | 1 19 | \ 20 | 2 21 | \ 22 | 3 23 | 24 | 2nd 25 | --- 26 | 3 27 | / 28 | 2 29 | / 30 | 1 31 | 32 | It is possible notice that both results are different. -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter11/reinforcement/Exercise05.txt: -------------------------------------------------------------------------------- 1 | R-11.5 Dr. Amongus claims that the order in which a fixed set of entries is inserted 2 | into an AVL tree does not matter—the same AVL tree results every time. Give a small 3 | example that proves he is wrong. 4 | 5 | Answer: 6 | ====== 7 | Given a set of keys: 8 | {1, 2, 3, 4} 9 | 10 | Given two insertion sequences: 11 | 1st -> 1, 2, 3, 4 12 | 2nd -> 4, 3, 2, 1 13 | 14 | The respective results are: 15 | 1st 16 | --- 17 | 2 18 | / \ 19 | 1 3 20 | \ 21 | 4 22 | 23 | 2nd 24 | --- 25 | 3 26 | / \ 27 | 2 4 28 | / 29 | 1 30 | 31 | It is possible notice that both results are different. -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter11/reinforcement/Exercise08.txt: -------------------------------------------------------------------------------- 1 | R-11.8 Draw the AVL tree resulting from the insertion of an entry with key 52 2 | into the AVL tree of Figure 11.13b. 3 | 4 | Answer: 5 | ====== 6 | Figure 11.13b: 7 | 8 | 62 9 | / \ 10 | 44 78 11 | / \ \ 12 | 17 50 88 13 | / \ 14 | 48 54 15 | 16 | 17 | Insertion of the entry with key 52 (violation of the height-balance property: the 18 | heights of the children > 1): 19 | 20 | 62 21 | / \ 22 | 44 78 23 | / \ \ 24 | 17 50 88 25 | / \ 26 | 48 54 27 | / 28 | 52 29 | 30 | Trinode restructuring notation (a = z, b = y, c = x): 31 | 32 | 62 33 | z / \ 34 | 44 78 35 | / \ y \ 36 | 17 50 88 37 | / \ x 38 | 48 54 39 | / 40 | 52 41 | 42 | After Single Rotate Left (final result): 43 | 44 | 62 45 | y / \ 46 | 50 78 47 | z / \ x \ 48 | 44 54 88 49 | / \ / 50 | 17 48 52 51 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter11/reinforcement/Exercise09.txt: -------------------------------------------------------------------------------- 1 | R-11.9 Draw the AVL tree resulting from the removal of the entry with key 62 2 | from the AVL tree of Figure 11.13b. 3 | 4 | Answer: 5 | ====== 6 | Figure 11.13b: 7 | 8 | 62 9 | / \ 10 | 44 78 11 | / \ \ 12 | 17 50 88 13 | / \ 14 | 48 54 15 | 16 | 17 | Final result (delete node and replace with largest node in left tree): 18 | 19 | 54 20 | / \ 21 | 44 78 22 | / \ \ 23 | 17 50 88 24 | / 25 | 48 -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter11/reinforcement/Exercise14.txt: -------------------------------------------------------------------------------- 1 | R-11.14 What does a splay tree look like if its entries are accessed in 2 | increasing order by their keys? 3 | 4 | Answer: 5 | ====== 6 | 7 | Given a ordered access sequence in a Splay Tree, the result is a degenerate tree 8 | in decreasing order. 9 | 10 | K - N 11 | / 12 | ... 13 | / 14 | K - 1 15 | / 16 | K 17 | 18 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter11/reinforcement/Exercise17.txt: -------------------------------------------------------------------------------- 1 | R-11.17 Is the search tree of Figure 11.22(a) a (2, 4) tree? Why or why not? 2 | 3 | Answer: 4 | ====== 5 | 22 6 | / \ 7 | / \ 8 | 5 10 25 9 | / | \ / \ 10 | / | \ / \ 11 | 3 4 6 8 14 23 24 27 12 | / \ 13 | / \ 14 | 11 13 17 15 | 16 | Despite all internal nodes have at most four children, this search tree isn't 17 | a (2, 4) tree because not all external nodes have the same depth. -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter12/QuickSort.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter12; 2 | 3 | import java.util.Comparator; 4 | import rogeriogentil.data.structures.chapter06.LinkedQueue; 5 | import rogeriogentil.data.structures.chapter06.Queue; 6 | 7 | /** 8 | * 9 | * @author Rogerio J. Gentil 10 | */ 11 | public class QuickSort { 12 | 13 | /** 14 | * Quick-sort contents of a queue. 15 | * 16 | * @param 17 | * @param S 18 | * @param comp 19 | */ 20 | public static void quickSort(Queue S, Comparator comp) { 21 | int n = S.size(); 22 | 23 | if (n < 2) { 24 | return; 25 | } 26 | 27 | // divide 28 | K pivot = S.first(); // using first as arbitrary pivot 29 | 30 | Queue L = new LinkedQueue<>(); 31 | Queue E = new LinkedQueue<>(); 32 | Queue G = new LinkedQueue<>(); 33 | 34 | while (!S.isEmpty()) { 35 | K element = S.dequeue(); // divide original into L, E, and G 36 | 37 | int comparation = comp.compare(element, pivot); 38 | 39 | if (comparation < 0) { 40 | L.enqueue(element); // element is less than pivot 41 | } else if (comparation == 0) { 42 | E.enqueue(element); // element is equal to pivot 43 | } else { 44 | G.enqueue(element); // element is greater than pivot 45 | } 46 | } 47 | 48 | // conquer 49 | quickSort(L, comp); // sort elements less than pivot 50 | quickSort(G, comp); // sort elements greater than pivot 51 | 52 | // concatenate results 53 | while (!L.isEmpty()) { 54 | S.enqueue(L.dequeue()); 55 | } 56 | 57 | while (!E.isEmpty()) { 58 | S.enqueue(E.dequeue()); 59 | } 60 | 61 | while (!G.isEmpty()) { 62 | S.enqueue(G.dequeue()); 63 | } 64 | } 65 | 66 | /** 67 | * Sort the subarray S[a..b] inclusive. The entire array can be sorted as 68 | * {@code quickSortInPlace(S, comp, 0, S.length−1)}. 69 | * 70 | * @param 71 | * @param S 72 | * @param comp 73 | * @param a 74 | * @param b 75 | */ 76 | public static void quickSortInPlace(K[] S, Comparator comp, int a, int b) { 77 | if (a >= b) { 78 | return; 79 | } 80 | 81 | int left = a; 82 | int right = b - 1; 83 | 84 | K pivot = S[b]; 85 | K temp; // temp object used for swapping 86 | 87 | while (left <= right) { 88 | // scan until reaching value equal or larger than pivot (or right marker) 89 | while (left <= right && comp.compare(S[left], pivot) < 0) { 90 | left++; 91 | } 92 | 93 | // scan until reaching value equal or smaller than pivot (or left marker) 94 | while (left <= right && comp.compare(S[right], pivot) > 0) { 95 | right--; 96 | } 97 | 98 | if (left <= right) { // indices did not strictly cross 99 | // so swap values and shrink range 100 | temp = S[left]; 101 | S[left] = S[right]; 102 | S[right] = temp; 103 | left++; 104 | right--; 105 | } 106 | } 107 | 108 | // put pivot into its final place (currently marked by left index) 109 | temp = S[left]; 110 | S[left] = S[b]; 111 | S[b] = temp; 112 | 113 | quickSortInPlace(S, comp, a, left - 1); 114 | quickSortInPlace(S, comp, left + 1, b); 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter12/reinforcement/Exercise01.txt: -------------------------------------------------------------------------------- 1 | R-12.1 Give a complete justification of Proposition 12.1. 2 | 3 | Answer: 4 | ====== 5 | 6 | Proposition 12.1: The merge-sort tree associated with an execution of merge-sort 7 | on a sequence of size n has height ⌈log n⌉ . 8 | 9 | As the merge-sort algorithm divide the input size into two halves to every call, 10 | thereby: 11 | 12 | - in the case in which n is a power of 2 13 | 1st call -> n = n/2^0 14 | 2nd call -> n/2 = n/2^1 15 | 3rd call -> n/4 = n/2^2 16 | 4th call -> n/8 = n/2^3 17 | ... 18 | last call -> n/n = n/2^i 19 | 20 | Consider 21 | n = 2^i <=> log n = i 22 | 23 | where i is the height of the merge-sort tree associated. 24 | 25 | - in the case in wich n is not a power of 2, the height approximates of log n. 26 | Therefore, the height will be bounded. -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter12/reinforcement/Exercise02.txt: -------------------------------------------------------------------------------- 1 | R-12.2 In the merge-sort tree shown in Figures 12.2 through 12.4, some 2 | edges are drawn as arrows. What is the meaning of a downward arrow? How 3 | about an upward arrow? 4 | 5 | Answer: 6 | ====== 7 | 8 | The downward arrow meaning that the input data are being divided until a 9 | lower fraction and the upward arrow indicates that the subsets are being 10 | merged into a larger subsets until turn up a only ordered data set. -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter12/reinforcement/Exercise04.txt: -------------------------------------------------------------------------------- 1 | R-12.4 Is our array-based implementation of merge-sort given in Section 12.1.2 2 | stable? Explain why or why not. 3 | 4 | Answer: 5 | ====== 6 | 7 | No, the array-based implementation of merge-sort given in Section 12.1.2 isn't 8 | stable because when two key with same values are compared the condition result 9 | 0 (zero). So, the posterior element is first stored in S. 10 | 11 | // S2[j] is stored before S1[i] in S when they have same value 12 | if (j == S2.length || (i < S1.length && comp.compare(S1[i], S2[j]) < 0)) { 13 | S[i+j] = S1[i++]; 14 | } else { 15 | S[i+j] = S2[j++]; 16 | } 17 | 18 | Example: 19 | ------- 20 | Given: 21 | i0 i1 22 | S1: | 6 | 7 | (S1 last level before last merge) 23 | 24 | j0 j1 25 | S2: | 3 | 6 | (S2 last level before last merge) 26 | 27 | Merge results: 28 | j0 j1 i0 i1 29 | S: | 3 | 6 | 6 | 7 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter12/reinforcement/Exercise05.txt: -------------------------------------------------------------------------------- 1 | R-12.5 Is our linked-list-based implementation of merge-sort (Code Fragment 12.3) 2 | stable? Explain why or why not. 3 | 4 | Answer: 5 | ====== 6 | 7 | No, the linked-list-based implementation of merge-sort given in Code Fragment 8 | 12.3 isn't stable because the compartion of two keys with same values results 9 | 0 (zero). So, the posterior element is first stored in S. 10 | 11 | // S2.first() is queued before S1.first() in S when they have same value 12 | if (comp.compare(S1.first(), S2.first()) < 0) { 13 | S.enqueue(S1.dequeue()); 14 | } else { 15 | S.enqueue(S2.dequeue()); 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter14/Edge.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014, Michael T. Goodrich, Roberto Tamassia, Michael H. Goldwasser 3 | * 4 | * Developed for use with the book: 5 | * 6 | * Data Structures and Algorithms in Java, Sixth Edition 7 | * Michael T. Goodrich, Roberto Tamassia, and Michael H. Goldwasser 8 | * John Wiley & Sons, 2014 9 | * 10 | * This program is free software: you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by 12 | * the Free Software Foundation, either version 3 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program. If not, see . 22 | */ 23 | //package net.datastructures; 24 | package rogeriogentil.data.structures.chapter14; 25 | 26 | /** 27 | * An edge of a graph. 28 | * 29 | * @author Michael T. Goodrich 30 | * @author Roberto Tamassia 31 | * @author Michael H. Goldwasser 32 | */ 33 | public interface Edge { 34 | /** Returns the element associated with the edge. */ 35 | E getElement(); 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter14/Graph.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014, Michael T. Goodrich, Roberto Tamassia, Michael H. Goldwasser 3 | * 4 | * Developed for use with the book: 5 | * 6 | * Data Structures and Algorithms in Java, Sixth Edition 7 | * Michael T. Goodrich, Roberto Tamassia, and Michael H. Goldwasser 8 | * John Wiley & Sons, 2014 9 | * 10 | * This program is free software: you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by 12 | * the Free Software Foundation, either version 3 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program. If not, see . 22 | */ 23 | //package net.datastructures; 24 | package rogeriogentil.data.structures.chapter14; 25 | 26 | /** 27 | * An interface for a graph structure. A graph can be declared as either directed or undirected. 28 | * In the case of an undirected graph, methods outgoingEdges and incomingEdges return the same collection, 29 | * and outDegree and inDegree return the same value. 30 | * 31 | * Every vertex stores an element of type V (possibly null). 32 | * Every edge stores an element of type E (possibly null). 33 | * 34 | * @author Michael T. Goodrich 35 | * @author Roberto Tamassia 36 | * @author Michael H. Goldwasser 37 | */ 38 | public interface Graph { 39 | 40 | /** Returns the number of vertices of the graph */ 41 | int numVertices(); 42 | 43 | /** Returns the number of edges of the graph */ 44 | int numEdges(); 45 | 46 | /** Returns the vertices of the graph as an iterable collection */ 47 | Iterable> vertices(); 48 | 49 | /** Returns the edges of the graph as an iterable collection */ 50 | Iterable> edges(); 51 | 52 | /** 53 | * Returns the number of edges leaving vertex v. 54 | * Note that for an undirected graph, this is the same result 55 | * returned by inDegree 56 | * @throws IllegalArgumentException if v is not a valid vertex 57 | */ 58 | int outDegree(Vertex v) throws IllegalArgumentException; 59 | 60 | /** 61 | * Returns the number of edges for which vertex v is the destination. 62 | * Note that for an undirected graph, this is the same result 63 | * returned by outDegree 64 | * @throws IllegalArgumentException if v is not a valid vertex 65 | */ 66 | int inDegree(Vertex v) throws IllegalArgumentException; 67 | 68 | /** 69 | * Returns an iterable collection of edges for which vertex v is the origin. 70 | * Note that for an undirected graph, this is the same result 71 | * returned by incomingEdges. 72 | * @throws IllegalArgumentException if v is not a valid vertex 73 | */ 74 | Iterable> outgoingEdges(Vertex v) throws IllegalArgumentException; 75 | 76 | /** 77 | * Returns an iterable collection of edges for which vertex v is the destination. 78 | * Note that for an undirected graph, this is the same result 79 | * returned by outgoingEdges. 80 | * @throws IllegalArgumentException if v is not a valid vertex 81 | */ 82 | Iterable> incomingEdges(Vertex v) throws IllegalArgumentException; 83 | 84 | /** Returns the edge from u to v, or null if they are not adjacent. */ 85 | Edge getEdge(Vertex u, Vertex v) throws IllegalArgumentException; 86 | 87 | /** 88 | * Returns the vertices of edge e as an array of length two. 89 | * If the graph is directed, the first vertex is the origin, and 90 | * the second is the destination. If the graph is undirected, the 91 | * order is arbitrary. 92 | */ 93 | Vertex[] endVertices(Edge e) throws IllegalArgumentException; 94 | 95 | /** Returns the vertex that is opposite vertex v on edge e. */ 96 | Vertex opposite(Vertex v, Edge e) throws IllegalArgumentException; 97 | 98 | /** Inserts and returns a new vertex with the given element. */ 99 | Vertex insertVertex(V element); 100 | 101 | /** 102 | * Inserts and returns a new edge between vertices u and v, storing given element. 103 | * 104 | * @throws IllegalArgumentException if u or v are invalid vertices, or if an edge already exists between u and v. 105 | */ 106 | Edge insertEdge(Vertex u, Vertex v, E element) throws IllegalArgumentException; 107 | 108 | /** Removes a vertex and all its incident edges from the graph. */ 109 | void removeVertex(Vertex v) throws IllegalArgumentException; 110 | 111 | /** Removes an edge from the graph. */ 112 | void removeEdge(Edge e) throws IllegalArgumentException; 113 | } 114 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter14/GraphTraversals.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter14; 2 | 3 | import java.util.HashSet; 4 | import java.util.Set; 5 | import rogeriogentil.data.structures.chapter07.LinkedPositionalList; 6 | import rogeriogentil.data.structures.chapter07.PositionalList; 7 | import rogeriogentil.data.structures.chapter10.Map; 8 | import rogeriogentil.data.structures.chapter10.UnsortedTableMap; 9 | 10 | /** 11 | * 12 | * @author Rogerio J. Gentil 13 | * @param Vertex 14 | * @param Edge 15 | */ 16 | public class GraphTraversals { 17 | 18 | /** 19 | * Performs depth-first search (DFS) of graph starting at vertex u. 20 | * 21 | * @param 22 | * @param 23 | * @param graph 24 | * @param u 25 | * @param known 26 | * @param forest 27 | */ 28 | public static void DFS(Graph graph, Vertex u, Set> known, Map, Edge> forest) { 29 | known.add(u); // u has been discovered 30 | 31 | for (Edge e : graph.outgoingEdges(u)) { 32 | Vertex v = graph.opposite(u, e); 33 | 34 | if (!known.contains(v)) { 35 | forest.put(v, e); // e is the tree edge that discovered v 36 | DFS(graph, v, known, forest); 37 | } 38 | } 39 | } 40 | 41 | /** 42 | * Returns an ordered list of edges comprising the directed path from u to 43 | * v. 44 | * 45 | * @param 46 | * @param 47 | * @param graph 48 | * @param u 49 | * @param v 50 | * @param forest 51 | * @return 52 | */ 53 | public static PositionalList> constructPath(Graph graph, 54 | Vertex u, Vertex v, Map, Edge> forest) { 55 | PositionalList> path = new LinkedPositionalList<>(); 56 | 57 | if (forest.get(v) != null) { // v was discovered during the search 58 | Vertex walk = v; // we construct the path from back to front 59 | 60 | while (walk != u) { 61 | Edge edge = forest.get(walk); 62 | path.addFirst(edge); // add edge to *front* of path 63 | walk = graph.opposite(walk, edge); 64 | } 65 | } 66 | 67 | return path; 68 | } 69 | 70 | /** 71 | * Performs DFS for the entire graph and returns the DFS forest as a map. 72 | * 73 | * @param 74 | * @param 75 | * @param graph 76 | * @return 77 | */ 78 | public static Map, Edge> DFSComplete(Graph graph) { 79 | Set> known = new HashSet<>(); 80 | Map, Edge> forest = new UnsortedTableMap<>(); // TODO: change by ProbeHashMap - cap 10 81 | for (Vertex u : graph.vertices()) { 82 | if (!known.contains(u)) { 83 | DFS(graph, u, known, forest); // (re)start the DFS process at u 84 | } 85 | } 86 | 87 | return forest; 88 | } 89 | 90 | /** 91 | * Performs breadth-first search (BFS) of graph starting at Vertex s. 92 | * 93 | * @param 94 | * @param 95 | * @param graph 96 | * @param s 97 | * @param known 98 | * @param forest 99 | */ 100 | public static void BFS(Graph graph, Vertex s, Set> known, Map, Edge> forest) { 101 | PositionalList> level = new LinkedPositionalList<>(); 102 | 103 | known.add(s); 104 | level.addLast(s); // first level includes only s 105 | 106 | while (!level.isEmpty()) { 107 | PositionalList> nextLevel = new LinkedPositionalList<>(); 108 | 109 | for (Vertex u : level) { 110 | for (Edge e : graph.outgoingEdges(s)) { 111 | Vertex v = graph.opposite(s, e); 112 | 113 | if (!known.contains(v)) { 114 | known.add(v); 115 | forest.put(v, e); // e is the tree edge that discovered v 116 | nextLevel.addLast(v); 117 | } 118 | } 119 | } 120 | 121 | level = nextLevel; 122 | } 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter14/Vertex.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014, Michael T. Goodrich, Roberto Tamassia, Michael H. Goldwasser 3 | * 4 | * Developed for use with the book: 5 | * 6 | * Data Structures and Algorithms in Java, Sixth Edition 7 | * Michael T. Goodrich, Roberto Tamassia, and Michael H. Goldwasser 8 | * John Wiley & Sons, 2014 9 | * 10 | * This program is free software: you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by 12 | * the Free Software Foundation, either version 3 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program. If not, see . 22 | */ 23 | //package net.datastructures; 24 | package rogeriogentil.data.structures.chapter14; 25 | 26 | /** 27 | * A vertex of a graph. 28 | * 29 | * @author Michael T. Goodrich 30 | * @author Roberto Tamassia 31 | * @author Michael H. Goldwasser 32 | */ 33 | public interface Vertex { 34 | /** Returns the element associated with the vertex. */ 35 | V getElement(); 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter14/reinforcement/Exercise05.txt: -------------------------------------------------------------------------------- 1 | R-14.5 Draw a simple, connected, directed graph with 8 vertices and 16 edges such that 2 | the in-degree and out-degree of each vertex is 2. Show that there is a single 3 | (nonsimple) cycle that includes all the edges of your graph, that is, you can trace 4 | all the edges in their respective directions without ever lifting your pencil. (Such 5 | a cycle is called an Euler tour.) 6 | 7 | Answer: 8 | ====== 9 | 10 | Directed Graph: 11 | -------------- 12 | 13 | ------- 14 | | \ 15 | v \ 16 | A--->B----\---->C<--->D 17 | ^ ^ \ | ^ 18 | | / | \ | | 19 | | / | \ | | 20 | v/ v \ v v 21 | E<---F<--------G<-----H 22 | | ^ 23 | | | 24 | ---------------- 25 | 26 | Graph Traversal: A, E, B, F, H, D, C, G, A 27 | 28 | ------- 29 | | \ 30 | v \ 31 | A B \ C<----D 32 | | ^ \ | ^ 33 | | / | \ | | 34 | | / | \ | | 35 | v/ v \ v | 36 | E F G H 37 | | ^ 38 | | | 39 | ---------------- -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter14/reinforcement/Exercise06.txt: -------------------------------------------------------------------------------- 1 | R-14.6 Suppose we represent a graph G having n vertices and m edges with the edge list 2 | structure. Why, in this case, does the insertVertex method run in O(1) time while 3 | the removeVertex method runs in O(m) time? 4 | 5 | Answer: 6 | ====== 7 | 8 | The insertVertex method runs in O(1) time because the vertex is added in the last 9 | position of the list that store all vertex (all vertex objects are stored in an 10 | unordered list). 11 | 12 | However, the removeVertex method runs in O(m) (m = edges) because to remove a 13 | vertex is necessary to search all edges that are linked with this vertex. -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter14/reinforcement/Exercise07.txt: -------------------------------------------------------------------------------- 1 | R-14.7 Give pseudocode for performing the operation insertEdge(u, v, x) in O(1) time 2 | using the adjacency matrix representation. 3 | 4 | Answer: 5 | ====== 6 | 7 | An adjacency matrix, for instance: 8 | 9 | 0 1 2 3 10 | A -> 0 11 | B -> 1 12 | C -> 2 13 | D -> 3 14 | 15 | Pseudo-code: 16 | 17 | insertEdge(A, B, edge) 18 | matrix[A][B] = edge 19 | matrix[B][A] = edge 20 | 21 | 22 | The adjacency matrix after insertion (e = edge): 23 | 24 | 0 1 2 3 25 | A -> 0 e 26 | B -> 1 e 27 | C -> 2 28 | D -> 3 -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter14/reinforcement/Exercise08.txt: -------------------------------------------------------------------------------- 1 | R-14.8 Repeat Exercise R-14.7 for the adjacency list representation, as described in the 2 | chapter. 3 | 4 | 5 | Answer: 6 | ====== 7 | 8 | An adjacency list, for instance: 9 | 10 | V (vertices) 11 | ___ 12 | | | 13 | | *-|--> A 14 | | | 15 | | *-|--> B 16 | | | 17 | | *-|--> C 18 | | | 19 | | *-|--> D 20 | |___| 21 | 22 | Pseudo-code: 23 | 24 | insertEdge(A, B, edge) 25 | list.getVertex(A).add(edge) 26 | list.getVertex(B).add(edge) 27 | 28 | 29 | The adjacency list after insertion (e = edge): 30 | 31 | V (vertices) 32 | ___ 33 | | | 34 | | *-|--> A --> e 35 | | | 36 | | *-|--> B --> e 37 | | | 38 | | *-|--> C 39 | | | 40 | | *-|--> D 41 | |___| 42 | -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter14/reinforcement/Exercise11.txt: -------------------------------------------------------------------------------- 1 | R-14.11 Would you use the adjacency matrix structure or the adjacency list structure in 2 | each of the following cases? Justify your choice. 3 | 4 | a. The graph has 10,000 vertices and 20,000 edges, and it is important to use 5 | as little space as possible. 6 | 7 | b. The graph has 10,000 vertices and 20,000,000 edges, and it is important to 8 | use as little space as possible. 9 | 10 | c. You need to answer the query getEdge(u, v) as fast as possible, no matter 11 | how much space you use. 12 | 13 | Answer: 14 | ======= 15 | 16 | a: It would be better use an adjacency list structure because a 10,000-by-10,000 17 | matrix has 100,000,000 positions. Even that was necessary stored the double of 18 | the edges (edge E must be stored both in matrix[A][B] and in matrix[B][A]. So 19 | 40,000 = 20,000 * 2), there would be 99,960,000 positions null. Futhermore, 20 | an adjacency matrix uses O(n²) space while a adjacency list structure uses 21 | O(n + m) (n = vertices, m = edges). 22 | 23 | b. Probably it would be better to use an adjacency list structure, because even 24 | with 20,000,000 edges, less of the half of an adjacency matrix would be used to 25 | store all edges. 26 | 27 | c. In this case, it would be better to use an adjacency matrix structure to 28 | answer the query getEdge(u, v) as fast as possible, because this query runs in 29 | O(1) in an adjacency matrix structure against O(min(du, dv)) in an adjacency 30 | list structure. -------------------------------------------------------------------------------- /src/main/java/rogeriogentil/data/structures/chapter14/reinforcement/Exercise13.txt: -------------------------------------------------------------------------------- 1 | R-14.13 Explain why the DFS traversal runs in O(n 2 ) time on an n-vertex simple graph 2 | that is represented with the adjacency matrix structure. 3 | 4 | Answer: 5 | ====== 6 | 7 | As DFS is a discover algorithm, when is used an adjacency matrix structure, it 8 | is necessary go through every vertices (columns) for each vertex (rows) to find 9 | its adjacency vertices (non null elements). -------------------------------------------------------------------------------- /src/test/java/rogeriogentil/data/structures/chapter03/ArraysTest.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter03; 2 | 3 | import java.util.Arrays; 4 | import org.junit.Test; 5 | 6 | import static org.hamcrest.CoreMatchers.*; 7 | import static org.hamcrest.MatcherAssert.*; 8 | import static org.junit.Assert.*; 9 | 10 | /** 11 | * 12 | * @author rogerio 13 | */ 14 | public class ArraysTest { 15 | 16 | @Test 17 | public void devemSerArraysIguais() { 18 | int[] a = {0, 1, 2, 3, 4}; 19 | int[] b = {0, 1, 2, 3, 4}; 20 | 21 | assertTrue(Arrays.equals(a, b)); 22 | } 23 | 24 | @Test 25 | public void naoDevemSerArraysIguais() { 26 | int[] a = {4, 3, 2, 1, 0}; 27 | int[] b = {0, 1, 2, 3, 4}; 28 | 29 | assertFalse(Arrays.equals(a, b)); 30 | } 31 | 32 | @Test 33 | public void devePrencherArrayComValorUnico() { 34 | int[] array = new int[5]; 35 | 36 | Arrays.fill(array, 5); 37 | 38 | for (int i = 0; i < array.length; i++) { 39 | assertTrue(array[i] == 5); 40 | } 41 | } 42 | 43 | @Test 44 | public void deveObterPorBuscaBinaria() { 45 | int[] array = {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40}; 46 | 47 | int index = Arrays.binarySearch(array, 14); 48 | 49 | assertEquals(index, 7); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/test/java/rogeriogentil/data/structures/chapter03/CircularyLinkedListTest.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter03; 2 | 3 | import rogeriogentil.data.structures.chapter03.CircularyLinkedList; 4 | import static org.junit.Assert.assertTrue; 5 | import org.junit.Test; 6 | 7 | /** 8 | * 9 | * @author rogerio 10 | */ 11 | public class CircularyLinkedListTest { 12 | 13 | @Test 14 | public void deveSerMesmoElementoEmNextQuandoListaEstaVazia() { 15 | CircularyLinkedList linkedList = new CircularyLinkedList<>(); 16 | linkedList.addFirst("A"); 17 | 18 | assertTrue(linkedList.getTailNode().getElement().equals("A")); 19 | assertTrue(linkedList.getTailNode().getNext().getElement().equals("A")); 20 | assertTrue(linkedList.getSize() == 1); 21 | } 22 | 23 | @Test 24 | public void deveAdicionarNoInicio() { 25 | CircularyLinkedList linkedList = new CircularyLinkedList<>(); 26 | linkedList.addFirst("C"); 27 | linkedList.addFirst("B"); 28 | linkedList.addFirst("A"); 29 | 30 | assertTrue(linkedList.getHeadNode().getElement().equals("A")); 31 | assertTrue(linkedList.getSize() == 3); 32 | } 33 | 34 | @Test 35 | public void tailDeveApontarParaNovoNoQuandoAdicionarNoInicio() { 36 | CircularyLinkedList linkedList = new CircularyLinkedList<>(); 37 | linkedList.addFirst("C"); 38 | linkedList.addFirst("B"); 39 | linkedList.addFirst("A"); 40 | 41 | assertTrue(linkedList.getTailNode().getNext().getElement().equals("A")); 42 | assertTrue(linkedList.getSize() == 3); 43 | } 44 | 45 | @Test 46 | public void deveAdicionarNoFim() { 47 | CircularyLinkedList linkedList = new CircularyLinkedList(); 48 | linkedList.addLast("A"); 49 | linkedList.addLast("B"); 50 | linkedList.addLast("C"); 51 | 52 | assertTrue(linkedList.getTailNode().getElement().equals("C")); 53 | assertTrue(linkedList.getSize() == 3); 54 | } 55 | 56 | @Test 57 | public void tailDeveApontarParaNovoNoQuandoAdicionarNoFim() { 58 | CircularyLinkedList linkedList = new CircularyLinkedList<>(); 59 | linkedList.addLast("A"); 60 | linkedList.addLast("B"); 61 | linkedList.addLast("C"); 62 | 63 | assertTrue(linkedList.getTailNode().getNext().getElement().equals("A")); 64 | assertTrue(linkedList.getSize() == 3); 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /src/test/java/rogeriogentil/data/structures/chapter03/DoublyLinkedListTest.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter03; 2 | 3 | import rogeriogentil.data.structures.chapter03.DoublyLinkedList; 4 | import org.junit.Test; 5 | 6 | import static org.junit.Assert.*; 7 | import static org.hamcrest.CoreMatchers.*; 8 | 9 | /** 10 | * 11 | * @author rogerio 12 | */ 13 | public class DoublyLinkedListTest { 14 | 15 | @Test 16 | public void deveInicialiarListaDuplamenteEncadeada() { 17 | DoublyLinkedList linkedList = new DoublyLinkedList<>(); 18 | 19 | assertTrue(linkedList.getHeader().getNext().equals(linkedList.getTrailer())); 20 | assertTrue(linkedList.getTrailer().getPrevious().equals(linkedList.getHeader())); 21 | } 22 | 23 | @Test 24 | public void deveInicialiarListaDuplamenteEncadeadaVazia() { 25 | DoublyLinkedList linkedList = new DoublyLinkedList<>(); 26 | 27 | assertTrue(linkedList.isEmpty()); 28 | } 29 | 30 | @Test 31 | public void deveAdicionarNoInicioQuandoListaEstaVazia() { 32 | DoublyLinkedList linkedList = new DoublyLinkedList<>(); 33 | linkedList.addFirst("A"); 34 | 35 | assertEquals("A", linkedList.getHeader().getNext().getElement()); 36 | } 37 | 38 | @Test 39 | public void deveAdicionarNoInicioQuandoListaJaTemNos() { 40 | DoublyLinkedList linkedList = new DoublyLinkedList<>(); 41 | linkedList.addFirst("C"); 42 | linkedList.addFirst("B"); 43 | linkedList.addFirst("A"); 44 | 45 | assertEquals("A", linkedList.getHeader().getNext().getElement()); 46 | assertEquals("B", linkedList.getHeader().getNext().getNext().getElement()); 47 | assertEquals("C", linkedList.getTrailer().getPrevious().getElement()); 48 | assertThat(linkedList.getSize(), is(equalTo(3))); 49 | } 50 | 51 | @Test 52 | public void deveRetornarPrimeiroElementoNuloQuandoListaEstaVazia() { 53 | DoublyLinkedList linkedList = new DoublyLinkedList<>(); 54 | 55 | assertNull(linkedList.first()); 56 | } 57 | 58 | @Test 59 | public void deveRetornarPrimeiroElemento() { 60 | DoublyLinkedList linkedList = new DoublyLinkedList<>(); 61 | linkedList.addFirst("A"); 62 | 63 | assertEquals("A", linkedList.first()); 64 | } 65 | 66 | @Test 67 | public void deveAdicionarNoFimQuandoListaEstaVazia() { 68 | DoublyLinkedList linkedList = new DoublyLinkedList<>(); 69 | linkedList.addLast("A"); 70 | 71 | assertEquals("A", linkedList.getTrailer().getPrevious().getElement()); 72 | } 73 | 74 | @Test 75 | public void deveAdicionarNoFimQuandoListaJaTemNos() { 76 | DoublyLinkedList linkedList = new DoublyLinkedList<>(); 77 | linkedList.addLast("A"); 78 | linkedList.addLast("B"); 79 | linkedList.addLast("C"); 80 | 81 | assertEquals("C", linkedList.getTrailer().getPrevious().getElement()); 82 | assertEquals("B", linkedList.getTrailer().getPrevious().getPrevious().getElement()); 83 | assertEquals("A", linkedList.getHeader().getNext().getElement()); 84 | assertThat(linkedList.getSize(), is(equalTo(3))); 85 | } 86 | 87 | @Test 88 | public void deveRetornarUltimoElementoNuloQuandoListaEstaVazia() { 89 | DoublyLinkedList linkedList = new DoublyLinkedList<>(); 90 | 91 | assertNull(linkedList.last()); 92 | } 93 | 94 | @Test 95 | public void deveRetornarUltimoElemento() { 96 | DoublyLinkedList linkedList = new DoublyLinkedList<>(); 97 | linkedList.addLast("A"); 98 | 99 | assertEquals("A", linkedList.first()); 100 | } 101 | 102 | @Test 103 | public void deveExecutarRemocaoNoInicioMesmoQuandoListaEstaVazia() { 104 | DoublyLinkedList linkedList = new DoublyLinkedList<>(); 105 | linkedList.removeFirst(); 106 | 107 | assertThat(linkedList.getSize(), is(equalTo(0))); 108 | } 109 | 110 | @Test 111 | public void deveRemoverNoInicioQuandoListaNaoEstaVazia() { 112 | DoublyLinkedList linkedList = new DoublyLinkedList<>(); 113 | linkedList.addFirst("C"); 114 | linkedList.addFirst("B"); 115 | linkedList.addFirst("A"); 116 | 117 | linkedList.removeFirst(); 118 | 119 | assertEquals("B", linkedList.getHeader().getNext().getElement()); 120 | assertEquals("C", linkedList.getTrailer().getPrevious().getElement()); 121 | assertThat(linkedList.getSize(), is(equalTo(2))); 122 | } 123 | 124 | @Test 125 | public void deveExecutarRemocaoNoFimMesmoQuandoListaEstaVazia() { 126 | DoublyLinkedList linkedList = new DoublyLinkedList<>(); 127 | linkedList.removeLast(); 128 | 129 | assertThat(linkedList.getSize(), is(equalTo(0))); 130 | } 131 | 132 | @Test 133 | public void deveRemoverNoFimQuandoListaNaoEstaVazia() { 134 | DoublyLinkedList linkedList = new DoublyLinkedList<>(); 135 | linkedList.addLast("A"); 136 | linkedList.addLast("B"); 137 | linkedList.addLast("C"); 138 | 139 | linkedList.removeLast(); 140 | 141 | assertEquals("A", linkedList.getHeader().getNext().getElement()); 142 | assertEquals("B", linkedList.getTrailer().getPrevious().getElement()); 143 | assertThat(linkedList.getSize(), is(equalTo(2))); 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /src/test/java/rogeriogentil/data/structures/chapter03/InsertionSortTest.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter03; 2 | 3 | import rogeriogentil.data.structures.chapter03.InsertionSort; 4 | import org.hamcrest.MatcherAssert; 5 | import org.junit.Test; 6 | 7 | /** 8 | * 9 | * @author rogerio 10 | */ 11 | public class InsertionSortTest { 12 | 13 | @Test 14 | public void deveOrdernarQuandoArrayEstaCheio() { 15 | Integer[] arrayDesordenado = new Integer[5]; // não pode ser int por usar Generics!! 16 | arrayDesordenado[0] = 3; 17 | arrayDesordenado[1] = 6; 18 | arrayDesordenado[2] = 9; 19 | arrayDesordenado[3] = 4; 20 | arrayDesordenado[4] = 1; 21 | 22 | InsertionSort insertionSort = new InsertionSort(); 23 | Integer[] arrayOrdenado = insertionSort.sort(arrayDesordenado); 24 | 25 | for (int i = 1; i < arrayOrdenado.length; i++) { 26 | MatcherAssert.assertThat("", arrayDesordenado[i] > arrayDesordenado[i - 1]); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/test/java/rogeriogentil/data/structures/chapter03/SinglyLinkedListTest.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter03; 2 | 3 | import rogeriogentil.data.structures.chapter03.SinglyLinkedList; 4 | import org.junit.Test; 5 | 6 | import static org.junit.Assert.*; 7 | 8 | /** 9 | * 10 | * @author rogerio 11 | */ 12 | public class SinglyLinkedListTest { 13 | 14 | @Test 15 | public void deveAdicionarNoInicio() { 16 | SinglyLinkedList linkedList = new SinglyLinkedList<>(); 17 | linkedList.addFirst("C"); 18 | linkedList.addFirst("B"); 19 | linkedList.addFirst("A"); 20 | 21 | assertTrue(linkedList.getHead().getElement().equals("A")); 22 | assertTrue(linkedList.getSize() == 3); 23 | } 24 | 25 | @Test 26 | public void deveAdicionarNoFim() { 27 | SinglyLinkedList linkedList = new SinglyLinkedList(); 28 | linkedList.addLast("A"); 29 | linkedList.addLast("B"); 30 | linkedList.addLast("C"); 31 | 32 | assertTrue(linkedList.getHead().getNext().getNext().getElement().equals("C")); 33 | assertTrue(linkedList.getSize() == 3); 34 | } 35 | 36 | @Test 37 | public void deveIndicarQueListaEstaVazia() { 38 | SinglyLinkedList linkedList = new SinglyLinkedList(); 39 | assertTrue(linkedList.isEmpty()); 40 | } 41 | 42 | @Test 43 | public void deveRemoverPrimeiroElemento() { 44 | SinglyLinkedList linkedList = new SinglyLinkedList(); 45 | linkedList.addLast(10); 46 | linkedList.addLast(20); 47 | linkedList.addLast(30); 48 | 49 | linkedList.removeFist(); 50 | 51 | assertTrue(linkedList.getHead().getElement().equals(20)); 52 | assertTrue(linkedList.getSize() == 2); 53 | } 54 | 55 | @Test 56 | public void deveExecutarRemoverPrimeiroElementoMesmoQuandoListaEstaVazia() { 57 | SinglyLinkedList linkedList = new SinglyLinkedList(); 58 | linkedList.removeFist(); 59 | 60 | assertTrue(linkedList.getSize() == 0); 61 | } 62 | 63 | @Test 64 | public void deveRemoverPrimeiroElementoMesmoQuandoListaTemApenasUmNo() { 65 | SinglyLinkedList linkedList = new SinglyLinkedList(); 66 | linkedList.addLast(10); 67 | linkedList.removeFist(); 68 | 69 | assertTrue(linkedList.getSize() == 0); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/test/java/rogeriogentil/data/structures/chapter05/FactorialTest.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter05; 2 | 3 | import rogeriogentil.data.structures.chapter05.Factorial; 4 | import org.junit.Test; 5 | 6 | import static org.junit.Assert.*; 7 | 8 | /** 9 | * 10 | * @author rogerio 11 | */ 12 | public class FactorialTest { 13 | 14 | @Test 15 | public void deveRetornarFatorialDeTres() { 16 | int n = 3; 17 | long resultado = Factorial.factorial(n); 18 | 19 | assertEquals(6, resultado); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/test/java/rogeriogentil/data/structures/chapter05/RecursionBinarySearchTest.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter05; 2 | 3 | import rogeriogentil.data.structures.chapter05.RecursionBinarySearch; 4 | import org.junit.Assert; 5 | import org.junit.Ignore; 6 | import org.junit.Test; 7 | 8 | /** 9 | * 10 | * @author rogerio 11 | */ 12 | public class RecursionBinarySearchTest { 13 | 14 | @Test 15 | public void deveEncontrarNumeroNoMeio() { 16 | int[] array = {0, 10, 20, 30, 40}; 17 | int numero = 20; 18 | 19 | int index = RecursionBinarySearch.search(numero, array, 0, array.length - 1); 20 | 21 | Assert.assertEquals(2, index); 22 | } 23 | 24 | @Ignore 25 | @Test 26 | public void deveEncontrarNumeroADireta() { 27 | int[] array = {0, 10, 20, 30, 40, 50, 60, 70, 80, 90}; 28 | int numero = 30; 29 | 30 | int index = RecursionBinarySearch.search(numero, array, 0, array.length - 1); 31 | 32 | Assert.assertEquals(4, index); 33 | } 34 | 35 | @Ignore 36 | @Test 37 | public void deveEncontrarNumeroAEsquerda() { 38 | int[] array = {0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100}; 39 | int numero = 90; 40 | 41 | int index = RecursionBinarySearch.search(numero, array, 0, array.length - 1); 42 | 43 | Assert.assertEquals(10, index); 44 | } 45 | } 46 | 47 | -------------------------------------------------------------------------------- /src/test/java/rogeriogentil/data/structures/chapter05/RecursionFibonacciTest.java: -------------------------------------------------------------------------------- 1 | 2 | package rogeriogentil.data.structures.chapter05; 3 | 4 | import rogeriogentil.data.structures.chapter05.RecursionFibonacci; 5 | import org.junit.Assert; 6 | import org.junit.Ignore; 7 | import org.junit.Test; 8 | 9 | /** 10 | * 11 | * @author rogerio 12 | */ 13 | public class RecursionFibonacciTest { 14 | 15 | @Ignore 16 | @Test 17 | public void deveRetornarQuartoNumeroDeFibonacci() { 18 | long n = RecursionFibonacci.get(6); 19 | Assert.assertEquals(24, n); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/test/java/rogeriogentil/data/structures/chapter06/ArrayCircularQueueTest.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter06; 2 | 3 | import rogeriogentil.data.structures.chapter06.Queue; 4 | import rogeriogentil.data.structures.chapter06.ArrayCircularQueue; 5 | import org.junit.Test; 6 | 7 | import static org.junit.Assert.*; 8 | import static org.hamcrest.CoreMatchers.*; 9 | 10 | /** 11 | * 12 | * @author rogerio 13 | */ 14 | public class ArrayCircularQueueTest { 15 | 16 | private Queue queue; 17 | 18 | @Test 19 | public void deveInserirUmElemento() { 20 | String s = "A"; 21 | queue = new ArrayCircularQueue<>(3); 22 | queue.enqueue(s); 23 | 24 | assertThat(queue.first(), is(equalTo(s))); 25 | } 26 | 27 | @Test 28 | public void deveRemoverUmElementoDoComeco() { 29 | String s = "A"; 30 | queue = new ArrayCircularQueue<>(3); 31 | queue.enqueue(s); 32 | queue.enqueue("B"); 33 | queue.enqueue("C"); 34 | 35 | assertThat(queue.dequeue(), is(equalTo(s))); 36 | } 37 | 38 | @Test 39 | public void deveInserirUmElementoNoInicioQuandoFilaVoltar() { 40 | String s = "A"; 41 | queue = new ArrayCircularQueue<>(3); 42 | queue.enqueue("B"); 43 | queue.enqueue("C"); 44 | queue.enqueue("D"); 45 | queue.dequeue(); // remove "B" 46 | queue.enqueue(s); 47 | 48 | assertThat(queue.size(), is(equalTo(3))); 49 | } 50 | 51 | @Test 52 | public void deveInserirCriarUmaFilaVazia() { 53 | queue = new ArrayCircularQueue<>(3); 54 | 55 | assertThat(queue.isEmpty(), is(true)); 56 | } 57 | 58 | @Test(expected = IllegalStateException.class) 59 | public void deveLancarExcecaoTentarInserirElementoQuandoFilaEstaCheia() { 60 | queue = new ArrayCircularQueue<>(3); 61 | queue.enqueue("A"); 62 | queue.enqueue("B"); 63 | queue.enqueue("C"); 64 | queue.enqueue("D"); 65 | } 66 | 67 | @Test 68 | public void deveRetornarTamanho() { 69 | queue = new ArrayCircularQueue<>(4); 70 | queue.enqueue("A"); 71 | queue.enqueue("B"); 72 | queue.enqueue("C"); 73 | queue.enqueue("D"); 74 | 75 | assertThat(queue.size(), is(equalTo(4))); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/test/java/rogeriogentil/data/structures/chapter06/ArrayStackTest.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter06; 2 | 3 | import rogeriogentil.data.structures.chapter06.ArrayStack; 4 | import rogeriogentil.data.structures.chapter06.Stack; 5 | import org.junit.Test; 6 | 7 | import static org.hamcrest.CoreMatchers.*; 8 | import static org.junit.Assert.*; 9 | 10 | /** 11 | * 12 | * @author rogerio 13 | */ 14 | public class ArrayStackTest { 15 | 16 | @Test 17 | public void deveIndicarQuePilhaEstaVaziaAoInicializarObjeto() { 18 | Stack stack = new ArrayStack<>(); 19 | assertThat(stack.isEmpty(), is(true)); 20 | } 21 | 22 | @Test 23 | public void deveAdicionarUmElementoNaPilha() { 24 | Stack stack = new ArrayStack<>(1); 25 | stack.push(10); 26 | 27 | assertThat(stack.size(), is(equalTo(1))); 28 | } 29 | 30 | @Test 31 | public void deveObterElementoDoTopoDaPilha() { 32 | Stack stack = new ArrayStack<>(3); 33 | stack.push(10); 34 | stack.push(25); 35 | stack.push(50); 36 | 37 | assertThat(stack.top(), is(equalTo(50))); 38 | } 39 | 40 | @Test(expected = IllegalStateException.class) 41 | public void deveLancarExcecaoAoExcederLimiteDeCapacidadeDaPilhar() { 42 | Stack stack = new ArrayStack<>(3); 43 | stack.push(10); 44 | stack.push(20); 45 | stack.push(30); 46 | stack.push(40); 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/test/java/rogeriogentil/data/structures/chapter06/ArrayUtilTest.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter06; 2 | 3 | import rogeriogentil.data.structures.chapter06.ArrayUtil; 4 | import java.util.Arrays; 5 | import org.junit.Test; 6 | 7 | import static org.hamcrest.CoreMatchers.*; 8 | import static org.junit.Assert.*; 9 | 10 | /** 11 | * 12 | * @author Rogerio J. Gentil 13 | */ 14 | public class ArrayUtilTest { 15 | 16 | @Test 17 | public void deveReverterArray() { 18 | Integer[] array = {10, 20, 30, 40, 50}; 19 | ArrayUtil.reverse(array); 20 | 21 | System.out.println(Arrays.toString(array)); 22 | assertThat(array[0], is(equalTo(50))); 23 | assertThat(array[1], is(equalTo(40))); 24 | assertThat(array[2], is(equalTo(30))); 25 | assertThat(array[3], is(equalTo(20))); 26 | assertThat(array[4], is(equalTo(10))); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/test/java/rogeriogentil/data/structures/chapter06/MatchUtilTest.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter06; 2 | 3 | import rogeriogentil.data.structures.chapter06.MatchUtil; 4 | import org.junit.Test; 5 | 6 | import static org.junit.Assert.*; 7 | import static org.hamcrest.CoreMatchers.*; 8 | 9 | /** 10 | * 11 | * @author rogerio 12 | */ 13 | public class MatchUtilTest { 14 | 15 | @Test 16 | public void deveValidarQuandoNaoHaCaracteresDeAberturaOuFechamento() { 17 | String expressao = "1 + 1 - 2"; 18 | boolean isMatched = MatchUtil.isMatched(expressao); 19 | 20 | assertThat(isMatched, is(true)); 21 | } 22 | 23 | @Test 24 | public void deveValidarComExpressaoSimples() { 25 | String expressao = "(1 + 1 - 2)"; 26 | boolean isMatched = MatchUtil.isMatched(expressao); 27 | 28 | assertThat(isMatched, is(true)); 29 | } 30 | 31 | @Test 32 | public void deveValidarComExpressaoComposta() { 33 | String expressao = "[1 + (1 - 2)]"; 34 | boolean isMatched = MatchUtil.isMatched(expressao); 35 | 36 | assertThat(isMatched, is(true)); 37 | } 38 | 39 | @Test 40 | public void naoDeveValidarExpressaoSimple() { 41 | String expressao = "(1 + 1 - 2"; 42 | boolean isMatched = MatchUtil.isMatched(expressao); 43 | 44 | assertThat(isMatched, is(false)); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/test/java/rogeriogentil/data/structures/chapter06/reinforcement/Exercise04Test.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter06.reinforcement; 2 | 3 | import rogeriogentil.data.structures.chapter06.reinforcement.Exercise04; 4 | import java.util.Arrays; 5 | import org.junit.Test; 6 | import rogeriogentil.data.structures.chapter06.ArrayStack; 7 | import rogeriogentil.data.structures.chapter06.Stack; 8 | 9 | import static org.junit.Assert.*; 10 | import static org.hamcrest.CoreMatchers.*; 11 | 12 | /** 13 | * 14 | * @author Rogerio J. Gentil 15 | */ 16 | public class Exercise04Test { 17 | 18 | @Test 19 | public void deveTransferirPilhaInvertendoTopo() { 20 | Stack s = new ArrayStack<>(5); 21 | s.push("A"); 22 | s.push("B"); 23 | s.push("C"); 24 | s.push("D"); 25 | 26 | Stack t = new ArrayStack<>(5); 27 | assertThat(t.top(), is(equalTo(null))); 28 | 29 | Exercise04.transfer(s, t); 30 | 31 | assertThat(t.top(), is(equalTo("A"))); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/test/java/rogeriogentil/data/structures/chapter06/reinforcement/Exercise05Test.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter06.reinforcement; 2 | 3 | import static org.hamcrest.CoreMatchers.is; 4 | import static org.junit.Assert.assertThat; 5 | import org.junit.Test; 6 | import rogeriogentil.data.structures.chapter06.ArrayStack; 7 | import rogeriogentil.data.structures.chapter06.Stack; 8 | 9 | /** 10 | * 11 | * @author Rogerio J. Gentil 12 | */ 13 | public class Exercise05Test { 14 | 15 | @Test 16 | public void mustRemoveAllElementsRecursively() { 17 | Stack stack = new ArrayStack<>(); 18 | stack.push(10); 19 | stack.push(20); 20 | stack.push(30); 21 | stack.push(40); 22 | 23 | Exercise05 ex05 = new Exercise05<>(); 24 | ex05.removeAll(stack); 25 | 26 | assertThat(stack.isEmpty(), is(true)); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/test/java/rogeriogentil/data/structures/chapter06/reinforcement/Exercise10Test.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter06.reinforcement; 2 | 3 | 4 | import static org.hamcrest.CoreMatchers.*; 5 | import static org.junit.Assert.*; 6 | import org.junit.Before; 7 | import org.junit.Test; 8 | import rogeriogentil.data.structures.chapter06.reinforcement.Exercise10; 9 | 10 | /** 11 | * 12 | * @author Rogerio J. Gentil 13 | */ 14 | public class Exercise10Test { 15 | 16 | private Exercise10 ex10; 17 | 18 | @Before 19 | public void beforeEachTest() { 20 | ex10 = new Exercise10<>(); 21 | } 22 | 23 | @Test 24 | public void dequeMustBeEmtpyWhenInitialized() { 25 | assertThat(ex10.isEmpty(), is(true)); 26 | } 27 | 28 | @Test 29 | public void lastElementMustBeTheTop() { 30 | ex10.push(10); 31 | ex10.push(20); 32 | ex10.push(30); 33 | 34 | assertThat(ex10.top(), is(equalTo(30))); 35 | } 36 | 37 | @Test 38 | public void mustRemoveTheElementOnTheTop() { 39 | ex10.push(10); 40 | ex10.push(20); 41 | ex10.push(30); 42 | 43 | ex10.pop(); 44 | 45 | assertThat(ex10.top(), is(equalTo(20))); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/test/java/rogeriogentil/data/structures/chapter07/ArrayListTest.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter07; 2 | 3 | import rogeriogentil.data.structures.chapter07.ArrayList; 4 | import org.junit.Test; 5 | 6 | import static org.hamcrest.CoreMatchers.*; 7 | import static org.junit.Assert.*; 8 | /** 9 | * 10 | * @author Rogerio J. Gentil 11 | */ 12 | public class ArrayListTest { 13 | 14 | @Test 15 | public void deveRemover() { 16 | ArrayList list = new ArrayList<>(5); 17 | list.add(0, 10); 18 | list.add(1, 20); 19 | list.add(2, 30); 20 | list.add(3, 40); 21 | list.add(4, 50); 22 | 23 | list.remove(3); 24 | assertThat(list.get(3), is(equalTo(50))); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/test/java/rogeriogentil/data/structures/chapter07/reinforcement/Exercise02Test.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter07.reinforcement; 2 | 3 | import rogeriogentil.data.structures.chapter07.reinforcement.StackArrayList; 4 | import org.junit.Test; 5 | 6 | import static org.hamcrest.CoreMatchers.*; 7 | import static org.junit.Assert.*; 8 | 9 | /** 10 | * 11 | * @author Rogerio J. Gentil 12 | */ 13 | public class Exercise02Test { 14 | 15 | @Test 16 | public void mustInstanceStackWithoutElements() { 17 | StackArrayList stack = new StackArrayList<>(); 18 | 19 | assertThat(stack.isEmpty(), is(true)); 20 | } 21 | 22 | @Test 23 | public void mustReturnSize() { 24 | StackArrayList stack = new StackArrayList<>(); 25 | stack.push(1); 26 | stack.push(2); 27 | stack.push(3); 28 | 29 | assertThat(stack.size(), is(equalTo(3))); 30 | } 31 | 32 | @Test 33 | public void mustInsertOnTop() { 34 | StackArrayList stack = new StackArrayList<>(); 35 | stack.push(10); 36 | stack.push(20); 37 | stack.push(30); 38 | 39 | assertThat(stack.top(), is(equalTo(30))); 40 | } 41 | 42 | @Test 43 | public void mustGetElementOnTop() { 44 | StackArrayList stack = new StackArrayList<>(); 45 | stack.push(10); 46 | stack.push(20); 47 | 48 | assertThat(stack.top(), is(equalTo(20))); 49 | } 50 | 51 | @Test 52 | public void mustRemoveElementOfTheTop() { 53 | StackArrayList stack = new StackArrayList<>(); 54 | stack.push(10); 55 | stack.push(20); 56 | stack.push(30); 57 | 58 | Integer popped = stack.pop(); 59 | 60 | assertThat(popped, is(equalTo(30))); 61 | assertThat(stack.top(), is(equalTo(20))); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/test/java/rogeriogentil/data/structures/chapter07/reinforcement/Exercise03Test.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter07.reinforcement; 2 | 3 | import rogeriogentil.data.structures.chapter07.reinforcement.DequeArrayList; 4 | import org.junit.Test; 5 | import rogeriogentil.data.structures.chapter06.Deque; 6 | 7 | import static org.hamcrest.CoreMatchers.*; 8 | import static org.junit.Assert.*; 9 | 10 | /** 11 | * 12 | * @author Rogerio J. Gentil 13 | */ 14 | public class Exercise03Test { 15 | 16 | private Deque deque; 17 | 18 | @Test 19 | public void mustInstanceDequeWithoutElementsByDefault() { 20 | deque = new DequeArrayList(); 21 | 22 | assertThat(deque.isEmpty(), is(true)); 23 | } 24 | 25 | @Test 26 | public void mustInstanceDequeWithoutElementsEvenWhenCapacityIsProvided() { 27 | deque = new DequeArrayList(10); 28 | 29 | assertThat(deque.isEmpty(), is(true)); 30 | } 31 | 32 | @Test 33 | public void mustAddAtBegin() { 34 | deque = new DequeArrayList(); 35 | deque.addFirst(10); 36 | deque.addFirst(20); 37 | deque.addFirst(30); 38 | 39 | assertThat(deque.first(), is(equalTo(30))); 40 | assertThat(deque.size(), is(equalTo(3))); 41 | } 42 | 43 | @Test 44 | public void mustAddAtEnd() { 45 | deque = new DequeArrayList(); 46 | deque.addLast(10); 47 | deque.addLast(20); 48 | deque.addLast(30); 49 | 50 | assertThat(deque.last(), is(equalTo(30))); 51 | assertThat(deque.size(), is(equalTo(3))); 52 | } 53 | 54 | @Test 55 | public void mustRemoveAtBegin() { 56 | deque = new DequeArrayList(); 57 | deque.addFirst(10); 58 | deque.addFirst(20); 59 | deque.addFirst(30); 60 | 61 | assertThat(deque.removeFirst(), is(equalTo(30))); 62 | assertThat(deque.size(), is(equalTo(2))); 63 | } 64 | 65 | @Test 66 | public void mustRemoveAtEnd() { 67 | deque = new DequeArrayList(); 68 | deque.addFirst(10); 69 | deque.addFirst(20); 70 | deque.addFirst(30); 71 | 72 | assertThat(deque.removeLast(), is(equalTo(10))); 73 | assertThat(deque.size(), is(equalTo(2))); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/test/java/rogeriogentil/data/structures/chapter07/reinforcement/Exercise10Test.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter07.reinforcement; 2 | 3 | import static org.hamcrest.CoreMatchers.*; 4 | import static org.junit.Assert.*; 5 | import org.junit.Before; 6 | import org.junit.Test; 7 | 8 | /** 9 | * 10 | * @author Rogerio J. Gentil 11 | */ 12 | public class Exercise10Test { 13 | 14 | private ArrayStack stack; 15 | 16 | @Before 17 | public void beforeEachTest() { 18 | stack = new ArrayStack<>(); 19 | } 20 | 21 | @Test 22 | public void mustInitializeEmptyStack() { 23 | assertThat(stack.isEmpty(), is(true)); 24 | } 25 | 26 | @Test 27 | public void lastInsertedElementMustBeOnTheTop() { 28 | stack.push(10); 29 | stack.push(20); 30 | stack.push(30); 31 | 32 | assertThat(stack.top(), is(equalTo(30))); 33 | } 34 | 35 | @Test 36 | public void mustRemoveOfTheTop() { 37 | stack.push(10); 38 | stack.push(20); 39 | stack.push(30); 40 | 41 | stack.pop(); 42 | 43 | assertThat(stack.top(), is(equalTo(20))); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/test/java/rogeriogentil/data/structures/chapter08/TreeUtilTest.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter08; 2 | 3 | import rogeriogentil.data.structures.chapter08.LinkedBinaryTree; 4 | import rogeriogentil.data.structures.chapter08.TreeUtil; 5 | import java.util.ArrayList; 6 | import org.junit.Test; 7 | import rogeriogentil.data.structures.chapter07.Position; 8 | 9 | /** 10 | * 11 | * @author Rogerio J. Gentil 12 | */ 13 | public class TreeUtilTest { 14 | 15 | @Test 16 | public void mustPrintIndent() { 17 | LinkedBinaryTree tree = new LinkedBinaryTree(); 18 | tree.addRoot("Book Title"); 19 | Position firstLevelLeft = tree.addLeft(tree.root(), "Title 1"); 20 | tree.addLeft(firstLevelLeft, "Subtitle 1"); 21 | tree.addRight(tree.root(), "Title 2"); 22 | 23 | TreeUtil.printPreOrderIndent(tree, tree.root(), 0); 24 | } 25 | 26 | @Test 27 | public void mustPrintLabeled() { 28 | LinkedBinaryTree tree = new LinkedBinaryTree(); 29 | tree.addRoot("Book Title"); 30 | Position firstLevelLeft = tree.addLeft(tree.root(), "Title 1"); 31 | tree.addLeft(firstLevelLeft, "Subtitle 1"); 32 | tree.addRight(tree.root(), "Title 2"); 33 | 34 | TreeUtil.printPreOrderLabeled(tree, tree.root(), new ArrayList<>()); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/test/java/rogeriogentil/data/structures/chapter08/reinforcement/Exercise05Test.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter08.reinforcement; 2 | 3 | import rogeriogentil.data.structures.chapter08.reinforcement.Exercise05; 4 | import org.junit.Test; 5 | import rogeriogentil.data.structures.chapter07.Position; 6 | import rogeriogentil.data.structures.chapter08.LinkedBinaryTree; 7 | 8 | import static org.hamcrest.CoreMatchers.*; 9 | import static org.junit.Assert.*; 10 | 11 | /** 12 | * 13 | * @author Rogerio J. Gentil 14 | */ 15 | public class Exercise05Test { 16 | 17 | @Test 18 | public void mustReturnZeroWhenBinaryTreeIsEmpty() { 19 | LinkedBinaryTree linkedBinaryTree = new LinkedBinaryTree<>(); 20 | int count = Exercise05.countLeftLeaves(linkedBinaryTree, linkedBinaryTree.root()); 21 | assertThat(count, is(equalTo(0))); 22 | } 23 | 24 | @Test 25 | public void mustReturnZeroWhenBinaryTreeHasJustRoot() { 26 | LinkedBinaryTree linkedBinaryTree = new LinkedBinaryTree<>(); 27 | linkedBinaryTree.addRoot(1); 28 | 29 | int count = Exercise05.countLeftLeaves(linkedBinaryTree, linkedBinaryTree.root()); 30 | assertThat(count, is(equalTo(0))); 31 | } 32 | 33 | @Test 34 | public void mustReturnZeroWhenBinaryTreeHasJustRightPositions() { 35 | LinkedBinaryTree linkedBinaryTree = new LinkedBinaryTree<>(); 36 | linkedBinaryTree.addRoot(1); 37 | 38 | Position rootRightPosition = linkedBinaryTree.addRight(linkedBinaryTree.root(), 2); 39 | Position rightPositionOfTheRightPosition = linkedBinaryTree.addRight(rootRightPosition, 3); 40 | 41 | int count = Exercise05.countLeftLeaves(linkedBinaryTree, linkedBinaryTree.root()); 42 | assertThat(count, is(equalTo(0))); 43 | } 44 | 45 | @Test 46 | public void mustCountLeftLeavesWhenBinaryTreeHasJustOneLeftPosition() { 47 | LinkedBinaryTree linkedBinaryTree = new LinkedBinaryTree<>(); 48 | linkedBinaryTree.addRoot(1); 49 | 50 | Position rootLeftPosition = linkedBinaryTree.addLeft(linkedBinaryTree.root(), 2); 51 | 52 | int count = Exercise05.countLeftLeaves(linkedBinaryTree, linkedBinaryTree.root()); 53 | assertThat(count, is(equalTo(1))); 54 | } 55 | 56 | @Test 57 | public void mustCountLeftLeavesWhenBinaryTreeHasJustLeftmostPosition() { 58 | LinkedBinaryTree linkedBinaryTree = new LinkedBinaryTree<>(); 59 | linkedBinaryTree.addRoot(1); 60 | 61 | Position rootLeftPosition = linkedBinaryTree.addLeft(linkedBinaryTree.root(), 2); 62 | Position leaveleftPosition = linkedBinaryTree.addLeft(rootLeftPosition, 3); 63 | 64 | int count = Exercise05.countLeftLeaves(linkedBinaryTree, linkedBinaryTree.root()); 65 | assertThat(count, is(equalTo(1))); 66 | } 67 | 68 | @Test 69 | public void mustCountLeftLeavesWhenBinaryTreeHasTwoLeftLeavesPositions() { 70 | LinkedBinaryTree linkedBinaryTree = new LinkedBinaryTree<>(); 71 | linkedBinaryTree.addRoot(1); 72 | 73 | Position rootLeftPosition = linkedBinaryTree.addLeft(linkedBinaryTree.root(), 2); 74 | Position leftMostPosition = linkedBinaryTree.addLeft(rootLeftPosition, 3); 75 | 76 | Position rootRightPosition = linkedBinaryTree.addRight(linkedBinaryTree.root(), 4); 77 | Position leftPositionOfTheRightPosition = linkedBinaryTree.addLeft(rootRightPosition, 5); 78 | Position rightPositionOfTheRightPosition = linkedBinaryTree.addRight(rootRightPosition, 6); 79 | 80 | int count = Exercise05.countLeftLeaves(linkedBinaryTree, linkedBinaryTree.root()); 81 | assertThat(count, is(equalTo(2))); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/test/java/rogeriogentil/data/structures/chapter09/StringLengthComparatorTest.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter09; 2 | 3 | import rogeriogentil.data.structures.chapter09.StringLengthComparator; 4 | import org.junit.Test; 5 | 6 | import static org.hamcrest.CoreMatchers.*; 7 | import static org.junit.Assert.*; 8 | 9 | /** 10 | * 11 | * @author Rogerio J. Gentil 12 | */ 13 | public class StringLengthComparatorTest { 14 | 15 | @Test 16 | public void mustBeEquals() { 17 | final String s1 = "abc"; 18 | final String s2 = "xyz"; 19 | 20 | StringLengthComparator slc = new StringLengthComparator(); 21 | int result = slc.compare(s1, s2); 22 | 23 | assertThat(result, is(equalTo(0))); 24 | } 25 | 26 | @Test 27 | public void mustReturnOneNegative() { 28 | final String s1 = "abc"; 29 | final String s2 = "wxyz"; 30 | 31 | StringLengthComparator slc = new StringLengthComparator(); 32 | int result = slc.compare(s1, s2); 33 | 34 | assertThat(result, is(equalTo(-1))); 35 | } 36 | 37 | @Test 38 | public void mustReturnOne() { 39 | final String s1 = "abcde"; 40 | final String s2 = "xyz"; 41 | 42 | StringLengthComparator slc = new StringLengthComparator(); 43 | int result = slc.compare(s1, s2); 44 | 45 | assertThat(result, is(equalTo(1))); 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /src/test/java/rogeriogentil/data/structures/chapter09/UnsortedProrityQueueTest.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter09; 2 | 3 | import rogeriogentil.data.structures.chapter09.UnsortedProrityQueue; 4 | import org.junit.Test; 5 | 6 | import static org.hamcrest.CoreMatchers.*; 7 | import static org.junit.Assert.*; 8 | 9 | /** 10 | * 11 | * @author rogerio 12 | */ 13 | public class UnsortedProrityQueueTest { 14 | 15 | @Test 16 | public void mustInstanceEmptyUnsortedPriorityQueue() { 17 | UnsortedProrityQueue unsortedProrityQueue = new UnsortedProrityQueue<>(); 18 | assertThat(unsortedProrityQueue.isEmpty(), is(true)); 19 | } 20 | 21 | @Test 22 | public void mustInsert() { 23 | UnsortedProrityQueue unsortedProrityQueue = new UnsortedProrityQueue<>(); 24 | unsortedProrityQueue.insert(1, "A"); 25 | 26 | assertThat(unsortedProrityQueue.size(), is(equalTo(1))); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/test/java/rogeriogentil/data/structures/chapter12/MergeSortTest.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter12; 2 | 3 | 4 | import org.junit.Test; 5 | import rogeriogentil.data.structures.chapter09.DefaultComparator; 6 | 7 | import static org.hamcrest.CoreMatchers.*; 8 | import static org.junit.Assert.*; 9 | import rogeriogentil.data.structures.chapter06.LinkedQueue; 10 | import rogeriogentil.data.structures.chapter06.Queue; 11 | 12 | /** 13 | * 14 | * @author Rogerio J. Gentil 15 | */ 16 | public class MergeSortTest { 17 | 18 | @Test 19 | public void mustOrderDataUsingArrayBasedApproach() { 20 | System.out.println("Testing Array-based mergeSort implementation"); 21 | Integer[] s = {2, 6, 9, 7, 5, 3, 1, 4, 8}; 22 | MergeSort.mergeSort(s, new DefaultComparator<>()); 23 | 24 | Integer[] expected = {1, 2, 3, 4, 5, 6, 7, 8, 9}; 25 | assertThat(s, is(equalTo(expected))); 26 | } 27 | 28 | @Test 29 | public void mustOrderDataUsingQueueApproach() { 30 | System.out.println("Testing Queue-based mergeSort implementation"); 31 | Queue S = new LinkedQueue<>(); 32 | S.enqueue(2); 33 | S.enqueue(6); 34 | S.enqueue(9); 35 | S.enqueue(7); 36 | S.enqueue(5); 37 | S.enqueue(3); 38 | S.enqueue(1); 39 | S.enqueue(4); 40 | S.enqueue(8); 41 | 42 | MergeSort.mergeSort(S, new DefaultComparator<>()); 43 | 44 | Integer[] expected = {1, 2, 3, 4, 5, 6, 7, 8, 9}; 45 | 46 | for (Integer value : expected) { 47 | assertThat(S.dequeue(), is(equalTo(value))); 48 | } 49 | } 50 | 51 | @Test 52 | public void mustOrderDataUsingBottomUpApproach() { 53 | System.out.println("Testing Bottom-Up mergeSort implementation"); 54 | Integer[] s = {2, 6, 9, 7, 5, 3, 1, 4, 8}; 55 | MergeSort.mergeSortBottomUp(s, new DefaultComparator<>()); 56 | 57 | Integer[] expected = {1, 2, 3, 4, 5, 6, 7, 8, 9}; 58 | assertThat(s, is(equalTo(expected))); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/test/java/rogeriogentil/data/structures/chapter12/QuickSortTest.java: -------------------------------------------------------------------------------- 1 | package rogeriogentil.data.structures.chapter12; 2 | 3 | 4 | import org.junit.Test; 5 | import rogeriogentil.data.structures.chapter06.LinkedQueue; 6 | import rogeriogentil.data.structures.chapter06.Queue; 7 | import rogeriogentil.data.structures.chapter09.DefaultComparator; 8 | 9 | import static org.hamcrest.CoreMatchers.*; 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * 14 | * @author Rogerio J. Gentil 15 | */ 16 | public class QuickSortTest { 17 | 18 | @Test 19 | public void mustOrderUsingQueueAproach() { 20 | Queue q = new LinkedQueue<>(); 21 | q.enqueue(8); 22 | q.enqueue(2); 23 | q.enqueue(5); 24 | q.enqueue(4); 25 | q.enqueue(7); 26 | q.enqueue(1); 27 | q.enqueue(3); 28 | q.enqueue(6); 29 | 30 | QuickSort.quickSort(q, new DefaultComparator<>()); 31 | 32 | Integer[] expected = {1, 2, 3, 4, 5, 6, 7, 8}; 33 | for (Integer value : expected) { 34 | assertThat(q.dequeue(), is(equalTo(value))); 35 | } 36 | } 37 | 38 | @Test 39 | public void mustOrderUsingInPlaceApproach() { 40 | Integer[] S = {8, 2, 5, 4, 7, 1, 3, 6}; 41 | 42 | QuickSort.quickSortInPlace(S, new DefaultComparator<>(), 0, S.length - 1); 43 | 44 | Integer[] expected = {1, 2, 3, 4, 5, 6, 7, 8}; 45 | assertThat(S, is(equalTo(expected))); 46 | } 47 | } 48 | --------------------------------------------------------------------------------