[
  {
    "path": ".gitignore",
    "content": "Trees/.classpath\nTrees/.project\nTrees/.settings/org.eclipse.jdt.core.prefs\nTrees/.settings/org.eclipse.m2e.core.prefs\n"
  },
  {
    "path": "LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "README.md",
    "content": "# BinarySearchTrees\nJava binary search trees implementations and tests: AVL Tree, Red black tree, Scapegoat tree, Splay tree, Treap\n\nBlog post and benchmarks: https://intelligentjava.wordpress.com/2015/04/09/self-balancing-binary-search-trees-comparison/\n\nTo run benchmarks:  \ncd Trees  \nmvn clean install  \njava -jar target/benchmarks.jar  \n"
  },
  {
    "path": "Trees/.gitignore",
    "content": "/target/\n"
  },
  {
    "path": "Trees/pom.xml",
    "content": "<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <groupId>org.intelligentjava</groupId>\n  <artifactId>Trees</artifactId>\n  <version>0.0.1-SNAPSHOT</version>\n  \n  <dependencies>\n\n\t\t<!-- Microbenchmark -->\n\t\t<dependency>\n\t\t\t<groupId>org.openjdk.jmh</groupId>\n\t\t\t<artifactId>jmh-core</artifactId>\n\t\t\t<version>1.21</version>\n\t\t</dependency>\n\n\t\t<dependency>\n\t\t\t<groupId>org.openjdk.jmh</groupId>\n\t\t\t<artifactId>jmh-generator-annprocess</artifactId>\n\t\t\t<version>1.21</version>\n\t\t\t<!-- the processor artifact is required only during compilation and does \n\t\t\t\tnot need to be transitive, hence provided scope -->\n\t\t\t<scope>provided</scope>\n\t\t</dependency>\n\n\t\t<!-- Testing -->\n\t\t<dependency>\n\t\t\t<groupId>junit</groupId>\n\t\t\t<artifactId>junit</artifactId>\n\t\t\t<version>4.11</version>\n\t\t</dependency>\n\t</dependencies>\n\t\n\t<build>\n        <plugins>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-compiler-plugin</artifactId>\n                <version>3.1</version>\n                <configuration>\n                    <compilerVersion>1.7</compilerVersion>\n                    <source>1.7</source>\n                    <target>1.7</target>\n                </configuration>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-shade-plugin</artifactId>\n                <version>2.2</version>\n                <executions>\n                    <execution>\n                        <phase>package</phase>\n                        <goals>\n                            <goal>shade</goal>\n                        </goals>\n                        <configuration>\n                            <finalName>benchmarks</finalName>\n                            <transformers>\n                                <transformer implementation=\"org.apache.maven.plugins.shade.resource.ManifestResourceTransformer\">\n                                    <mainClass>org.openjdk.jmh.Main</mainClass>\n                                </transformer>\n                            </transformers>\n                        </configuration>\n                    </execution>\n                </executions>\n            </plugin>\n        </plugins>\n        <pluginManagement>\n            <plugins>\n                <plugin>\n                    <artifactId>maven-clean-plugin</artifactId>\n                    <version>2.5</version>\n                </plugin>\n                <plugin>\n                    <artifactId>maven-deploy-plugin</artifactId>\n                    <version>2.8.1</version>\n                </plugin>\n                <plugin>\n                    <artifactId>maven-install-plugin</artifactId>\n                    <version>2.5.1</version>\n                </plugin>\n                <plugin>\n                    <artifactId>maven-jar-plugin</artifactId>\n                    <version>2.4</version>\n                </plugin>\n                <plugin>\n                    <artifactId>maven-javadoc-plugin</artifactId>\n                    <version>2.9.1</version>\n                </plugin>\n                <plugin>\n                    <artifactId>maven-resources-plugin</artifactId>\n                    <version>2.6</version>\n                </plugin>\n                <plugin>\n                    <artifactId>maven-site-plugin</artifactId>\n                    <version>3.3</version>\n                </plugin>\n                <plugin>\n                    <artifactId>maven-source-plugin</artifactId>\n                    <version>2.2.1</version>\n                </plugin>\n                <plugin>\n                    <artifactId>maven-surefire-plugin</artifactId>\n                    <version>2.17</version>\n                </plugin>\n            </plugins>\n        </pluginManagement>\n    </build>\n  \n</project>"
  },
  {
    "path": "Trees/src/main/java/org/intelligentjava/algos/simplestructures/LinkedList.java",
    "content": "package org.intelligentjava.algos.simplestructures;\n\n/**\n * Standard simple non circular doubly linked Linked List implementation.\n * \n * @author Ignas Lelys\n * @created May 4, 2011\n *\n */\n// TODO iterator\npublic class LinkedList {\n    \n    private Entry head;\n    \n    // TODO error checking\n    public int get(int index) {\n        Entry entry = head;\n        for (int i = 0; i < index; i++) {\n            entry = entry.next;\n        }\n        return entry.element;\n    }\n    \n    public void insert(int element) {\n        Entry oldHead = this.head;\n        this.head = new Entry(null, oldHead, element);\n        if (oldHead != null) {\n            oldHead.previous = head;\n        }\n    }\n    \n    public void delete(int element) {\n        Entry elementEntry = search(element);\n        if (elementEntry != null) {\n            if (elementEntry.previous != null) {\n                elementEntry.previous.next = elementEntry.next;\n            } else {\n                this.head = elementEntry.next; // if no previous, that means we are deleting head\n            }\n            if (elementEntry.next != null) {\n                elementEntry.next.previous = elementEntry.previous;\n            }\n        }\n    }\n    \n    private Entry search(int key) {\n        Entry entry = head;\n        while (entry != null) {\n            if (entry.element == key) {\n                return entry;\n            }\n            entry = entry.next;\n        }\n        return null;\n    }\n    \n    private static class Entry {\n        public Entry(Entry previous, Entry next, int element) {\n            super();\n            this.previous = previous;\n            this.next = next;\n            this.element = element;\n        }\n        public Entry previous;\n        public Entry next;\n        public int element;\n    }\n}\n"
  },
  {
    "path": "Trees/src/main/java/org/intelligentjava/algos/simplestructures/PriorityQueue.java",
    "content": "package org.intelligentjava.algos.simplestructures;\n\nimport org.intelligentjava.algos.trees.utils.ArrayUtils;\nimport org.intelligentjava.algos.trees.utils.HeapUtils;\n\n/**\n * Priority queue implementation.\n * \n * @author Ignas Lelys\n * @created Apr 18, 2011\n * \n */\npublic class PriorityQueue {\n\n    private int[] heap;\n\n    private int heapSize = 0;\n\n    public PriorityQueue() {\n        heap = new int[100];\n    }\n\n    public void insertElement(int element) {\n        heapSize++;\n        heap[heapSize - 1] = Integer.MIN_VALUE;\n        changeElementValue(heapSize - 1, element);\n    }\n\n    public void changeElementValue(int index, int newValue) {\n        if (heap[index] > newValue) {\n            throw new RuntimeException(\"New value is smaller than old one.\");\n        }\n        heap[index] = newValue;\n        while (index > 0 && heap[HeapUtils.getParent(index)] < heap[index]) {\n            ArrayUtils.swap(heap, index, HeapUtils.getParent(index));\n            index = HeapUtils.getParent(index);\n        }\n    }\n\n    public int getElement() {\n        return heap[0];\n    }\n\n    public int removeElement() {\n        if (heapSize < 1) {\n            throw new RuntimeException();\n        }\n        int maxElement = heap[0];\n        heap[0] = heap[heapSize - 1];\n        heapSize--;\n        HeapUtils.maxHeapify(heap, 0, heapSize);\n        return maxElement;\n    }\n\n}\n"
  },
  {
    "path": "Trees/src/main/java/org/intelligentjava/algos/simplestructures/Queue.java",
    "content": "package org.intelligentjava.algos.simplestructures;\n\nimport org.intelligentjava.algos.trees.exceptions.QueueOverflowException;\n\n/**\n * Simple queue.\n * \n * @author Ignas Lelys\n * @created May 4, 2011\n * \n */\npublic class Queue {\n\n    private Object[] queue;\n\n    private int head = 0;\n\n    private int tail = 0;\n\n    public Queue() {\n        super();\n        queue = new Object[10];\n    }\n\n    public Queue(int queueSize) {\n        super();\n        queue = new Object[queueSize];\n    }\n\n    public void enqueue(Object element) throws QueueOverflowException {\n        if (isFull()) {\n            throw new QueueOverflowException();\n        }\n        queue[tail] = element;\n        if (tail == queue.length - 1) {\n            tail = 0;\n        } else {\n            tail++;\n        }\n    }\n\n    public Object dequeue() {\n        Object element = queue[head];\n        if (head == queue.length - 1) {\n            head = 0;\n        } else {\n            head++;\n        }\n        return element;\n    }\n\n    public boolean isEmpty() {\n        return head == tail;\n    }\n    \n    public boolean isFull() {\n        int nextTailValue = tail;\n        if (nextTailValue == queue.length - 1) {\n            nextTailValue = 0;\n        } else {\n            nextTailValue++;\n        }\n        if (head == nextTailValue) {\n            return true;\n        } else {\n            return false;\n        }\n    }\n}\n"
  },
  {
    "path": "Trees/src/main/java/org/intelligentjava/algos/simplestructures/Stack.java",
    "content": "package org.intelligentjava.algos.simplestructures;\n\nimport java.util.Arrays;\n\n/**\n * Stack.\n * \n * @author Ignas Lelys\n * @created May 4, 2011\n *\n */\npublic class Stack {\n    \n    private Object[] elements;\n    \n    private int top = 0;\n    \n    public Stack() {\n        super();\n        elements = new Object[10];\n    }\n    \n    public Stack(int initialSize) {\n        super();\n        elements = new Object[initialSize];\n    }\n\n    public boolean isEmpty() {\n        return top == 0;\n    }\n    \n    public void push(Object element) {\n        if (top == elements.length) {\n            elements = Arrays.copyOf(elements, elements.length + 10);\n        }\n        elements[top] = element;\n        top++;\n    }\n    \n    public Object pop() {\n        if (!isEmpty()) {\n            return elements[--top];\n        }\n        return null;\n    }\n\n}\n"
  },
  {
    "path": "Trees/src/main/java/org/intelligentjava/algos/trees/AVLTree.java",
    "content": "package org.intelligentjava.algos.trees;\n\nimport org.intelligentjava.algos.trees.utils.MathUtils;\n\n/**\n * AVL tree implementation.\n * \n * In computer science, an AVL tree is a self-balancing binary search tree, and\n * it was the first such data structure to be invented.[1] In an AVL tree, the\n * heights of the two child subtrees of any node differ by at most one. Lookup,\n * insertion, and deletion all take O(log n) time in both the average and worst\n * cases, where n is the number of nodes in the tree prior to the operation.\n * Insertions and deletions may require the tree to be rebalanced by one or more\n * tree rotations.\n * \n * @author Ignas Lelys\n * @created Jun 28, 2011\n * \n */\npublic class AVLTree extends AbstractSelfBalancingBinarySearchTree {\n\n    /**\n     * @see org.intelligentjava.algos.trees.AbstractBinarySearchTree#insert(int)\n     * \n     *      AVL tree insert method also balances tree if needed. Additional\n     *      height parameter on node is used to track if one subtree is higher\n     *      than other by more than one, if so AVL tree rotations is performed\n     *      to regain balance of the tree.\n     */\n    @Override\n    public Node insert(int element) {\n        Node newNode = super.insert(element);\n        rebalance((AVLNode)newNode);\n        return newNode;\n    }\n\n    /**\n     * @see org.intelligentjava.algos.trees.AbstractBinarySearchTree#delete(int)\n     */\n    @Override\n    public Node delete(int element) {\n        Node deleteNode = super.search(element);\n        if (deleteNode != null) {\n            Node successorNode = super.delete(deleteNode);\n            if (successorNode != null) {\n                // if replaced from getMinimum(deleteNode.right) then come back there and update heights\n                AVLNode minimum = successorNode.right != null ? (AVLNode)getMinimum(successorNode.right) : (AVLNode)successorNode;\n                recomputeHeight(minimum);\n                rebalance((AVLNode)minimum);\n            } else {\n                recomputeHeight((AVLNode)deleteNode.parent);\n                rebalance((AVLNode)deleteNode.parent);\n            }\n            return successorNode;\n        }\n        return null;\n    }\n    \n    /**\n     * @see org.intelligentjava.algos.trees.AbstractBinarySearchTree#createNode(int, org.intelligentjava.algos.trees.AbstractBinarySearchTree.Node, org.intelligentjava.algos.trees.AbstractBinarySearchTree.Node, org.intelligentjava.algos.trees.AbstractBinarySearchTree.Node)\n     */\n    @Override\n    protected Node createNode(int value, Node parent, Node left, Node right) {\n        return new AVLNode(value, parent, left, right);\n    }\n\n    /**\n     * Go up from inserted node, and update height and balance informations if needed.\n     * If some node balance reaches 2 or -2 that means that subtree must be rebalanced.\n     * \n     * @param node Inserted Node.\n     */\n    private void rebalance(AVLNode node) {\n        while (node != null) {\n            \n            Node parent = node.parent;\n            \n            int leftHeight = (node.left == null) ? -1 : ((AVLNode) node.left).height;\n            int rightHeight = (node.right == null) ? -1 : ((AVLNode) node.right).height;\n            int nodeBalance = rightHeight - leftHeight;\n            // rebalance (-2 means left subtree outgrow, 2 means right subtree)\n            if (nodeBalance == 2) {\n                if (node.right.right != null) {\n                    node = (AVLNode)avlRotateLeft(node);\n                    break;\n                } else {\n                    node = (AVLNode)doubleRotateRightLeft(node);\n                    break;\n                }\n            } else if (nodeBalance == -2) {\n                if (node.left.left != null) {\n                    node = (AVLNode)avlRotateRight(node);\n                    break;\n                } else {\n                    node = (AVLNode)doubleRotateLeftRight(node);\n                    break;\n                }\n            } else {\n                updateHeight(node);\n            }\n            \n            node = (AVLNode)parent;\n        }\n    }\n\n    /**\n     * Rotates to left side.\n     */\n    private Node avlRotateLeft(Node node) {\n        Node temp = super.rotateLeft(node);\n        \n        updateHeight((AVLNode)temp.left);\n        updateHeight((AVLNode)temp);\n        return temp;\n    }\n\n    /**\n     * Rotates to right side.\n     */\n    private Node avlRotateRight(Node node) {\n        Node temp = super.rotateRight(node);\n\n        updateHeight((AVLNode)temp.right);\n        updateHeight((AVLNode)temp);\n        return temp;\n    }\n\n    /**\n     * Take right child and rotate it to the right side first and then rotate\n     * node to the left side.\n     */\n    protected Node doubleRotateRightLeft(Node node) {\n        node.right = avlRotateRight(node.right);\n        return avlRotateLeft(node);\n    }\n\n    /**\n     * Take right child and rotate it to the right side first and then rotate\n     * node to the left side.\n     */\n    protected Node doubleRotateLeftRight(Node node) {\n        node.left = avlRotateLeft(node.left);\n        return avlRotateRight(node);\n    }\n    \n    /**\n     * Recomputes height information from the node and up for all of parents. It needs to be done after delete.\n     */\n    private void recomputeHeight(AVLNode node) {\n       while (node != null) {\n          node.height = maxHeight((AVLNode)node.left, (AVLNode)node.right) + 1;\n          node = (AVLNode)node.parent;\n       }\n    }\n    \n    /**\n     * Returns higher height of 2 nodes. \n     */\n    private int maxHeight(AVLNode node1, AVLNode node2) {\n        if (node1 != null && node2 != null) {\n            return node1.height > node2.height ? node1.height : node2.height;\n        } else if (node1 == null) {\n            return node2 != null ? node2.height : -1;\n        } else if (node2 == null) {\n            return node1 != null ? node1.height : -1;\n        }\n        return -1;\n    }\n\n    /**\n     * Updates height and balance of the node.\n     * \n     * @param node Node for which height and balance must be updated.\n     */\n    private static final void updateHeight(AVLNode node) {\n        int leftHeight = (node.left == null) ? -1 : ((AVLNode) node.left).height;\n        int rightHeight = (node.right == null) ? -1 : ((AVLNode) node.right).height;\n        node.height = 1 + MathUtils.getMax(leftHeight, rightHeight);\n    }\n\n    /**\n     * Node of AVL tree has height and balance additional properties. If balance\n     * equals 2 (or -2) that node needs to be re balanced. (Height is height of\n     * the subtree starting with this node, and balance is difference between\n     * left and right nodes heights).\n     * \n     * @author Ignas Lelys\n     * @created Jun 30, 2011\n     * \n     */\n    protected static class AVLNode extends Node {\n        public int height;\n\n        public AVLNode(int value, Node parent, Node left, Node right) {\n            super(value, parent, left, right);\n        }\n    }\n\n}\n"
  },
  {
    "path": "Trees/src/main/java/org/intelligentjava/algos/trees/AbstractBinarySearchTree.java",
    "content": "package org.intelligentjava.algos.trees;\n\n/**\n * Abstract binary search tree implementation. Its basically fully implemented\n * binary search tree, just template method is provided for creating Node (other\n * trees can have slightly different nodes with more info). This way some code\n * from standart binary search tree can be reused for other kinds of binary\n * trees.\n * \n * @author Ignas Lelys\n * @created Jun 29, 2011\n * \n */\npublic abstract class AbstractBinarySearchTree {\n\n    /** Root node where whole tree starts. */\n    public Node root;\n\n    /** Tree size. */\n    protected int size;\n\n    /**\n     * Because this is abstract class and various trees have different additional information on \n     * different nodes subclasses uses this abstract method to create nodes (maybe of class {@link Node}\n     * or maybe some different node sub class).\n     * \n     * @param value Value that node will have.\n     * @param parent Node's parent.\n     * @param left Node's left child.\n     * @param right Node's right child.\n     * @return Created node instance.\n     */\n    protected abstract Node createNode(int value, Node parent, Node left, Node right);\n\n    /**\n     * Finds a node with concrete value. If it is not found then null is\n     * returned.\n     * \n     * @param element\n     *            Element value.\n     * @return Node with value provided, or null if not found.\n     */\n    public Node search(int element) {\n        Node node = root;\n        while (node != null && node.value != null && node.value != element) {\n            if (element < node.value) {\n                node = node.left;\n            } else {\n                node = node.right;\n            }\n        }\n        return node;\n    }\n\n    /**\n     * Insert new element to tree.\n     * \n     * @param element\n     *            Element to insert.\n     */\n    public Node insert(int element) {\n        if (root == null) {\n            root = createNode(element, null, null, null);\n            size++;\n            return root;\n        }\n\n        Node insertParentNode = null;\n        Node searchTempNode = root;\n        while (searchTempNode != null && searchTempNode.value != null) {\n            insertParentNode = searchTempNode;\n            if (element < searchTempNode.value) {\n                searchTempNode = searchTempNode.left;\n            } else {\n                searchTempNode = searchTempNode.right;\n            }\n        }\n\n        Node newNode = createNode(element, insertParentNode, null, null);\n        if (insertParentNode.value > newNode.value) {\n            insertParentNode.left = newNode;\n        } else {\n            insertParentNode.right = newNode;\n        }\n\n        size++;\n        return newNode;\n    }\n\n    /**\n     * Removes element if node with such value exists.\n     * \n     * @param element\n     *            Element value to remove.\n     * \n     * @return New node that is in place of deleted node. Or null if element for\n     *         delete was not found.\n     */\n    public Node delete(int element) {\n        Node deleteNode = search(element);\n        if (deleteNode != null) {\n            return delete(deleteNode);\n        } else {\n            return null;\n        }\n    }\n\n    /**\n     * Delete logic when node is already found.\n     * \n     * @param deleteNode\n     *            Node that needs to be deleted.\n     * \n     * @return New node that is in place of deleted node. Or null if element for\n     *         delete was not found.\n     */\n    protected Node delete(Node deleteNode) {\n        if (deleteNode != null) {\n            Node nodeToReturn = null;\n            if (deleteNode != null) {\n                if (deleteNode.left == null) {\n                    nodeToReturn = transplant(deleteNode, deleteNode.right);\n                } else if (deleteNode.right == null) {\n                    nodeToReturn = transplant(deleteNode, deleteNode.left);\n                } else {\n                    Node successorNode = getMinimum(deleteNode.right);\n                    if (successorNode.parent != deleteNode) {\n                        transplant(successorNode, successorNode.right);\n                        successorNode.right = deleteNode.right;\n                        successorNode.right.parent = successorNode;\n                    }\n                    transplant(deleteNode, successorNode);\n                    successorNode.left = deleteNode.left;\n                    successorNode.left.parent = successorNode;\n                    nodeToReturn = successorNode;\n                }\n                size--;\n            }\n    \n            return nodeToReturn;\n        }\n        return null;\n    }\n\n    /**\n     * Put one node from tree (newNode) to the place of another (nodeToReplace).\n     * \n     * @param nodeToReplace\n     *            Node which is replaced by newNode and removed from tree.\n     * @param newNode\n     *            New node.\n     * \n     * @return New replaced node.\n     */\n    private Node transplant(Node nodeToReplace, Node newNode) {\n        if (nodeToReplace.parent == null) {\n            this.root = newNode;\n        } else if (nodeToReplace == nodeToReplace.parent.left) {\n            nodeToReplace.parent.left = newNode;\n        } else {\n            nodeToReplace.parent.right = newNode;\n        }\n        if (newNode != null) {\n            newNode.parent = nodeToReplace.parent;\n        }\n        return newNode;\n    }\n\n    /**\n     * @param element\n     * @return true if tree contains element.\n     */\n    public boolean contains(int element) {\n        return search(element) != null;\n    }\n\n    /**\n     * @return Minimum element in tree.\n     */\n    public int getMinimum() {\n        return getMinimum(root).value;\n    }\n\n    /**\n     * @return Maximum element in tree.\n     */\n    public int getMaximum() {\n        return getMaximum(root).value;\n    }\n\n    /**\n     * Get next element element who is bigger than provided element.\n     * \n     * @param element\n     *            Element for whom descendand element is searched\n     * @return Successor value.\n     */\n    // TODO Predecessor\n    public int getSuccessor(int element) {\n        return getSuccessor(search(element)).value;\n    }\n\n    /**\n     * @return Number of elements in the tree.\n     */\n    public int getSize() {\n        return size;\n    }\n\n    /**\n     * Tree traversal with printing element values. In order method.\n     */\n    public void printTreeInOrder() {\n        printTreeInOrder(root);\n    }\n\n    /**\n     * Tree traversal with printing element values. Pre order method.\n     */\n    public void printTreePreOrder() {\n        printTreePreOrder(root);\n    }\n\n    /**\n     * Tree traversal with printing element values. Post order method.\n     */\n    public void printTreePostOrder() {\n        printTreePostOrder(root);\n    }\n\n    /*-------------------PRIVATE HELPER METHODS-------------------*/\n\n    private void printTreeInOrder(Node entry) {\n        if (entry != null) {\n            printTreeInOrder(entry.left);\n            if (entry.value != null) {\n                System.out.println(entry.value);\n            }\n            printTreeInOrder(entry.right);\n        }\n    }\n\n    private void printTreePreOrder(Node entry) {\n        if (entry != null) {\n            if (entry.value != null) {\n                System.out.println(entry.value);\n            }\n            printTreeInOrder(entry.left);\n            printTreeInOrder(entry.right);\n        }\n    }\n\n    private void printTreePostOrder(Node entry) {\n        if (entry != null) {\n            printTreeInOrder(entry.left);\n            printTreeInOrder(entry.right);\n            if (entry.value != null) {\n                System.out.println(entry.value);\n            }\n        }\n    }\n\n    protected Node getMinimum(Node node) {\n        while (node.left != null) {\n            node = node.left;\n        }\n        return node;\n    }\n\n    protected Node getMaximum(Node node) {\n        while (node.right != null) {\n            node = node.right;\n        }\n        return node;\n    }\n\n    protected Node getSuccessor(Node node) {\n        // if there is right branch, then successor is leftmost node of that\n        // subtree\n        if (node.right != null) {\n            return getMinimum(node.right);\n        } else { // otherwise it is a lowest ancestor whose left child is also\n            // ancestor of node\n            Node currentNode = node;\n            Node parentNode = node.parent;\n            while (parentNode != null && currentNode == parentNode.right) {\n                // go up until we find parent that currentNode is not in right\n                // subtree.\n                currentNode = parentNode;\n                parentNode = parentNode.parent;\n            }\n            return parentNode;\n        }\n    }\n    \n    //-------------------------------- TREE PRINTING ------------------------------------\n\n    public void printTree() {\n        printSubtree(root);\n    }\n    \n    public void printSubtree(Node node) {\n        if (node.right != null) {\n            printTree(node.right, true, \"\");\n        }\n        printNodeValue(node);\n        if (node.left != null) {\n            printTree(node.left, false, \"\");\n        }\n    }\n    \n    private void printNodeValue(Node node) {\n        if (node.value == null) {\n            System.out.print(\"<null>\");\n        } else {\n            System.out.print(node.value.toString());\n        }\n        System.out.println();\n    }\n    \n    private void printTree(Node node, boolean isRight, String indent) {\n        if (node.right != null) {\n            printTree(node.right, true, indent + (isRight ? \"        \" : \" |      \"));\n        }\n        System.out.print(indent);\n        if (isRight) {\n            System.out.print(\" /\");\n        } else {\n            System.out.print(\" \\\\\");\n        }\n        System.out.print(\"----- \");\n        printNodeValue(node);\n        if (node.left != null) {\n            printTree(node.left, false, indent + (isRight ? \" |      \" : \"        \"));\n        }\n    }\n\n\n    public static class Node {\n        public Node(Integer value, Node parent, Node left, Node right) {\n            super();\n            this.value = value;\n            this.parent = parent;\n            this.left = left;\n            this.right = right;\n        }\n\n        public Integer value;\n        public Node parent;\n        public Node left;\n        public Node right;\n        \n        public boolean isLeaf() {\n            return left == null && right == null;\n        }\n\n        @Override\n        public int hashCode() {\n            final int prime = 31;\n            int result = 1;\n            result = prime * result + ((value == null) ? 0 : value.hashCode());\n            return result;\n        }\n\n        @Override\n        public boolean equals(Object obj) {\n            if (this == obj)\n                return true;\n            if (obj == null)\n                return false;\n            if (getClass() != obj.getClass())\n                return false;\n            Node other = (Node) obj;\n            if (value == null) {\n                if (other.value != null)\n                    return false;\n            } else if (!value.equals(other.value))\n                return false;\n            return true;\n        }\n\n    }\n}\n"
  },
  {
    "path": "Trees/src/main/java/org/intelligentjava/algos/trees/AbstractSelfBalancingBinarySearchTree.java",
    "content": "package org.intelligentjava.algos.trees;\n\n/**\n * Abstract class for self balancing binary search trees. Contains some methods\n * that is used for self balancing trees.\n * \n * @author Ignas Lelys\n * @created Jul 24, 2011\n * \n */\npublic abstract class AbstractSelfBalancingBinarySearchTree extends AbstractBinarySearchTree {\n\n    /**\n     * Rotate to the left.\n     * \n     * @param node Node on which to rotate.\n     * @return Node that is in place of provided node after rotation.\n     */\n    protected Node rotateLeft(Node node) {\n        Node temp = node.right;\n        temp.parent = node.parent;\n\n        node.right = temp.left;\n        if (node.right != null) {\n            node.right.parent = node;\n        }\n\n        temp.left = node;\n        node.parent = temp;\n\n        // temp took over node's place so now its parent should point to temp\n        if (temp.parent != null) {\n            if (node == temp.parent.left) {\n                temp.parent.left = temp;\n            } else {\n                temp.parent.right = temp;\n            }\n        } else {\n            root = temp;\n        }\n        \n        return temp;\n    }\n\n    /**\n     * Rotate to the right.\n     * \n     * @param node Node on which to rotate.\n     * @return Node that is in place of provided node after rotation.\n     */\n    protected Node rotateRight(Node node) {\n        Node temp = node.left;\n        temp.parent = node.parent;\n\n        node.left = temp.right;\n        if (node.left != null) {\n            node.left.parent = node;\n        }\n\n        temp.right = node;\n        node.parent = temp;\n\n        // temp took over node's place so now its parent should point to temp\n        if (temp.parent != null) {\n            if (node == temp.parent.left) {\n                temp.parent.left = temp;\n            } else {\n                temp.parent.right = temp;\n            }\n        } else {\n            root = temp;\n        }\n        \n        return temp;\n    }\n\n}\n"
  },
  {
    "path": "Trees/src/main/java/org/intelligentjava/algos/trees/BinarySearchTree.java",
    "content": "package org.intelligentjava.algos.trees;\n\n/**\n * Binary search tree implementation.\n * \n * In computer science, a binary search tree (BST), which may sometimes also be\n * called an ordered or sorted binary tree, is a node-based binary tree data\n * structure which has the following properties:\n * \n * a) The left subtree of a node contains only nodes with keys less than the node's key. </br>\n * b) The right subtree of a node contains only nodes with keys greater than the node's key. </br>\n * c) Both the left and right subtrees must also be binary search trees. </br>\n * \n * @author Ignas Lelys\n * @created May 6, 2011\n * \n */\npublic class BinarySearchTree extends AbstractBinarySearchTree {\n\n    @Override\n    protected Node createNode(int value, Node parent, Node left, Node right) {\n        return new Node(value, parent, left, right);\n    }\n\n}\n"
  },
  {
    "path": "Trees/src/main/java/org/intelligentjava/algos/trees/RedBlackTree.java",
    "content": "package org.intelligentjava.algos.trees;\n\n/**\n * Red-Black tree implementation. From Introduction to Algorithms 3rd edition.\n * \n * @author Ignas Lelys\n * @created May 6, 2011\n * \n */\npublic class RedBlackTree extends AbstractSelfBalancingBinarySearchTree {\n\n    protected enum ColorEnum {\n        RED,\n        BLACK\n    };\n\n    protected static final RedBlackNode nilNode = new RedBlackNode(null, null, null, null, ColorEnum.BLACK);\n\n    /**\n     * @see org.intelligentjava.algos.trees.AbstractBinarySearchTree#insert(int)\n     */\n    @Override\n    public Node insert(int element) {\n        Node newNode = super.insert(element);\n        newNode.left = nilNode;\n        newNode.right = nilNode;\n        root.parent = nilNode;\n        insertRBFixup((RedBlackNode) newNode);\n        return newNode;\n    }\n    \n    /**\n     * Slightly modified delete routine for red-black tree.\n     * \n     * {@inheritDoc}\n     */\n    @Override\n    protected Node delete(Node deleteNode) {\n        Node replaceNode = null; // track node that replaces removedOrMovedNode\n        if (deleteNode != null && deleteNode != nilNode) {\n            Node removedOrMovedNode = deleteNode; // same as deleteNode if it has only one child, and otherwise it replaces deleteNode\n            ColorEnum removedOrMovedNodeColor = ((RedBlackNode)removedOrMovedNode).color;\n        \n            if (deleteNode.left == nilNode) {\n                replaceNode = deleteNode.right;\n                rbTreeTransplant(deleteNode, deleteNode.right);\n            } else if (deleteNode.right == nilNode) {\n                replaceNode = deleteNode.left;\n                rbTreeTransplant(deleteNode, deleteNode.left);\n            } else {\n                removedOrMovedNode = getMinimum(deleteNode.right);\n                removedOrMovedNodeColor = ((RedBlackNode)removedOrMovedNode).color;\n                replaceNode = removedOrMovedNode.right;\n                if (removedOrMovedNode.parent == deleteNode) {\n                    replaceNode.parent = removedOrMovedNode;\n                } else {\n                    rbTreeTransplant(removedOrMovedNode, removedOrMovedNode.right);\n                    removedOrMovedNode.right = deleteNode.right;\n                    removedOrMovedNode.right.parent = removedOrMovedNode;\n                }\n                rbTreeTransplant(deleteNode, removedOrMovedNode);\n                removedOrMovedNode.left = deleteNode.left;\n                removedOrMovedNode.left.parent = removedOrMovedNode;\n                ((RedBlackNode)removedOrMovedNode).color = ((RedBlackNode)deleteNode).color;\n            }\n            \n            size--;\n            if (removedOrMovedNodeColor == ColorEnum.BLACK) {\n                deleteRBFixup((RedBlackNode)replaceNode);\n            }\n        }\n        \n        return replaceNode;\n    }\n    \n    /**\n     * @see org.intelligentjava.algos.trees.AbstractBinarySearchTree#createNode(int, org.intelligentjava.algos.trees.AbstractBinarySearchTree.Node, org.intelligentjava.algos.trees.AbstractBinarySearchTree.Node, org.intelligentjava.algos.trees.AbstractBinarySearchTree.Node)\n     */\n    @Override\n    protected Node createNode(int value, Node parent, Node left, Node right) {\n        return new RedBlackNode(value, parent, left, right, ColorEnum.RED);\n    }\n    \n    /**\n     * {@inheritDoc}\n     */\n    @Override\n    protected Node getMinimum(Node node) {\n        while (node.left != nilNode) {\n            node = node.left;\n        }\n        return node;\n    }\n\n    /**\n     * {@inheritDoc}\n     */\n    @Override\n    protected Node getMaximum(Node node) {\n        while (node.right != nilNode) {\n            node = node.right;\n        }\n        return node;\n    }\n    \n    /**\n     * {@inheritDoc}\n     */\n    @Override\n    protected Node rotateLeft(Node node) {\n        Node temp = node.right;\n        temp.parent = node.parent;\n        \n        node.right = temp.left;\n        if (node.right != nilNode) {\n            node.right.parent = node;\n        }\n\n        temp.left = node;\n        node.parent = temp;\n\n        // temp took over node's place so now its parent should point to temp\n        if (temp.parent != nilNode) {\n            if (node == temp.parent.left) {\n                temp.parent.left = temp;\n            } else {\n                temp.parent.right = temp;\n            }\n        } else {\n            root = temp;\n        }\n        \n        return temp;\n    }\n\n    /**\n     * {@inheritDoc}\n     */\n    @Override\n    protected Node rotateRight(Node node) {\n        Node temp = node.left;\n        temp.parent = node.parent;\n\n        node.left = temp.right;\n        if (node.left != nilNode) {\n            node.left.parent = node;\n        }\n\n        temp.right = node;\n        node.parent = temp;\n\n        // temp took over node's place so now its parent should point to temp\n        if (temp.parent != nilNode) {\n            if (node == temp.parent.left) {\n                temp.parent.left = temp;\n            } else {\n                temp.parent.right = temp;\n            }\n        } else {\n            root = temp;\n        }\n        \n        return temp;\n    }\n\n    \n    /**\n     * Similar to original transplant() method in BST but uses nilNode instead of null.\n     */\n    private Node rbTreeTransplant(Node nodeToReplace, Node newNode) {\n        if (nodeToReplace.parent == nilNode) {\n            this.root = newNode;\n        } else if (nodeToReplace == nodeToReplace.parent.left) {\n            nodeToReplace.parent.left = newNode;\n        } else {\n            nodeToReplace.parent.right = newNode;\n        }\n        newNode.parent = nodeToReplace.parent;\n        return newNode;\n    }\n    \n    /**\n     * Restores Red-Black tree properties after delete if needed.\n     */\n    private void deleteRBFixup(RedBlackNode x) {\n        while (x != root && isBlack(x)) {\n            \n            if (x == x.parent.left) {\n                RedBlackNode w = (RedBlackNode)x.parent.right;\n                if (isRed(w)) { // case 1 - sibling is red\n                    w.color = ColorEnum.BLACK;\n                    ((RedBlackNode)x.parent).color = ColorEnum.RED;\n                    rotateLeft(x.parent);\n                    w = (RedBlackNode)x.parent.right; // converted to case 2, 3 or 4\n                }\n                // case 2 sibling is black and both of its children are black\n                if (isBlack(w.left) && isBlack(w.right)) {\n                    w.color = ColorEnum.RED;\n                    x = (RedBlackNode)x.parent;\n                } else if (w != nilNode) {\n                    if (isBlack(w.right)) { // case 3 sibling is black and its left child is red and right child is black\n                        ((RedBlackNode)w.left).color = ColorEnum.BLACK;\n                        w.color = ColorEnum.RED;\n                        rotateRight(w);\n                        w = (RedBlackNode)x.parent.right;\n                    }\n                    w.color = ((RedBlackNode)x.parent).color; // case 4 sibling is black and right child is red\n                    ((RedBlackNode)x.parent).color = ColorEnum.BLACK;\n                    ((RedBlackNode)w.right).color = ColorEnum.BLACK;\n                    rotateLeft(x.parent);\n                    x = (RedBlackNode)root;\n                } else {\n                    x.color = ColorEnum.BLACK;\n                    x = (RedBlackNode)x.parent;\n                }\n            } else {\n                RedBlackNode w = (RedBlackNode)x.parent.left;\n                if (isRed(w)) { // case 1 - sibling is red\n                    w.color = ColorEnum.BLACK;\n                    ((RedBlackNode)x.parent).color = ColorEnum.RED;\n                    rotateRight(x.parent);\n                    w = (RedBlackNode)x.parent.left; // converted to case 2, 3 or 4\n                }\n                // case 2 sibling is black and both of its children are black\n                if (isBlack(w.left) && isBlack(w.right)) {\n                    w.color = ColorEnum.RED;\n                    x = (RedBlackNode)x.parent;\n                } else if (w != nilNode) {\n                    if (isBlack(w.left)) { // case 3 sibling is black and its right child is red and left child is black\n                        ((RedBlackNode)w.right).color = ColorEnum.BLACK;\n                        w.color = ColorEnum.RED;\n                        rotateLeft(w);\n                        w = (RedBlackNode)x.parent.left;\n                    }\n                    w.color = ((RedBlackNode)x.parent).color; // case 4 sibling is black and left child is red\n                    ((RedBlackNode)x.parent).color = ColorEnum.BLACK;\n                    ((RedBlackNode)w.left).color = ColorEnum.BLACK;\n                    rotateRight(x.parent);\n                    x = (RedBlackNode)root;\n                } else {\n                    x.color = ColorEnum.BLACK;\n                    x = (RedBlackNode)x.parent;\n                }\n            }\n            \n        }\n    }\n    \n    private boolean isBlack(Node node) {\n        return node != null ? ((RedBlackNode)node).color == ColorEnum.BLACK : false;\n    }\n    \n    private boolean isRed(Node node) {\n        return node != null ? ((RedBlackNode)node).color == ColorEnum.RED : false;\n    }\n\n    /**\n     * Restores Red-Black tree properties after insert if needed. Insert can\n     * break only 2 properties: root is red or if node is red then children must\n     * be black.\n     */\n    private void insertRBFixup(RedBlackNode currentNode) {\n        // current node is always RED, so if its parent is red it breaks\n        // Red-Black property, otherwise no fixup needed and loop can terminate\n        while (currentNode.parent != root && ((RedBlackNode) currentNode.parent).color == ColorEnum.RED) {\n            RedBlackNode parent = (RedBlackNode) currentNode.parent;\n            RedBlackNode grandParent = (RedBlackNode) parent.parent;\n            if (parent == grandParent.left) {\n                RedBlackNode uncle = (RedBlackNode) grandParent.right;\n                // case1 - uncle and parent are both red\n                // re color both of them to black\n                if (((RedBlackNode) uncle).color == ColorEnum.RED) {\n                    parent.color = ColorEnum.BLACK;\n                    uncle.color = ColorEnum.BLACK;\n                    grandParent.color = ColorEnum.RED;\n                    // grandparent was recolored to red, so in next iteration we\n                    // check if it does not break Red-Black property\n                    currentNode = grandParent;\n                } \n                // case 2/3 uncle is black - then we perform rotations\n                else {\n                    if (currentNode == parent.right) { // case 2, first rotate left\n                        currentNode = parent;\n                        rotateLeft(currentNode);\n                        parent = (RedBlackNode) currentNode.parent;\n                    }\n                    // do not use parent\n                    parent.color = ColorEnum.BLACK; // case 3\n                    grandParent.color = ColorEnum.RED;\n                    rotateRight(grandParent);\n                }\n            } else if (parent == grandParent.right) {\n                RedBlackNode uncle = (RedBlackNode) grandParent.left;\n                // case1 - uncle and parent are both red\n                // re color both of them to black\n                if (((RedBlackNode) uncle).color == ColorEnum.RED) {\n                    parent.color = ColorEnum.BLACK;\n                    uncle.color = ColorEnum.BLACK;\n                    grandParent.color = ColorEnum.RED;\n                    // grandparent was recolored to red, so in next iteration we\n                    // check if it does not break Red-Black property\n                    currentNode = grandParent;\n                }\n                // case 2/3 uncle is black - then we perform rotations\n                else {\n                    if (currentNode == parent.left) { // case 2, first rotate right\n                        currentNode = parent;\n                        rotateRight(currentNode);\n                        parent = (RedBlackNode) currentNode.parent;\n                    }\n                    // do not use parent\n                    parent.color = ColorEnum.BLACK; // case 3\n                    grandParent.color = ColorEnum.RED;\n                    rotateLeft(grandParent);\n                }\n            }\n\n        }\n        // ensure root is black in case it was colored red in fixup\n        ((RedBlackNode) root).color = ColorEnum.BLACK;\n    }\n\n    protected static class RedBlackNode extends Node {\n        public ColorEnum color;\n\n        public RedBlackNode(Integer value, Node parent, Node left, Node right, ColorEnum color) {\n            super(value, parent, left, right);\n            this.color = color;\n        }\n    }\n\n}\n"
  },
  {
    "path": "Trees/src/main/java/org/intelligentjava/algos/trees/ScapegoatTree.java",
    "content": "package org.intelligentjava.algos.trees;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Stack;\n\nimport org.intelligentjava.algos.trees.utils.MathUtils;\n\n/**\n * Scapegoat tree non recursive implementation.\n * Warning: not sure if my implementations is really correct, didn't have time to learn more about scapegoat trees.\n * \n * @author Ignas Lelys\n * @created Jul 28, 2011\n * \n */\npublic class ScapegoatTree extends AbstractSelfBalancingBinarySearchTree {\n\n    /** Alpha parameter. */\n    private double alpha = 0.57;\n    \n    private int maxSize = 0;\n    \n    /**\n     * Constructor.\n     */\n    public ScapegoatTree() {\n        super();\n    }\n\n    /**\n     * Constructor.\n     * \n     * @param alpha Alpha parameter.\n     */\n    public ScapegoatTree(double alpha) {\n        super();\n        this.alpha = alpha;\n    }\n\n    /**\n     * {@inheritDoc}\n     */\n    @Override\n    public Node insert(int element) {\n        Node inserted = super.insert(element);\n        int height = getNodeHeight(inserted);\n        if (height > getHAlpha()) {\n            Node scapegoat = findScapegoatNode(inserted);\n            Node scapegoatParent = scapegoat.parent;\n            boolean scapegoatOnParentsLeft = scapegoatParent != null && scapegoatParent.left == scapegoat;\n            Node rebuiltSubtree = rebuildTree(getSubtreeSize(scapegoat), scapegoat);\n            rebuiltSubtree.parent = scapegoatParent;\n            if (scapegoatParent != null) {\n                if (scapegoatOnParentsLeft) {\n                    scapegoatParent.left = rebuiltSubtree;\n                } else {\n                    scapegoatParent.right = rebuiltSubtree;\n                }\n            }\n            if (scapegoat == root) {\n                root = rebuiltSubtree;\n            }\n            maxSize = getSize();\n        }\n        return inserted;\n    }\n    \n    /**\n     * {@inheritDoc}\n     */\n    @Override\n    public Node delete(int element) {\n        Node replaceNode = super.delete(element);\n        if (getSize() <= alpha * maxSize) {\n            root = rebuildTree(getSize(), root);\n            maxSize = getSize();\n        }\n        return replaceNode;\n    }\n    \n    /**\n     * {@inheritDoc}\n     */\n    @Override\n    protected Node createNode(int value, Node parent, Node left, Node right) {\n        return new Node(value, parent, left, right);\n    }\n    \n    /**\n     * Finds scapegoat node which is used for rebalancing the tree.\n     * \n     * @return Scapegoat node.\n     */\n    protected Node findScapegoatNode(Node node) {\n        int size = 1;\n        int height = 0;\n        int totalSize = 0;\n        while (node.parent != null) {\n            height++;\n            totalSize = 1 + size + getSubtreeSize(getSibling(node));\n            if (height > Math.floor(MathUtils.logarithm(1 / alpha, totalSize))) {\n                return node.parent;\n            }\n            node = node.parent;\n            size = totalSize;\n        }\n        return null;\n    }\n\n    /**\n     * Rebuilds unbalanced tree.\n     * Found this implementation much clearer and easier to make it work: https://github.com/satchamo/Scapegoat-Tree/blob/master/scapegoat.py\n     * Could't get implementations from pdfs to work.\n     * \n     * @param size Size of subtree.\n     * @param scapegoat Scapegoat is the root of subtree of {@link size} number of nodes.\n     * \n     * @return Balanced subtree.\n     */\n    protected Node rebuildTree(int size, Node scapegoat) {\n        List<Node> nodes = new ArrayList<Node>();\n        \n        // flatten tree without recursion\n        Node currentNode = scapegoat;\n        boolean done = false;\n        Stack<Node> stack = new Stack<>();\n        while (!done) {\n            if (currentNode != null) {\n                stack.push(currentNode);\n                currentNode = currentNode.left;\n            } else {\n                if (!stack.isEmpty()) {\n                    currentNode = stack.pop();\n                    nodes.add(currentNode);\n                    currentNode = currentNode.right;\n                } else {\n                    done = true;\n                }\n            }\n        }\n        \n        // build tree from flattened list of nodes\n        return buildTree(nodes, 0, size - 1);\n    }\n    \n    /**\n     * Build balanced tree from flattened tree.\n     */\n    private Node buildTree(List<Node> nodes, int start, int end) {\n        int middle = (int)Math.ceil(((double)(start + end)) / 2.0);\n        if (start > end) {\n            return null;\n        }\n\n        // middle becomes root of subtree instead of scapegoat\n        Node node = nodes.get(middle);\n        \n        // recursively get left and right nodes\n        Node leftNode = buildTree(nodes, start, middle - 1);\n        node.left = leftNode;\n        if (leftNode != null) {\n            leftNode.parent = node;\n        }\n        Node rightNode = buildTree(nodes, middle + 1, end);\n        node.right = rightNode;\n        if (rightNode != null) {\n            rightNode.parent = node;\n        }\n        return node;\n    }\n    \n    /**\n     * @return Node's sibling.\n     */\n    // TODO move to AbstractBinaySearchTree and use in other trees where needed.\n    private Node getSibling(Node node) {\n        if (node.parent != null) {\n            if (node.parent.left == node) {\n                return node.parent.right;\n            } else {\n                return node.parent.left;\n            }\n        }\n        return null;\n    }\n    \n    /**\n     * Calculate size of subtree.\n     * \n     * @param node\n     *            Subtree root node.\n     * @return Number of elements in the subtree.\n     */\n    // TODO move to AbstractBinaySearchTree\n    protected int getSubtreeSize(Node node) {\n        if (node == null) {\n            return 0;\n        }\n        if (node.isLeaf()) {\n            return 1;\n        } else {\n            int sum = 1;\n            sum += getSubtreeSize(node.left);\n            sum += getSubtreeSize(node.right);\n            return sum;\n        }\n    }\n    \n    // TODO move to AbstractBinaySearchTree\n    protected int getNodeHeight(Node node) {\n        if (node == null) {\n            return -1;\n        } else if (node.parent == null) {\n            return 0;\n        } else {\n            return getNodeHeight(node.parent) + 1;\n        }\n    }\n\n    private int getHAlpha() {\n        return (int)Math.floor(MathUtils.logarithm(1 / alpha, (double)getSize()));\n    }\n\n}"
  },
  {
    "path": "Trees/src/main/java/org/intelligentjava/algos/trees/SplayTree.java",
    "content": "package org.intelligentjava.algos.trees;\n\n/**\n * Splay tree implementation.\n * \n * @author Ignas Lelys\n * @created Jul 19, 2011\n * \n */\npublic class SplayTree extends AbstractSelfBalancingBinarySearchTree {\n\n    /**\n     * @see org.intelligentjava.algos.trees.AbstractBinarySearchTree#search(int)\n     */\n    @Override\n    public Node search(int element) {\n        Node node = super.search(element);\n        if (node != null) {\n            splay(node);\n        }\n        return node;\n    }\n    \n    /**\n     * @see org.intelligentjava.algos.trees.AbstractBinarySearchTree#insert(int)\n     */\n    @Override\n    public Node insert(int element) {\n        Node insertNode = super.insert(element);\n        splay(insertNode);\n        return insertNode;\n    }\n\n    /**\n     * @see org.intelligentjava.algos.trees.AbstractBinarySearchTree#delete(int)\n     */\n    @Override\n    public Node delete(int element) {\n        // search first, because need parent to splay, might be improved later if needed\n        Node deleteNode = super.search(element); // do not use search with splaying\n        Node successor = null;\n        if (deleteNode != null) {\n            Node parent = deleteNode.parent;\n            successor = super.delete(deleteNode);\n            if (parent != null) {\n                splay(parent);\n            }\n        }\n        return successor;\n    }\n    \n    /**\n     * @see org.intelligentjava.algos.trees.AbstractBinarySearchTree#createNode(int, org.intelligentjava.algos.trees.AbstractBinarySearchTree.Node, org.intelligentjava.algos.trees.AbstractBinarySearchTree.Node, org.intelligentjava.algos.trees.AbstractBinarySearchTree.Node)\n     */\n    @Override\n    protected Node createNode(int value, Node parent, Node left, Node right) {\n        return new Node(value, parent, left, right);\n    }\n\n    /**\n     * Splay operation. Move node to the root through some tree transformations.\n     * \n     * @param node\n     *            Node to perform splay operation on.\n     */\n    protected void splay(Node node) {\n        // move node up until its root\n        while (node != root) {\n            // Zig step\n            Node parent = node.parent;\n            if (parent.equals(root)) {\n                if (node.equals(parent.left)) {\n                    rotateRight(parent);\n                } else if (node.equals(parent.right)) {\n                    rotateLeft(parent);\n                }\n                break;\n            } else {\n                Node grandParent = parent.parent;\n                boolean nodeAndParentLeftChildren = node.equals(parent.left) && parent.equals(grandParent.left);\n                boolean nodeAndParentRightChildren = node.equals(parent.right) && parent.equals(grandParent.right);\n                boolean nodeRightChildParentLeftChild = node.equals(parent.right) && parent.equals(grandParent.left);\n                boolean nodeLeftChildParentRightChild = node.equals(parent.left) && parent.equals(grandParent.right);\n                // Zig zig step to the right\n                if (nodeAndParentLeftChildren) {\n                    rotateRight(grandParent);\n                    rotateRight(parent);\n                }  \n                // Zig zig step to the left\n                else if (nodeAndParentRightChildren) {\n                    rotateLeft(grandParent);\n                    rotateLeft(parent);\n                }\n                // Zig zag steps\n                else if (nodeRightChildParentLeftChild) {\n                    rotateLeft(parent);\n                    rotateRight(grandParent);\n                }\n                else if (nodeLeftChildParentRightChild) {\n                    rotateRight(parent);\n                    rotateLeft(grandParent);\n                }\n            }\n        }\n    }\n\n}\n"
  },
  {
    "path": "Trees/src/main/java/org/intelligentjava/algos/trees/Treap.java",
    "content": "package org.intelligentjava.algos.trees;\n\nimport java.util.Random;\n\n/**\n * Treap is randomized binary search tree. Easiest way to randomize would be to get all elements in array and then after\n * random permutation insert them all. However that would require to know all elements in advance. Treap solves this by\n * introducing additional variable to its node - priority which is generated randomly.\n * \n * @author Ignas Lelys\n * @created Jul 25, 2011\n * \n */\npublic class Treap extends AbstractSelfBalancingBinarySearchTree {\n\n    private Random random = new Random(System.currentTimeMillis());\n\n    /**\n     * Insert same as normal binary search tree first, just TreapNode will have random number - priority. Then performs\n     * rotations up until root if priority of child is larger than priority of parent.\n     * \n     * @see org.intelligentjava.algos.trees.AbstractBinarySearchTree#insert(int)\n     */\n    @Override\n    public Node insert(int element) {\n        // insert as in normal BST\n        TreapNode insertedNode = (TreapNode) super.insert(element);\n        // then rebalance by randomized priority\n        while (insertedNode != root) {\n            TreapNode parent = (TreapNode) insertedNode.parent;\n            if (parent.priority < insertedNode.priority) {\n                if (insertedNode.equals(parent.left)) {\n                    rotateRight(parent);\n                } else {\n                    rotateLeft(parent);\n                }\n            } else {\n                break;\n            }\n        }\n        return insertedNode;\n    }\n\n    /**\n     * {@inheritDoc}\n     */\n    @Override\n    protected Node delete(Node deleteNode) {\n        if (deleteNode != null) {\n            // rotate node down to leaf\n            Node replaceNode = rotateDown((TreapNode)deleteNode);\n            // then delete it normally\n            super.delete(deleteNode);\n            return replaceNode;\n        }\n        return null;\n    }\n    \n    /**\n     * {@inheritDoc}\n     */\n    @Override\n    protected Node createNode(int value, Node parent, Node left, Node right) {\n        return new TreapNode(value, parent, left, right, random.nextInt(10000));\n    }\n\n    /**\n     * Rotates a node downwards until it becomes a leaf. It must be deleted later to keep heap property intact.\n     * \n     * @param node The node which is moved to leaf.\n     * \n     * @return Node that replaces the one which is moved downwards to leaf.\n     */\n    private Node rotateDown(TreapNode node) {\n        Node replaceNode = null;\n        while (true) {\n            if (node.left != null) {\n                boolean leftNodePriorityLarger = node.right == null || ((TreapNode) node.left).priority >= ((TreapNode) node.right).priority;\n                if (leftNodePriorityLarger) {\n                    Node replace = rotateRight(node);\n                    if (replaceNode == null) {\n                        replaceNode = replace;\n                    }\n                } else {\n                    Node replace = rotateLeft(node);\n                    if (replaceNode == null) {\n                        replaceNode = replace;\n                    }\n                }\n            } else if (node.right != null) {\n                Node replace = rotateLeft(node);\n                if (replaceNode == null) {\n                    replaceNode = replace;\n                }\n            } else {\n                break;\n            }\n        }\n        return replaceNode;\n    }\n\n    /**\n     * Node for Treap. It has additional priority value which is set randomly. It is used for tree randomization.\n     * \n     * @author Ignas Lelys\n     * @created Jul 25, 2011\n     */\n    protected static class TreapNode extends Node {\n        public int priority;\n\n        public TreapNode(int value, Node parent, Node left, Node right, int priority) {\n            super(value, parent, left, right);\n            this.priority = priority;\n        }\n    }\n}\n"
  },
  {
    "path": "Trees/src/main/java/org/intelligentjava/algos/trees/benchmark/TreesDeleteBenchmark.java",
    "content": "package org.intelligentjava.algos.trees.benchmark;\n\nimport java.util.Random;\nimport java.util.TreeSet;\nimport java.util.concurrent.TimeUnit;\n\nimport org.intelligentjava.algos.trees.AVLTree;\nimport org.intelligentjava.algos.trees.RedBlackTree;\nimport org.intelligentjava.algos.trees.ScapegoatTree;\nimport org.intelligentjava.algos.trees.SplayTree;\nimport org.intelligentjava.algos.trees.Treap;\nimport org.openjdk.jmh.annotations.Benchmark;\nimport org.openjdk.jmh.annotations.BenchmarkMode;\nimport org.openjdk.jmh.annotations.Level;\nimport org.openjdk.jmh.annotations.Measurement;\nimport org.openjdk.jmh.annotations.Mode;\nimport org.openjdk.jmh.annotations.OutputTimeUnit;\nimport org.openjdk.jmh.annotations.Scope;\nimport org.openjdk.jmh.annotations.Setup;\nimport org.openjdk.jmh.annotations.State;\nimport org.openjdk.jmh.annotations.Warmup;\nimport org.openjdk.jmh.runner.Runner;\nimport org.openjdk.jmh.runner.RunnerException;\nimport org.openjdk.jmh.runner.options.Options;\nimport org.openjdk.jmh.runner.options.OptionsBuilder;\n\n@OutputTimeUnit(TimeUnit.MILLISECONDS)\n@BenchmarkMode(Mode.AverageTime)\n@Warmup(iterations = 1, time = 1)\n@Measurement(iterations = 2, time = 1)\n@State(Scope.Thread)\npublic class TreesDeleteBenchmark {\n    \n    private static final int SIZE = 100000;\n    \n    private Integer[] randomInts = new Integer[SIZE];\n  \n    @Setup(Level.Trial)\n    public void setup() {\n        Random random = new Random(System.currentTimeMillis());\n        for (int i = 0; i < SIZE; i++) {\n            randomInts[i] = random.nextInt(SIZE);\n        }\n    }\n    \n    @Benchmark\n    public Object timeJDKTreeSet() {\n        TreeSet<Integer> treeSet = new TreeSet<>();\n        for (int i = 0; i < SIZE; i++) {\n            treeSet.add(randomInts[i]);\n        }\n\n        for (int i = 0; i < SIZE; i++) {\n            treeSet.remove(randomInts[i]);\n        }\n        \n        return treeSet.contains(randomInts[0]);\n    }\n    \n    @Benchmark\n    public Object timeDeleteRedBlackTree() {\n        RedBlackTree rbTree = new RedBlackTree();\n        for (int i = 0; i < SIZE; i++) {\n            rbTree.insert(randomInts[i]);\n        }\n        \n        for (int i = 0; i < SIZE; i++) {\n            rbTree.delete(randomInts[i]);\n        }\n        \n        return rbTree.root;\n    }\n\n    @Benchmark\n    public Object timeDeleteAVLTree() {\n        AVLTree avlTree = new AVLTree();\n        for (int i = 0; i < SIZE; i++) {\n            avlTree.insert(randomInts[i]);\n        }\n        \n        for (int i = 0; i < SIZE; i++) {\n            avlTree.delete(randomInts[i]);\n        }\n        \n        return avlTree.root;\n    }\n\n    @Benchmark\n    public Object timeDeleteSplayTree() {\n        SplayTree splayTree = new SplayTree();\n        for (int i = 0; i < SIZE; i++) {\n            splayTree.insert(randomInts[i]);\n        }\n        \n        for (int i = 0; i < SIZE; i++) {\n            splayTree.delete(randomInts[i]);\n        }\n        \n        return splayTree.root;\n    }\n\n    @Benchmark\n    public Object timeDeleteTreap() {\n        Treap treap = new Treap();\n        for (int i = 0; i < SIZE; i++) {\n            treap.insert(randomInts[i]);\n        }\n        \n        for (int i = 0; i < SIZE; i++) {\n            treap.delete(randomInts[i]);\n        }\n        \n        return treap.root;\n    }\n\n    @Benchmark\n    public Object timeDeleteScapegoat0_6Tree() {\n        ScapegoatTree scapegoatTree0_6 = new ScapegoatTree(0.6);\n        for (int i = 0; i < SIZE; i++) {\n            scapegoatTree0_6.insert(randomInts[i]);\n        }\n        \n        for (int i = 0; i < SIZE; i++) {\n            scapegoatTree0_6.delete(randomInts[i]);\n        }\n        \n        return scapegoatTree0_6.root;\n    }\n\n    @Benchmark\n    public Object timeDeleteScapegoat0_75Tree() {\n        ScapegoatTree scapegoatTree0_75 = new ScapegoatTree(0.75);\n        for (int i = 0; i < SIZE; i++) {\n            scapegoatTree0_75.insert(randomInts[i]);\n        }\n        \n        for (int i = 0; i < SIZE; i++) {\n            scapegoatTree0_75.delete(randomInts[i]);\n        }\n        \n        return scapegoatTree0_75.root;\n    }\n    \n    @Benchmark\n    public Object timeDeleteScapegoat0_9Tree() {\n        ScapegoatTree scapegoatTree0_9 = new ScapegoatTree(0.9);\n        for (int i = 0; i < SIZE; i++) {\n            scapegoatTree0_9.insert(randomInts[i]);\n        }\n        \n        for (int i = 0; i < SIZE; i++) {\n            scapegoatTree0_9.delete(randomInts[i]);\n        }\n        \n        return scapegoatTree0_9.root;\n    }\n    \n    public static void main(String[] args) throws RunnerException {\n        Options opt = new OptionsBuilder().include(\".*\" + TreesDeleteBenchmark.class.getSimpleName() + \".*\").forks(1)\n                .build();\n\n        new Runner(opt).run();\n    }\n\n}\n"
  },
  {
    "path": "Trees/src/main/java/org/intelligentjava/algos/trees/benchmark/TreesInsertRandomBenchmark.java",
    "content": "package org.intelligentjava.algos.trees.benchmark;\n\nimport java.util.Random;\nimport java.util.TreeSet;\nimport java.util.concurrent.TimeUnit;\n\nimport org.intelligentjava.algos.trees.AVLTree;\nimport org.intelligentjava.algos.trees.RedBlackTree;\nimport org.intelligentjava.algos.trees.ScapegoatTree;\nimport org.intelligentjava.algos.trees.SplayTree;\nimport org.intelligentjava.algos.trees.Treap;\nimport org.openjdk.jmh.annotations.Benchmark;\nimport org.openjdk.jmh.annotations.BenchmarkMode;\nimport org.openjdk.jmh.annotations.Level;\nimport org.openjdk.jmh.annotations.Measurement;\nimport org.openjdk.jmh.annotations.Mode;\nimport org.openjdk.jmh.annotations.OutputTimeUnit;\nimport org.openjdk.jmh.annotations.Scope;\nimport org.openjdk.jmh.annotations.Setup;\nimport org.openjdk.jmh.annotations.State;\nimport org.openjdk.jmh.annotations.Warmup;\nimport org.openjdk.jmh.runner.Runner;\nimport org.openjdk.jmh.runner.RunnerException;\nimport org.openjdk.jmh.runner.options.Options;\nimport org.openjdk.jmh.runner.options.OptionsBuilder;\n\n@OutputTimeUnit(TimeUnit.MILLISECONDS)\n@BenchmarkMode(Mode.AverageTime)\n@Warmup(iterations = 1, time = 1)\n@Measurement(iterations = 2, time = 1)\n@State(Scope.Thread)\npublic class TreesInsertRandomBenchmark {\n    \n    private static final int SIZE = 100000;\n\n    private Integer[] randomInts = new Integer[SIZE];\n    \n    @Setup(Level.Trial)\n    public void setup() {\n        Random random = new Random(System.currentTimeMillis());\n        for (int i = 0; i < SIZE; i++) {\n            randomInts[i] = random.nextInt(SIZE);\n        }\n    }\n    \n    @SuppressWarnings({ \"unchecked\", \"rawtypes\" })\n    @Benchmark\n    public Object timeJDKTreeSet() {\n        TreeSet tree = new TreeSet();\n        for (int i = 0; i < SIZE; i++) {\n            tree.add(randomInts[i]);\n        }\n        return tree.contains(Integer.MAX_VALUE);\n    }\n\n    @Benchmark\n    public Object timeRedBlackTree() {\n        RedBlackTree tree = new RedBlackTree();\n        for (int i = 0; i < SIZE; i++) {\n            tree.insert(randomInts[i]);\n        }\n        return tree.root;\n    }\n\n    @Benchmark\n    public Object timeAVLTree() {\n        AVLTree tree = new AVLTree();\n        for (int i = 0; i < SIZE; i++) {\n            tree.insert(randomInts[i]);\n        }\n        return tree.root;\n    }\n\n    @Benchmark\n    public Object timeSplayTree() {\n        SplayTree tree = new SplayTree();\n        for (int i = 0; i < SIZE; i++) {\n            tree.insert(randomInts[i]);\n        }\n        return tree.root;\n    }\n\n    @Benchmark\n    public Object timeTreap() {\n        Treap tree = new Treap();\n        for (int i = 0; i < SIZE; i++) {\n            tree.insert(randomInts[i]);\n        }\n        return tree.root;\n    }\n\n    @Benchmark\n    public Object timeScapegoat0_6Tree() {\n        ScapegoatTree tree = new ScapegoatTree(0.6);\n        for (int i = 0; i < SIZE; i++) {\n            tree.insert(randomInts[i]);\n        }\n        return tree.root;\n    }\n    \n    @Benchmark\n    public Object timeScapegoat0_75Tree() {\n        ScapegoatTree tree = new ScapegoatTree(0.75);\n        for (int i = 0; i < SIZE; i++) {\n            tree.insert(randomInts[i]);\n        }\n        return tree.root;\n    }\n    \n    @Benchmark\n    public Object timeScapegoat0_9Tree() {\n        ScapegoatTree tree = new ScapegoatTree(0.9);\n        for (int i = 0; i < SIZE; i++) {\n            tree.insert(randomInts[i]);\n        }\n        return tree.root;\n    }\n    \n    public static void main(String[] args) throws RunnerException {\n        Options opt = new OptionsBuilder().include(\".*\" + TreesInsertRandomBenchmark.class.getSimpleName() + \".*\").forks(1)\n                .build();\n\n        new Runner(opt).run();\n    }\n\n}\n"
  },
  {
    "path": "Trees/src/main/java/org/intelligentjava/algos/trees/benchmark/TreesInsertSortedBenchmark.java",
    "content": "package org.intelligentjava.algos.trees.benchmark;\n\nimport java.util.TreeSet;\nimport java.util.concurrent.TimeUnit;\n\nimport org.intelligentjava.algos.trees.AVLTree;\nimport org.intelligentjava.algos.trees.RedBlackTree;\nimport org.intelligentjava.algos.trees.ScapegoatTree;\nimport org.intelligentjava.algos.trees.SplayTree;\nimport org.intelligentjava.algos.trees.Treap;\nimport org.openjdk.jmh.annotations.Benchmark;\nimport org.openjdk.jmh.annotations.BenchmarkMode;\nimport org.openjdk.jmh.annotations.Measurement;\nimport org.openjdk.jmh.annotations.Mode;\nimport org.openjdk.jmh.annotations.OutputTimeUnit;\nimport org.openjdk.jmh.annotations.Scope;\nimport org.openjdk.jmh.annotations.State;\nimport org.openjdk.jmh.annotations.Warmup;\nimport org.openjdk.jmh.runner.Runner;\nimport org.openjdk.jmh.runner.RunnerException;\nimport org.openjdk.jmh.runner.options.Options;\nimport org.openjdk.jmh.runner.options.OptionsBuilder;\n\n@OutputTimeUnit(TimeUnit.MILLISECONDS)\n@BenchmarkMode(Mode.AverageTime)\n@Warmup(iterations = 1, time = 1)\n@Measurement(iterations = 2, time = 1)\n@State(Scope.Thread)\npublic class TreesInsertSortedBenchmark {\n    \n    @SuppressWarnings({ \"unchecked\", \"rawtypes\" })\n    @Benchmark\n    public Object timeJDKTreeSet() {\n        TreeSet tree = new TreeSet();\n        for (int i = 0; i < 100000; i++) {\n            tree.add(i);\n        }\n        return tree.contains(Integer.MAX_VALUE);\n    }\n\n    @Benchmark\n    public Object timeRedBlackTree() {\n        RedBlackTree tree = new RedBlackTree();\n        for (int i = 0; i < 100000; i++) {\n            tree.insert(i);\n        }\n        return tree.root;\n    }\n\n    @Benchmark\n    public Object timeAVLTree() {\n        AVLTree tree = new AVLTree();\n        for (int i = 0; i < 100000; i++) {\n            tree.insert(i);\n        }\n        return tree.root;\n    }\n\n    @Benchmark\n    public Object timeSplayTree() {\n        SplayTree tree = new SplayTree();\n        for (int i = 0; i < 100000; i++) {\n            tree.insert(i);\n        }\n        return tree.root;\n    }\n\n    @Benchmark\n    public Object timeTreap() {\n        Treap tree = new Treap();\n        for (int i = 0; i < 100000; i++) {\n            tree.insert(i);\n        }\n        return tree.root;\n    }\n\n    @Benchmark\n    public Object timeScapegoat0_6Tree() {\n        ScapegoatTree tree = new ScapegoatTree(0.6);\n        for (int i = 0; i < 100000; i++) {\n            tree.insert(i);\n        }\n        return tree.root;\n    }\n    \n    @Benchmark\n    public Object timeScapegoat0_75Tree() {\n        ScapegoatTree tree = new ScapegoatTree(0.75);\n        for (int i = 0; i < 100000; i++) {\n            tree.insert(i);\n        }\n        return tree.root;\n    }\n    \n    @Benchmark\n    public Object timeScapegoat0_9Tree() {\n        ScapegoatTree tree = new ScapegoatTree(0.9);\n        for (int i = 0; i < 100000; i++) {\n            tree.insert(i);\n        }\n        return tree.root;\n    }\n    \n    public static void main(String[] args) throws RunnerException {\n        Options opt = new OptionsBuilder().include(\".*\" + TreesInsertSortedBenchmark.class.getSimpleName() + \".*\").forks(1)\n                .build();\n\n        new Runner(opt).run();\n    }\n\n}\n"
  },
  {
    "path": "Trees/src/main/java/org/intelligentjava/algos/trees/benchmark/TreesSearchBenchmark.java",
    "content": "package org.intelligentjava.algos.trees.benchmark;\n\nimport java.util.Random;\nimport java.util.TreeSet;\nimport java.util.concurrent.TimeUnit;\n\nimport org.intelligentjava.algos.trees.AVLTree;\nimport org.intelligentjava.algos.trees.AbstractBinarySearchTree.Node;\nimport org.intelligentjava.algos.trees.RedBlackTree;\nimport org.intelligentjava.algos.trees.ScapegoatTree;\nimport org.intelligentjava.algos.trees.SplayTree;\nimport org.intelligentjava.algos.trees.Treap;\nimport org.openjdk.jmh.annotations.Benchmark;\nimport org.openjdk.jmh.annotations.BenchmarkMode;\nimport org.openjdk.jmh.annotations.Level;\nimport org.openjdk.jmh.annotations.Measurement;\nimport org.openjdk.jmh.annotations.Mode;\nimport org.openjdk.jmh.annotations.OutputTimeUnit;\nimport org.openjdk.jmh.annotations.Scope;\nimport org.openjdk.jmh.annotations.Setup;\nimport org.openjdk.jmh.annotations.State;\nimport org.openjdk.jmh.annotations.Warmup;\nimport org.openjdk.jmh.runner.Runner;\nimport org.openjdk.jmh.runner.RunnerException;\nimport org.openjdk.jmh.runner.options.Options;\nimport org.openjdk.jmh.runner.options.OptionsBuilder;\n\n@SuppressWarnings(\"unchecked\")\n@OutputTimeUnit(TimeUnit.MILLISECONDS)\n@BenchmarkMode(Mode.AverageTime)\n@Warmup(iterations = 1, time = 1)\n@Measurement(iterations = 2, time = 1)\n@State(Scope.Thread)\npublic class TreesSearchBenchmark {\n    \n    private static final int SIZE = 100000;\n    @SuppressWarnings(\"rawtypes\")\n    private TreeSet treeSet = new TreeSet();\n    private RedBlackTree rbTree = new RedBlackTree();\n    private AVLTree avlTree = new AVLTree();\n    private SplayTree splayTree = new SplayTree();\n    private Treap treap = new Treap();\n    private ScapegoatTree scapegoatTree0_6 = new ScapegoatTree(0.6);\n    private ScapegoatTree scapegoatTree0_75 = new ScapegoatTree(0.75);\n    private ScapegoatTree scapegoatTree0_9 = new ScapegoatTree(0.9);\n    private Integer[] randomInts = new Integer[SIZE];\n    \n    @Setup(Level.Trial)\n    public void setup() {\n        Random random = new Random(System.currentTimeMillis());\n        for (Integer i = 0; i < SIZE; i++) {\n            randomInts[i] = random.nextInt(SIZE);\n        }\n        for (int i = 0; i < SIZE; i++) {\n            rbTree.insert(randomInts[i]);\n        }\n        for (int i = 0; i < SIZE; i++) {\n            treeSet.add(randomInts[i]);\n        }\n        for (int i = 0; i < SIZE; i++) {\n            avlTree.insert(randomInts[i]);\n        }\n        for (int i = 0; i < SIZE; i++) {\n            splayTree.insert(randomInts[i]);\n        }\n        for (int i = 0; i < SIZE; i++) {\n            treap.insert(randomInts[i]);\n        }\n        for (int i = 0; i < SIZE; i++) {\n            scapegoatTree0_6.insert(randomInts[i]);\n        }\n        for (int i = 0; i < SIZE; i++) {\n            scapegoatTree0_75.insert(randomInts[i]);\n        }\n        for (int i = 0; i < SIZE; i++) {\n            scapegoatTree0_9.insert(randomInts[i]);\n        }\n    }\n    \n    \n    @Benchmark\n    public boolean timeJDKTreeSet() {\n        boolean[] booleans = new boolean[SIZE];\n        for (int i = 0; i < SIZE; i++) {\n            booleans[i] = treeSet.contains(randomInts[i]);\n        }\n        return booleans[0];\n    }\n    \n    @Benchmark\n    public Node timeSearchRedBlackTree() {\n        Node[] nodes = new Node[SIZE];\n        for (int i = 0; i < SIZE; i++) {\n            nodes[i] = rbTree.search(randomInts[i]);\n        }\n        return nodes[0];\n    }\n\n    @Benchmark\n    public Node timeSearchAVLTree() {\n        Node[] nodes = new Node[SIZE];\n        for (int i = 0; i < SIZE; i++) {\n            nodes[i] = avlTree.search(randomInts[i]);\n        }\n        return nodes[0];\n    }\n\n    @Benchmark\n    public Node timeSearchSplayTree() {\n        Node[] nodes = new Node[SIZE];\n        for (int i = 0; i < SIZE; i++) {\n            nodes[i] = splayTree.search(randomInts[i]);\n        }\n        return nodes[0];\n    }\n\n    @Benchmark\n    public Node timeSearchTreap() {\n        Node[] nodes = new Node[SIZE];\n        for (int i = 0; i < SIZE; i++) {\n            nodes[i] = treap.search(randomInts[i]);\n        }\n        return nodes[0];\n    }\n\n    @Benchmark\n    public Node timeSearchScapegoat0_6Tree() {\n        Node[] nodes = new Node[SIZE];\n        for (int i = 0; i < SIZE; i++) {\n            nodes[i] = scapegoatTree0_6.search(randomInts[i]);\n        }\n        return nodes[0];\n    }\n\n    @Benchmark\n    public Node timeSearchScapegoat0_75Tree() {\n        Node[] nodes = new Node[SIZE];\n        for (int i = 0; i < SIZE; i++) {\n            nodes[i] = scapegoatTree0_75.search(randomInts[i]);\n        }\n        return nodes[0];\n    }\n    \n    @Benchmark\n    public Node timeSearchScapegoat0_9Tree() {\n        Node[] nodes = new Node[SIZE];\n        for (int i = 0; i < SIZE; i++) {\n            nodes[i] = scapegoatTree0_9.search(randomInts[i]);\n        }\n        return nodes[0];\n    }\n    \n    public static void main(String[] args) throws RunnerException {\n        Options opt = new OptionsBuilder().include(\".*\" + TreesDeleteBenchmark.class.getSimpleName() + \".*\").forks(1)\n                .build();\n\n        new Runner(opt).run();\n    }\n\n}\n"
  },
  {
    "path": "Trees/src/main/java/org/intelligentjava/algos/trees/benchmark/TreesSearchSameElementsBenchmark.java",
    "content": "package org.intelligentjava.algos.trees.benchmark;\n\nimport java.util.Random;\nimport java.util.TreeSet;\nimport java.util.concurrent.TimeUnit;\n\nimport org.intelligentjava.algos.trees.AVLTree;\nimport org.intelligentjava.algos.trees.AbstractBinarySearchTree.Node;\nimport org.intelligentjava.algos.trees.RedBlackTree;\nimport org.intelligentjava.algos.trees.ScapegoatTree;\nimport org.intelligentjava.algos.trees.SplayTree;\nimport org.intelligentjava.algos.trees.Treap;\nimport org.openjdk.jmh.annotations.Benchmark;\nimport org.openjdk.jmh.annotations.BenchmarkMode;\nimport org.openjdk.jmh.annotations.Level;\nimport org.openjdk.jmh.annotations.Measurement;\nimport org.openjdk.jmh.annotations.Mode;\nimport org.openjdk.jmh.annotations.OutputTimeUnit;\nimport org.openjdk.jmh.annotations.Scope;\nimport org.openjdk.jmh.annotations.Setup;\nimport org.openjdk.jmh.annotations.State;\nimport org.openjdk.jmh.annotations.Warmup;\nimport org.openjdk.jmh.runner.Runner;\nimport org.openjdk.jmh.runner.RunnerException;\nimport org.openjdk.jmh.runner.options.Options;\nimport org.openjdk.jmh.runner.options.OptionsBuilder;\n\n@SuppressWarnings(\"unchecked\")\n@OutputTimeUnit(TimeUnit.MILLISECONDS)\n@BenchmarkMode(Mode.AverageTime)\n@Warmup(iterations = 1, time = 1)\n@Measurement(iterations = 3, time = 1)\n@State(Scope.Thread)\npublic class TreesSearchSameElementsBenchmark {\n    \n    private static final int SIZE = 100000;\n    @SuppressWarnings(\"rawtypes\")\n    private TreeSet treeSet = new TreeSet();\n    private RedBlackTree rbTree = new RedBlackTree();\n    private AVLTree avlTree = new AVLTree();\n    private SplayTree splayTree = new SplayTree();\n    private Treap treap = new Treap();\n    private ScapegoatTree scapegoatTree0_6 = new ScapegoatTree(0.6);\n    private ScapegoatTree scapegoatTree0_75 = new ScapegoatTree(0.75);\n    private ScapegoatTree scapegoatTree0_9 = new ScapegoatTree(0.9);\n    private Integer[] randomInts = new Integer[SIZE];\n    \n    @Setup(Level.Trial)\n    public void setup() {\n        Random random = new Random(System.currentTimeMillis());\n        for (int i = 0; i < SIZE; i++) {\n            randomInts[i] = random.nextInt(SIZE);\n        }\n        for (int i = 0; i < SIZE; i++) {\n            rbTree.insert(randomInts[i]);\n        }\n        for (int i = 0; i < SIZE; i++) {\n            treeSet.add(randomInts[i]);\n        }\n        for (int i = 0; i < SIZE; i++) {\n            avlTree.insert(randomInts[i]);\n        }\n        for (int i = 0; i < SIZE; i++) {\n            splayTree.insert(randomInts[i]);\n        }\n        for (int i = 0; i < SIZE; i++) {\n            treap.insert(randomInts[i]);\n        }\n        for (int i = 0; i < SIZE; i++) {\n            scapegoatTree0_6.insert(randomInts[i]);\n        }\n        for (int i = 0; i < SIZE; i++) {\n            scapegoatTree0_75.insert(randomInts[i]);\n        }\n        for (int i = 0; i < SIZE; i++) {\n            scapegoatTree0_9.insert(randomInts[i]);\n        }\n    }\n    \n    @Benchmark\n    public boolean timeJDKTreeSet() {\n        boolean[] booleans = new boolean[SIZE];\n        for (int i = 0; i < SIZE; i++) {\n            booleans[i] = treeSet.contains(randomInts[i % 100]);\n        }\n        return booleans[0];\n    }\n    \n    @Benchmark\n    public Node timeSearchRedBlackTree() {\n        Node[] nodes = new Node[SIZE];\n        for (int i = 0; i < SIZE; i++) {\n            nodes[i] = rbTree.search(randomInts[i % 100]);\n        }\n        return nodes[0];\n    }\n\n    @Benchmark\n    public Node timeSearchAVLTree() {\n        Node[] nodes = new Node[SIZE];\n        for (int i = 0; i < SIZE; i++) {\n            nodes[i] = avlTree.search(randomInts[i % 100]);\n        }\n        return nodes[0];\n    }\n\n    @Benchmark\n    public Node timeSearchSplayTree() {\n        Node[] nodes = new Node[SIZE];\n        for (int i = 0; i < SIZE; i++) {\n            nodes[i] = splayTree.search(randomInts[i  % 100]);\n        }\n        return nodes[0];\n    }\n\n    @Benchmark\n    public Node timeSearchTreap() {\n        Node[] nodes = new Node[SIZE];\n        for (int i = 0; i < SIZE; i++) {\n            nodes[i] = treap.search(randomInts[i  % 100]);\n        }\n        return nodes[0];\n    }\n\n    @Benchmark\n    public Node timeSearchScapegoat0_6Tree() {\n        Node[] nodes = new Node[SIZE];\n        for (int i = 0; i < SIZE; i++) {\n            nodes[i] = scapegoatTree0_6.search(randomInts[i  % 100]);\n        }\n        return nodes[0];\n    }\n\n    @Benchmark\n    public Node timeSearchScapegoat0_75Tree() {\n        Node[] nodes = new Node[SIZE];\n        for (int i = 0; i < SIZE; i++) {\n            nodes[i] = scapegoatTree0_75.search(randomInts[i  % 100]);\n        }\n        return nodes[0];\n    }\n    \n    @Benchmark\n    public Node timeSearchScapegoat0_9Tree() {\n        Node[] nodes = new Node[SIZE];\n        for (int i = 0; i < SIZE; i++) {\n            nodes[i] = scapegoatTree0_9.search(randomInts[i % 100]);\n        }\n        return nodes[0];\n    }\n    \n    public static void main(String[] args) throws RunnerException {\n        Options opt = new OptionsBuilder().include(\".*\" + TreesDeleteBenchmark.class.getSimpleName() + \".*\").forks(1)\n                .build();\n\n        new Runner(opt).run();\n    }\n\n}\n"
  },
  {
    "path": "Trees/src/main/java/org/intelligentjava/algos/trees/exceptions/QueueOverflowException.java",
    "content": "package org.intelligentjava.algos.trees.exceptions;\n\n/**\n * Exception when queue overflow.\n * \n * @author Ignas Lelys\n * @created May 4, 2011\n *\n */\npublic class QueueOverflowException extends Exception {\n\n    private static final long serialVersionUID = 1L;\n\n}\n"
  },
  {
    "path": "Trees/src/main/java/org/intelligentjava/algos/trees/main/Main.java",
    "content": "package org.intelligentjava.algos.trees.main;\n\nimport java.util.Random;\n\nimport org.intelligentjava.algos.trees.RedBlackTree;\n\npublic class Main {\n\n    private static final int SIZE = 100;\n\n    public static void main(String[] args) {\n        Random random = new Random(System.currentTimeMillis());\n        Integer[] randomInts = new Integer[SIZE];\n        for (int i = 0; i < SIZE; i++) {\n            randomInts[i] = random.nextInt(SIZE);\n        }\n\n        long currentTimeMillis = System.currentTimeMillis();\n        RedBlackTree tree = new RedBlackTree();\n        for (int i = 1; i < SIZE; i++) {\n            tree.insert(randomInts[i]);\n        }\n\n        for (int i = 1; i < SIZE / 2; i++) {\n            tree.delete(randomInts[i]);\n        }\n        \n        tree.printTree();\n\n        System.out.println(System.currentTimeMillis() - currentTimeMillis + \" ms\");\n    }\n\n}\n"
  },
  {
    "path": "Trees/src/main/java/org/intelligentjava/algos/trees/utils/ArrayUtils.java",
    "content": "package org.intelligentjava.algos.trees.utils;\n\n/**\n * Helper class which helps to work with arrays.\n * \n * @author Ignas Lelys\n * @created Apr 18, 2011\n * \n */\npublic class ArrayUtils {\n\n    /**\n     * Swaps elements in array.\n     * \n     * @param data\n     *            Array of elements.\n     * @param elementIndex1\n     *            Index of element which value will be moved to elementIndex2.\n     * @param elementIndex2\n     *            Index of element which value will be moved to elementIndex1.\n     */\n    public static void swap(int[] data, int elementIndex1, int elementIndex2) {\n        int tmp = data[elementIndex1];\n        data[elementIndex1] = data[elementIndex2];\n        data[elementIndex2] = tmp;\n    }\n\n    /**\n     * Select nth smallest element in array. It could be easily solved by\n     * sorting array and select nth element, but this algorithm is more\n     * efficient. Expected running time is O(n). However worst case scenario\n     * could be O(n^2).\n     * \n     * @param data Data array.\n     * @param n N parameter.\n     * @return Value of nth smallest element.\n     */\n    public static int selectNthSmallestElement(int[] data, int n) {\n        return selectNthSmallestElement(data, 0, data.length - 1, n);\n    }\n\n    /**\n     * Select nth smallest element in array from sublist.\n     * \n     * @param @param data Data array.\n     * @param sublistStartIndex Sublist start index.\n     * @param sublistEndIndex Sublist end index.\n     * @param n N parameter.\n     * @return Value of nth smallest element in sublist.\n     */\n    public static int selectNthSmallestElement(int[] data, int sublistStartIndex, int sublistEndIndex, int n) {\n        if (sublistStartIndex == sublistEndIndex) {\n            return data[sublistStartIndex];\n        }\n        int pivotIndex = partition(data, sublistStartIndex, sublistEndIndex);\n        int k = sublistStartIndex - pivotIndex + 1;\n        if (n == k) {\n            return data[pivotIndex];\n        } else if (n < k) {\n            return selectNthSmallestElement(data, sublistStartIndex, pivotIndex - 1, n);\n        } else {\n            return selectNthSmallestElement(data, pivotIndex, sublistEndIndex, n - k);\n        }\n        \n    }\n\n    /**\n     * Partition algorithm.\n     * \n     * @param @param data Data array.\n     * @param sublistStartIndex Sublist start index.\n     * @param sublistEndIndex Sublist end index.\n     * @return Pivot index.\n     */\n    private static int partition(int[] data, int sublistStartIndex, int sublistEndIndex) {\n        int pivotElement = data[sublistEndIndex];\n        int pivotIndex = sublistStartIndex - 1;\n        for (int i = sublistStartIndex; i < sublistEndIndex; i++) {\n            if (data[i] <= pivotElement) {\n                pivotIndex++;\n                ArrayUtils.swap(data, pivotIndex, i);\n            }\n        }\n        ArrayUtils.swap(data, pivotIndex + 1, sublistEndIndex);\n        return pivotIndex + 1;\n    }\n    \n}\n"
  },
  {
    "path": "Trees/src/main/java/org/intelligentjava/algos/trees/utils/HeapUtils.java",
    "content": "package org.intelligentjava.algos.trees.utils;\n\n/**\n * Utils for working with heap data structure. Heap is a tree like data\n * structure, which has root element always bigger than its children.\n * Example of a heap:\n *              100\n *               /\\\n *             90  23\n *             /\\  /\n *           45  1 15\n * Heap is used in heap sort and priority queues implementations.\n */\npublic class HeapUtils {\n    \n    /**\n     * @param data\n     * @param index\n     */\n    public static void buildMaxHeap(int[] data) {\n        for (int i = data.length/2; i >= 0; i--) {\n            maxHeapify(data, i);\n        }\n    }\n    \n    /**\n     * This method takes array and index of root element (of heap subtree). It\n     * assumes that this element might not\n     * \n     * @param data\n     * @param index\n     */\n    public static void maxHeapify(int[] data, int index) {\n        maxHeapify(data, index, data.length);\n    }\n    \n    /**\n     * @param data\n     * @param index\n     * @param heapSize\n     */\n    public static void maxHeapify(int[] data, int index, int heapSize) {\n        int leftLeaf = getLeftLeaf(index);\n        int rightLeaf = getRightLeaf(index);\n        int largest = index;\n        if (leftLeaf < heapSize && data[leftLeaf] > data[largest]) {\n            largest = leftLeaf;\n        }\n        if (rightLeaf < heapSize && data[rightLeaf] > data[largest]) {\n            largest = rightLeaf;\n        }\n        if (largest != index) {\n            ArrayUtils.swap(data, index, largest);\n            HeapUtils.maxHeapify(data, largest, heapSize);\n        }\n    }\n\n    public static int getParent(int leafIndex) {\n        return leafIndex / 2;\n    }\n    \n    /**\n     * Calculates index of left child node.\n     * \n     * @param parentIndex\n     *            Array index that represents parent node.\n     * @return Left child node index in array.\n     */\n    private static int getLeftLeaf(int parentIndex) {\n        return 2 * parentIndex+1;\n    }\n\n    /**\n     * Calculates index of right child node.\n     * \n     * @param parentIndex\n     *            Array index that represents parent node.\n     * @return Right child node index in array.\n     */\n    private static int getRightLeaf(int parentIndex) {\n        return 2 * parentIndex + 2;\n    }\n}\n"
  },
  {
    "path": "Trees/src/main/java/org/intelligentjava/algos/trees/utils/MathUtils.java",
    "content": "package org.intelligentjava.algos.trees.utils;\n\n/**\n * Some syntactic sugar for math operations.\n * \n * @author Ignas Lelys\n * @created May 3, 2011\n *\n */\npublic class MathUtils {\n    \n    /**\n     * Extracts digit from integer number.\n     * \n     * @param number Number from which digit is extracted.\n     * @param digitIndex index of digit to get. 0 - last one.\n     * \n     * @return Required digit.\n     */\n    public static int getDigitFromNumber(int number, int digitIndex) {\n        // TODO error check and efficiency (maybe put powers of 10 to array)\n        return number / (int)Math.pow(10, digitIndex) % 10;\n    }\n    \n    /**\n     * Returns bigger integer.\n     * \n     * @param first First number.\n     * @param second Second number.\n     * @return Bigger number.\n     */\n    public static int getMax(int first, int second) {\n        return first > second ? first : second;\n    }\n    \n    /**\n     * Calculates logarithm.\n     */\n    public static double logarithm(double base, double a) {\n        return Math.log(a) / Math.log(base);\n    }\n\n}\n"
  },
  {
    "path": "Trees/src/test/java/org/intelligentjava/algos/simplestructures/LinkedListTest.java",
    "content": "package org.intelligentjava.algos.simplestructures;\n\nimport org.junit.Assert;\nimport org.junit.Test;\n\n/**\n * @author Ignas Lelys\n * @created May 5, 2011\n *\n */\npublic class LinkedListTest {\n    \n    @Test\n    public void testInsertDelete() {\n        LinkedList list = new LinkedList();\n        list.insert(1);\n        list.insert(2);\n        list.insert(3);\n        list.insert(4);\n        list.insert(5);\n        Assert.assertEquals(list.get(0), 5);\n        Assert.assertEquals(list.get(1), 4);\n        Assert.assertEquals(list.get(2), 3);\n        Assert.assertEquals(list.get(3), 2);\n        Assert.assertEquals(list.get(4), 1);\n        list.delete(5);\n        Assert.assertEquals(list.get(0), 4);\n        Assert.assertEquals(list.get(1), 3);\n        Assert.assertEquals(list.get(2), 2);\n        Assert.assertEquals(list.get(3), 1);\n        list.delete(1);\n        Assert.assertEquals(list.get(0), 4);\n        Assert.assertEquals(list.get(1), 3);\n        Assert.assertEquals(list.get(2), 2);\n        list.delete(3);\n        Assert.assertEquals(list.get(0), 4);\n        Assert.assertEquals(list.get(1), 2);\n        \n    }\n\n}\n"
  },
  {
    "path": "Trees/src/test/java/org/intelligentjava/algos/simplestructures/PriorityQueueTest.java",
    "content": "package org.intelligentjava.algos.simplestructures;\n\n/**\n * @author Ignas Lelys\n * @created May 4, 2011\n *\n */\npublic class PriorityQueueTest {\n\n}\n"
  },
  {
    "path": "Trees/src/test/java/org/intelligentjava/algos/simplestructures/QueueTest.java",
    "content": "package org.intelligentjava.algos.simplestructures;\n\nimport org.intelligentjava.algos.trees.exceptions.QueueOverflowException;\nimport org.junit.Assert;\nimport org.junit.Test;\n\n/**\n * @author Ignas Lelys\n * @created May 4, 2011\n *\n */\npublic class QueueTest {\n    \n    @Test\n    public void testEnqueueDequeue() throws QueueOverflowException {\n        Queue queue = new Queue();\n        queue.enqueue(1);\n        queue.enqueue(2);\n        queue.enqueue(3);\n        Assert.assertEquals(queue.dequeue(), 1);\n        Assert.assertEquals(queue.dequeue(), 2);\n        Assert.assertEquals(queue.dequeue(), 3);\n    }\n\n    @Test\n    public void testIsEmpty() throws QueueOverflowException {\n        Queue queue = new Queue();\n        Assert.assertTrue(queue.isEmpty());\n        queue.enqueue(1);\n        Assert.assertFalse(queue.isEmpty());\n    }\n    \n    @Test\n    public void testIsFull() throws QueueOverflowException {\n        Queue queue = new Queue();\n        for (int i = 0; i < 8; i++) {\n            queue.enqueue(i);\n        }\n        Assert.assertFalse(queue.isFull());\n        queue.enqueue(9);\n        Assert.assertTrue(queue.isFull());\n        queue.dequeue();\n        Assert.assertFalse(queue.isFull());\n        queue.enqueue(10);\n        Assert.assertTrue(queue.isFull());\n    }\n    \n//    @Test(expectedExceptions = { QueueOverflowException.class })\n//    public void testQueueOverflow() throws QueueOverflowException {\n//        Queue queue = new Queue();\n//        for (int i = 0; i < 11; i++) {\n//            queue.enqueue(i);\n//        }\n//    }\n\n}\n"
  },
  {
    "path": "Trees/src/test/java/org/intelligentjava/algos/simplestructures/StackTest.java",
    "content": "package org.intelligentjava.algos.simplestructures;\n\nimport org.junit.Assert;\nimport org.junit.Test;\n\n/**\n * @author Ignas Lelys\n * @created May 4, 2011\n * \n */\npublic class StackTest {\n\n    @Test\n    public void testPushPop() {\n        Stack stack = new Stack();\n        stack.push(1);\n        stack.push(2);\n        stack.push(3);\n        Assert.assertEquals(stack.pop(), 3);\n        Assert.assertEquals(stack.pop(), 2);\n        Assert.assertEquals(stack.pop(), 1);\n    }\n\n    @Test\n    public void testIsEmpty() {\n        Stack stack = new Stack();\n        Assert.assertTrue(stack.isEmpty());\n        stack.push(1);\n        Assert.assertFalse(stack.isEmpty());\n    }\n\n    /**\n     * Inserts more than 10 elements to stack. (Tests if inner array grows\n     * correctly because starting size for it is 10 elements).\n     */\n    @Test\n    public void testMoreThan10() {\n        Stack stack = new Stack();\n        for (int i = 0; i < 100; i++) {\n            stack.push(i);\n        }\n        for (int i = 99; i >= 0; i--) {\n            Assert.assertEquals(stack.pop(), i);\n        }\n    }\n\n}\n"
  },
  {
    "path": "Trees/src/test/java/org/intelligentjava/algos/trees/AVLTreeTest.java",
    "content": "package org.intelligentjava.algos.trees;\n\nimport org.intelligentjava.algos.trees.AVLTree.AVLNode;\nimport org.intelligentjava.algos.trees.AbstractBinarySearchTree.Node;\nimport org.junit.Assert;\nimport org.junit.Test;\n\n/**\n * Tests for AVL tree.\n * \n * @author Ignas Lelys\n * @created Jun 29, 2011\n *\n */\npublic class AVLTreeTest extends BaseBSTTest {\n    \n    @Test\n    public void testDelete() {\n        AVLTree tree = new AVLTree();\n        tree.insert(20);\n        tree.insert(15);\n        tree.insert(25);\n        tree.insert(23);\n        Assert.assertEquals(tree.size, 4);\n        tree.delete(15); // root is now unbalanced rotation performed\n        Assert.assertEquals(tree.size, 3);\n        Assert.assertEquals(tree.root.value, (Integer)23); // new root\n        Assert.assertEquals(((AVLNode)tree.root).height, 1); // new root\n        Assert.assertEquals(tree.root.left.value, (Integer)20);\n        Assert.assertEquals(tree.root.right.value, (Integer)25);\n        \n        testTreeBSTProperties(tree.root);\n    }\n    \n    @Test\n    public void testInsert() {\n        AVLTree tree = new AVLTree();\n        tree.insert(20);\n        tree.insert(15);\n        tree.insert(25);\n        tree.insert(22);\n        tree.insert(21);\n        Assert.assertEquals(tree.size, 5);\n        Assert.assertEquals((int) tree.root.value, 20);\n        Assert.assertEquals((int) tree.root.left.value, 15);\n        AVLNode rightSubtree = (AVLNode) tree.root.right;\n        // rotation performed and height+balance updated\n        Assert.assertEquals((int) rightSubtree.value, 22);\n        Assert.assertEquals((int) rightSubtree.height, 1);\n        Assert.assertEquals((int) rightSubtree.right.value, 25);\n        Assert.assertEquals(((AVLNode) rightSubtree.right).height, 0);\n        Assert.assertEquals((int) rightSubtree.left.value, 21);\n        Assert.assertEquals(((AVLNode) rightSubtree.left).height, 0);\n        \n        testTreeBSTProperties(tree.root);\n    }\n\n    @Test\n    public void testRotateLeft() {\n        Node root = new AVLNode(4, null, null, null);\n        Node rightChild = new AVLNode(6, root, null, null);\n        root.right = rightChild;\n        Node leftGrandChild = new AVLNode(5, rightChild, null, null);\n        Node rightGrandChild = new AVLNode(7, rightChild, null, null);\n        rightChild.left = leftGrandChild;\n        rightChild.right = rightGrandChild;\n\n        AVLTree tree = new AVLTree();\n        Node rotated = tree.rotateLeft(root);\n\n        Assert.assertEquals((int) rotated.value, 6);\n        Assert.assertEquals((int) rotated.left.value, 4);\n        Assert.assertEquals((int) rotated.right.value, 7);\n        Assert.assertEquals((int) rotated.left.right.value, 5);\n\n        Assert.assertNull(rotated.parent);\n        Assert.assertEquals(rotated.left.parent.value, rotated.value);\n        Assert.assertEquals(rotated.right.parent.value, rotated.value);\n        Assert.assertEquals(rotated.left.right.parent.value, rotated.left.value);\n    }\n\n    @Test\n    public void testRotateRight() {\n        Node root = new AVLNode(8, null, null, null);\n        Node leftChild = new AVLNode(6, root, null, null);\n        root.left = leftChild;\n        Node leftGrandChild = new AVLNode(5, leftChild, null, null);\n        Node rightGrandChild = new AVLNode(7, leftChild, null, null);\n        leftChild.left = leftGrandChild;\n        leftChild.right = rightGrandChild;\n\n        AVLTree tree = new AVLTree();\n        Node rotated = tree.rotateRight(root);\n\n        Assert.assertEquals((int) rotated.value, 6);\n        Assert.assertEquals((int) rotated.left.value, 5);\n        Assert.assertEquals((int) rotated.right.value, 8);\n        Assert.assertEquals((int) rotated.right.left.value, 7);\n\n        Assert.assertNull(rotated.parent);\n        Assert.assertEquals(rotated.left.parent.value, rotated.value);\n        Assert.assertEquals(rotated.right.parent.value, rotated.value);\n        Assert.assertEquals(rotated.right.left.parent.value, rotated.right.value);\n    }\n\n    @Test\n    public void testDoubleRotateRightLeft() {\n        Node root = new AVLNode(5, null, null, null);\n        Node rightChild = new AVLNode(8, root, null, null);\n        root.right = rightChild;\n        Node leftGrandChild = new AVLNode(7, rightChild, null, null);\n        Node rightGrandChild = new AVLNode(10, rightChild, null, null);\n        rightChild.left = leftGrandChild;\n        rightChild.right = rightGrandChild;\n\n        AVLTree tree = new AVLTree();\n        Node rotated = tree.doubleRotateRightLeft(root);\n\n        Assert.assertEquals((int) rotated.value, 7);\n        Assert.assertEquals((int) rotated.left.value, 5);\n        Assert.assertEquals((int) rotated.right.value, 8);\n        Assert.assertEquals((int) rotated.right.right.value, 10);\n\n        Assert.assertNull(rotated.parent);\n        Assert.assertEquals(rotated.left.parent.value, rotated.value);\n        Assert.assertEquals(rotated.right.parent.value, rotated.value);\n        Assert.assertEquals(rotated.right.right.parent.value, rotated.right.value);\n    }\n\n    @Test\n    public void testDoubleRotateLeftRight() {\n        Node root = new AVLNode(5, null, null, null);\n        Node leftChild = new AVLNode(3, root, null, null);\n        root.left = leftChild;\n        Node leftGrandChild = new AVLNode(1, leftChild, null, null);\n        Node rightGrandChild = new AVLNode(4, leftChild, null, null);\n        leftChild.left = leftGrandChild;\n        leftChild.right = rightGrandChild;\n\n        AVLTree tree = new AVLTree();\n        Node rotated = tree.doubleRotateLeftRight(root);\n\n        Assert.assertEquals((int) rotated.value, 4);\n        Assert.assertEquals((int) rotated.left.value, 3);\n        Assert.assertEquals((int) rotated.right.value, 5);\n        Assert.assertEquals((int) rotated.left.left.value, 1);\n\n        Assert.assertNull(rotated.parent);\n        Assert.assertEquals(rotated.left.parent.value, rotated.value);\n        Assert.assertEquals(rotated.right.parent.value, rotated.value);\n        Assert.assertEquals(rotated.left.left.parent.value, rotated.left.value);\n    }\n}\n"
  },
  {
    "path": "Trees/src/test/java/org/intelligentjava/algos/trees/BaseBSTTest.java",
    "content": "package org.intelligentjava.algos.trees;\n\nimport org.intelligentjava.algos.trees.AbstractBinarySearchTree.Node;\nimport org.junit.Assert;\n\n/**\n * Superclass that contains some basic BST tests.\n * \n * @author Ignas\n *\n */\npublic class BaseBSTTest {\n    \n    protected void testTreeBSTProperties(Node entry) {\n        if (entry != null) {\n            // test heap properties and BST properties\n            if (entry.left != null) {\n                Assert.assertTrue(entry.value >= entry.left.value);\n            }\n            if (entry.right != null) {\n                Assert.assertTrue(entry.value <= entry.right.value);\n            }\n            testTreeBSTProperties(entry.left);\n            testTreeBSTProperties(entry.right);\n        }\n    }\n\n}\n"
  },
  {
    "path": "Trees/src/test/java/org/intelligentjava/algos/trees/BinarySearchTreeTest.java",
    "content": "package org.intelligentjava.algos.trees;\n\nimport org.junit.Assert;\nimport org.junit.Test;\n\n/**\n * Tests for simple unbalanced binary search tree.\n * \n * @author Ignas Lelys\n * @created May 6, 2011\n *\n */\npublic class BinarySearchTreeTest extends BaseBSTTest {\n    \n    @Test\n    public void testInsertDelete() {\n        BinarySearchTree tree = new BinarySearchTree();\n        tree.insert(10);\n        tree.insert(16);\n        tree.insert(1);\n        tree.insert(8);\n        Assert.assertTrue(tree.contains(10));\n        Assert.assertTrue(tree.contains(16));\n        Assert.assertTrue(tree.contains(1));\n        Assert.assertFalse(tree.contains(9));\n        tree.delete(16);\n        tree.delete(1);\n        Assert.assertFalse(tree.contains(16));\n        Assert.assertFalse(tree.contains(1));\n        \n        testTreeBSTProperties(tree.root);\n    }\n    \n    @Test\n    public void testSize() {\n        BinarySearchTree tree = new BinarySearchTree();\n        tree.insert(10);\n        tree.insert(16);\n        tree.insert(1);\n        Assert.assertEquals(tree.getSize(), 3);\n        tree.delete(16);\n        Assert.assertEquals(tree.getSize(), 2);\n        tree.delete(16);\n        Assert.assertEquals(tree.getSize(), 2);\n    }\n\n    @Test\n    public void testMinimumMaximum() {\n        BinarySearchTree tree = new BinarySearchTree();\n        tree.insert(10);\n        tree.insert(16);\n        tree.insert(1);\n        tree.insert(8);\n        Assert.assertEquals(tree.getMinimum(), 1);\n        Assert.assertEquals(tree.getMaximum(), 16);\n    }\n    \n    @Test\n    public void testGetSuccessor() {\n        BinarySearchTree tree = new BinarySearchTree();\n        tree.insert(15);\n        tree.insert(6);\n        tree.insert(18);\n        tree.insert(17);\n        tree.insert(20);\n        tree.insert(3);\n        tree.insert(7);\n        tree.insert(2);\n        tree.insert(4);\n        tree.insert(13);\n        tree.insert(9);\n        Assert.assertEquals(tree.getSuccessor(15), 17);\n        Assert.assertEquals(tree.getSuccessor(13), 15);\n    }\n}\n"
  },
  {
    "path": "Trees/src/test/java/org/intelligentjava/algos/trees/RedBlackTreeTest.java",
    "content": "package org.intelligentjava.algos.trees;\n\nimport org.intelligentjava.algos.trees.AbstractBinarySearchTree.Node;\nimport org.intelligentjava.algos.trees.RedBlackTree.ColorEnum;\nimport org.intelligentjava.algos.trees.RedBlackTree.RedBlackNode;\nimport org.junit.Assert;\nimport org.junit.Test;\n\nimport static org.hamcrest.CoreMatchers.equalTo;\nimport static org.hamcrest.MatcherAssert.assertThat;\n\n/**\n * Tests for Red-Black tree.\n * \n * @author Ignas Lelys\n * @created Jul 18, 2011\n *\n */\npublic class RedBlackTreeTest {\n    @Test\n    public void testInsertionFixupColoring() throws Exception {\n        RedBlackTree tree = new RedBlackTree();\n        Node node8 = tree.insert(8);\n        Node node3 = tree.insert(3);\n        Node node4 = tree.insert(4);\n        assertThat(((RedBlackNode)node3).color, equalTo(ColorEnum.RED));\n        assertThat(((RedBlackNode)node4).color, equalTo(ColorEnum.BLACK));\n        assertThat(((RedBlackNode)node8).color, equalTo(ColorEnum.RED));\n    }\n\n    @Test\n    public void testInsert() {\n        RedBlackTree tree = new RedBlackTree();\n        tree.insert(20);\n        tree.insert(15);\n        tree.insert(25);\n        tree.insert(10); // re color 15 and 25 to black on this insert\n        Assert.assertEquals(((RedBlackNode)tree.root).color, ColorEnum.BLACK);\n        Assert.assertEquals(((RedBlackNode)tree.search(15)).color, ColorEnum.BLACK);\n        Assert.assertEquals(((RedBlackNode)tree.search(25)).color, ColorEnum.BLACK);\n        tree.insert(17);\n        tree.insert(8);\n        Assert.assertEquals(((RedBlackNode)tree.search(15)).color, ColorEnum.RED);\n        Assert.assertEquals(((RedBlackNode)tree.search(10)).color, ColorEnum.BLACK);\n        Assert.assertEquals(((RedBlackNode)tree.search(17)).color, ColorEnum.BLACK);\n        Assert.assertEquals(((RedBlackNode)tree.search(8)).color, ColorEnum.RED);\n        tree.insert(9); // case 2/3 - rotation right, then left\n        Assert.assertEquals(((RedBlackNode)tree.search(10)).color, ColorEnum.RED);\n        Assert.assertEquals(((RedBlackNode)tree.search(8)).color, ColorEnum.RED);\n        Assert.assertEquals(((RedBlackNode)tree.search(9)).left.value, (Integer)8);\n        \n        // TODO test other red black tree properties too\n        testTreeBSTProperties(tree.root);\n    }\n    \n    @Test\n    public void testSimpleDelete() {\n        RedBlackTree tree = new RedBlackTree();\n        tree.insert(20);\n        tree.insert(15);\n        tree.insert(25);\n        tree.insert(23);\n        Assert.assertEquals(((RedBlackNode)tree.root).color, ColorEnum.BLACK);\n        Assert.assertEquals(tree.size, 4);\n        tree.delete(15);\n        Assert.assertEquals(tree.size, 3);\n        Assert.assertEquals(tree.root.value, (Integer)23); // new root\n        \n        testTreeBSTProperties(tree.root);\n    }\n    \n    @Test\n    public void testDelete() {\n        RedBlackTree tree = new RedBlackTree();\n        tree.insert(20);\n        tree.insert(15);\n        tree.insert(25);\n        tree.insert(23);\n        tree.insert(27);\n        Assert.assertEquals(((RedBlackNode)tree.root).color, ColorEnum.BLACK);\n        Assert.assertEquals(tree.size, 5);\n        Assert.assertEquals(tree.root.right.value, (Integer)25);\n        Assert.assertEquals(tree.root.right.left.value, (Integer)23);\n        Assert.assertEquals(((RedBlackNode)tree.root.right.left).color, ColorEnum.RED);\n        tree.delete(25);\n        Assert.assertEquals(tree.size, 4);\n        Assert.assertEquals(tree.root.value, (Integer)20);\n        Assert.assertEquals(tree.root.right.value, (Integer)27);\n        Assert.assertEquals(((RedBlackNode)tree.root.right).color, ColorEnum.BLACK);\n        Assert.assertEquals(tree.root.right.right.value, null);\n        Assert.assertEquals(tree.root.right.left.value, (Integer)23);\n        Assert.assertEquals(((RedBlackNode)tree.root.right.left).color, ColorEnum.RED);\n        \n        testTreeBSTProperties(tree.root);\n    }\n\n    \n    /**\n     * Test BST properties method for RedBlack tree. Not using the one from {@link BaseBSTTest} because RedBlack tree implementation uses nilNode instead of nulls.\n     */\n    private void testTreeBSTProperties(Node entry) {\n        if (entry != RedBlackTree.nilNode) {\n            // test heap properties and BST properties\n            if (entry.left != RedBlackTree.nilNode) {\n                Assert.assertTrue(entry.value >= entry.left.value);\n            }\n            if (entry.right != RedBlackTree.nilNode) {\n                Assert.assertTrue(entry.value <= entry.right.value);\n            }\n            testTreeBSTProperties(entry.left);\n            testTreeBSTProperties(entry.right);\n        }\n    }\n}\n"
  },
  {
    "path": "Trees/src/test/java/org/intelligentjava/algos/trees/ScapegoatTreeTest.java",
    "content": "package org.intelligentjava.algos.trees;\n\nimport org.intelligentjava.algos.trees.AbstractBinarySearchTree.Node;\nimport org.junit.Assert;\nimport org.junit.Test;\n\n/**\n * Scapegoat tree implementation tests.\n * \n * @author Ignas Lelys\n * @created Jul 28, 2011\n *\n */\npublic class ScapegoatTreeTest extends BaseBSTTest {\n    \n    \n    @Test\n    public void testInsertSorted() {\n        ScapegoatTree tree = new ScapegoatTree();\n        tree.insert(1);\n        tree.insert(2);\n        tree.insert(3);\n        tree.insert(4);\n        tree.insert(5);\n        tree.insert(6);\n        tree.insert(7);\n        tree.insert(8);\n        tree.insert(9);\n        tree.insert(10);\n        tree.insert(11);\n        tree.insert(12);\n        tree.insert(13);\n        tree.insert(14);\n        tree.insert(15);\n        tree.insert(16);\n        tree.insert(17);\n        tree.insert(18);\n        \n        Assert.assertEquals(18, tree.size);\n        Assert.assertEquals((Integer)5, tree.root.value);\n        testTreeBSTProperties(tree.root);\n    }\n\n    @Test\n    public void testInsertSortedDesc() {\n        ScapegoatTree tree = new ScapegoatTree();\n        tree.insert(18);\n        tree.insert(17);\n        tree.insert(16);\n        tree.insert(15);\n        tree.insert(14);\n        tree.insert(13);\n        tree.insert(12);\n        tree.insert(11);\n        tree.insert(10);\n        tree.insert(9);\n        tree.insert(8);\n        tree.insert(7);\n        tree.insert(6);\n        tree.insert(5);\n        tree.insert(4);\n        tree.insert(3);\n        tree.insert(2);\n        tree.insert(1);\n        tree.printTree();\n        \n        Assert.assertEquals(18, tree.size);\n        Assert.assertEquals((Integer)12, tree.root.value);\n        testTreeBSTProperties(tree.root);\n    }\n    \n    \n    @Test\n    public void testDeleteSortedDesc() {\n        ScapegoatTree tree = new ScapegoatTree();\n        tree.insert(18);\n        tree.insert(17);\n        tree.insert(16);\n        tree.insert(15);\n        tree.insert(14);\n        tree.insert(13);\n        tree.insert(12);\n        tree.insert(11);\n        tree.insert(10);\n        tree.insert(9);\n        tree.insert(8);\n        tree.insert(7);\n        tree.insert(6);\n        tree.insert(5);\n        tree.insert(4);\n        tree.insert(3);\n        tree.insert(2);\n        tree.insert(1);\n        tree.printTree();\n        \n        tree.delete(18);\n        tree.delete(17);\n        tree.delete(15);\n        tree.delete(14);\n        tree.delete(12);\n        tree.delete(10);\n        tree.delete(8);\n        tree.printTree();\n        \n        Assert.assertEquals(11, tree.size);\n        Assert.assertEquals((Integer)13, tree.root.value);\n        testTreeBSTProperties(tree.root);\n    }\n    \n    @Test\n    public void testBuildBigTree() {\n        ScapegoatTree tree = new ScapegoatTree(0.95);\n        for (int i = 0; i < 100; i++) {\n            tree.insert(i);\n        }\n        tree.printTree();\n        Assert.assertEquals(100, tree.size);\n        testTreeBSTProperties(tree.root);\n        \n        for (int i = 0; i < 50; i++) {\n            tree.delete(i);\n        }\n        tree.printTree();\n        Assert.assertEquals(50, tree.size);\n        testTreeBSTProperties(tree.root);\n    }\n    \n    \n    @Test\n    public void testGetSubtreeSize() {\n        Node root = new Node(4, null, null, null);\n        Node rightChild = new Node(6, root, null, null);\n        root.right = rightChild;\n        Node leftGrandChild = new Node(5, rightChild, null, null);\n        Node rightGrandChild = new Node(7, rightChild, null, null);\n        rightChild.left = leftGrandChild;\n        rightChild.right = rightGrandChild;\n        ScapegoatTree tree = new ScapegoatTree();\n        Assert.assertEquals(tree.getSubtreeSize(root), 4);\n    }\n    \n    @Test\n    public void testFindScapegoat() {\n        // TODO\n    }\n    \n    @Test\n    public void testRebuildTree() {\n        // TODO\n    }\n\n}\n"
  },
  {
    "path": "Trees/src/test/java/org/intelligentjava/algos/trees/SplayTreeTest.java",
    "content": "package org.intelligentjava.algos.trees;\n\nimport org.intelligentjava.algos.trees.AbstractBinarySearchTree.Node;\nimport org.junit.Assert;\nimport org.junit.Test;\n\n/**\n * Splay tree unit tests.\n * \n * @author Ignas Lelys\n * @created Jul 19, 2011\n *\n */\npublic class SplayTreeTest extends BaseBSTTest {\n    \n    @Test\n    public void testSearch() {\n        SplayTree splayTree = new SplayTree();\n        splayTree.insert(24);\n        splayTree.insert(20);\n        splayTree.insert(30);\n        splayTree.insert(39);\n        splayTree.insert(80);\n        splayTree.insert(11);\n        splayTree.search(24);\n        Assert.assertEquals(splayTree.root.value, (Integer)24);\n        Assert.assertEquals(splayTree.root.left.value, (Integer)11);\n        Assert.assertEquals(splayTree.root.left.right.value, (Integer)20);\n        Assert.assertEquals(splayTree.root.right.value, (Integer)80);\n        Assert.assertEquals(splayTree.root.right.left.value, (Integer)30);\n        Assert.assertEquals(splayTree.root.right.left.right.value, (Integer)39);\n    }\n    \n    @Test\n    public void testInsert() {\n        SplayTree splayTree = new SplayTree();\n        splayTree.insert(24);\n        splayTree.insert(20);\n        splayTree.insert(30);\n        splayTree.insert(39);\n        splayTree.insert(80);\n        splayTree.insert(11);\n        Assert.assertEquals(splayTree.root.value, (Integer) 11);\n        Assert.assertEquals(splayTree.root.right.value, (Integer) 80);\n        Assert.assertNull(splayTree.root.right.right);\n        Assert.assertEquals(splayTree.root.right.left.value, (Integer) 30);\n        Assert.assertEquals(splayTree.root.right.left.right.value, (Integer) 39);\n        Assert.assertEquals(splayTree.root.right.left.left.value, (Integer) 20);\n        Assert.assertEquals(splayTree.root.right.left.left.right.value, (Integer) 24);\n        \n        testTreeBSTProperties(splayTree.root);\n    }\n    \n    @Test\n    public void testDelete() {\n        SplayTree splayTree = new SplayTree();\n        splayTree.insert(22);\n        splayTree.insert(11);\n        splayTree.insert(10);\n        splayTree.insert(16);\n        splayTree.insert(15);\n        splayTree.insert(14);\n        // test insert\n        Assert.assertEquals(splayTree.root.value, (Integer)14);\n        Assert.assertEquals(splayTree.root.left.value, (Integer)11);\n        Assert.assertEquals(splayTree.root.left.left.value, (Integer)10);\n        Assert.assertEquals(splayTree.root.right.value, (Integer)15);\n        Assert.assertEquals(splayTree.root.right.right.value, (Integer)16);\n        Assert.assertEquals(splayTree.root.right.right.right.value, (Integer)22);\n        splayTree.delete(16);\n        Assert.assertEquals(splayTree.root.value, (Integer)15);\n        Assert.assertEquals(splayTree.root.right.value, (Integer)22);\n        Assert.assertEquals(splayTree.root.left.value, (Integer)14);\n        Assert.assertEquals(splayTree.root.left.left.value, (Integer)11);\n        Assert.assertEquals(splayTree.root.left.left.left.value, (Integer)10);\n        splayTree.delete(22);\n        Assert.assertEquals(splayTree.root.value, (Integer)15);\n        Assert.assertNull(splayTree.root.right);\n        Assert.assertEquals(splayTree.root.left.value, (Integer)14);\n        Assert.assertEquals(splayTree.root.left.left.value, (Integer)11);\n        Assert.assertEquals(splayTree.root.left.left.left.value, (Integer)10);\n        splayTree.delete(15);\n        Assert.assertEquals(splayTree.root.value, (Integer)14);\n        Assert.assertNull(splayTree.root.right);\n        Assert.assertEquals(splayTree.root.left.value, (Integer)11);\n        Assert.assertEquals(splayTree.root.left.left.value, (Integer)10);\n        \n        testTreeBSTProperties(splayTree.root);\n    }\n\n    @Test\n    public void testSplayZig() {\n        SplayTree splayTree = new SplayTree();\n        Node root = new Node(15, null, null, null);\n        splayTree.root = root;\n        Node left = new Node(10, root, null, null);\n        root.left = left;\n        splayTree.splay(left);\n        Assert.assertEquals(splayTree.root.value, (Integer) 10);\n        Assert.assertEquals(splayTree.root.right.value, (Integer) 15);\n        splayTree.splay(splayTree.root.right);\n        Assert.assertEquals(splayTree.root.value, (Integer) 15);\n        Assert.assertEquals(splayTree.root.left.value, (Integer) 10);\n    }\n\n    @Test\n    public void testSplayZigZig() {\n        SplayTree splayTree = new SplayTree();\n        Node root = new Node(15, null, null, null);\n        splayTree.root = root;\n        Node left = new Node(10, root, null, null);\n        Node leftleft = new Node(5, left, null, null);\n        left.left = leftleft;\n        root.left = left;\n        splayTree.splay(leftleft);\n        Assert.assertEquals(splayTree.root.value, (Integer) 5);\n        Assert.assertEquals(splayTree.root.right.value, (Integer) 10);\n        Assert.assertEquals(splayTree.root.right.right.value, (Integer) 15);\n        splayTree.splay(splayTree.root.right.right);\n        Assert.assertEquals(splayTree.root.value, (Integer) 15);\n        Assert.assertEquals(splayTree.root.left.value, (Integer) 10);\n        Assert.assertEquals(splayTree.root.left.left.value, (Integer) 5);\n    }\n\n    @Test\n    public void testSplayZigZag() {\n        SplayTree splayTree = new SplayTree();\n        Node root = new Node(15, null, null, null);\n        splayTree.root = root;\n        Node left = new Node(10, root, null, null);\n        Node leftright = new Node(12, left, null, null);\n        left.right = leftright;\n        root.left = left;\n        // zig zag left-right\n        splayTree.splay(leftright);\n        Assert.assertEquals(splayTree.root.value, (Integer) 12);\n        Assert.assertEquals(splayTree.root.right.value, (Integer) 15);\n        Assert.assertEquals(splayTree.root.left.value, (Integer) 10);\n        // zig zag from other side (right-left)\n        splayTree.root.right.left = new Node(13, splayTree.root.right, null, null);\n        splayTree.splay(splayTree.root.right.left);\n        Assert.assertEquals(splayTree.root.value, (Integer) 13);\n        Assert.assertEquals(splayTree.root.left.value, (Integer) 12);\n        Assert.assertEquals(splayTree.root.right.value, (Integer) 15);\n    }\n\n}\n"
  },
  {
    "path": "Trees/src/test/java/org/intelligentjava/algos/trees/TreapTest.java",
    "content": "package org.intelligentjava.algos.trees;\n\nimport org.intelligentjava.algos.trees.AbstractBinarySearchTree.Node;\nimport org.intelligentjava.algos.trees.Treap.TreapNode;\nimport org.junit.Assert;\nimport org.junit.Test;\n\n/**\n * Treap tests.\n * \n * @author Ignas Lelys\n * @created Jul 26, 2011\n * \n */\npublic class TreapTest extends BaseBSTTest {\n\n    // TODO check if after rotation other Nodes can destroy heap property (it shouldn't i think)\n    @Test\n    public void testInsert() {\n        Treap treap = new Treap() {\n            @Override\n            protected Node createNode(int value, Node parent, Node left, Node right) {\n                return new TreapNode(value, parent, left, right, Integer.MAX_VALUE); // create max integer priority instead of random\n            }\n        };\n        TreapNode root = new TreapNode(20, null, null, null, 100);\n        TreapNode rootLeft = new TreapNode(15, root, null, null, 99);\n        TreapNode rootRight = new TreapNode(25, root, null, null, 98);\n        root.left = rootLeft;\n        root.right = rootRight;\n        TreapNode rootLeftLeft = new TreapNode(14, rootLeft, null, null, 97);\n        TreapNode rootLeftRight = new TreapNode(17, rootLeft, null, null, 96);\n        rootLeft.left = rootLeftLeft;\n        rootLeft.right = rootLeftRight;\n        treap.root = root;\n        treap.insert(16);\n        // this should go to root because createNode sets highest priority\n        Assert.assertEquals(treap.size, 1); // because only one insert invoked (other nodes were added manually)\n        Assert.assertEquals(treap.root.value, (Integer) 16);\n        Assert.assertEquals(treap.root.right.value, (Integer) 20);\n        Assert.assertEquals(treap.root.right.right.value, (Integer) 25);\n        Assert.assertEquals(treap.root.right.left.value, (Integer) 17);\n        Assert.assertEquals(treap.root.left.value, (Integer) 15);\n        Assert.assertEquals(treap.root.left.left.value, (Integer) 14);\n    }\n    \n    @Test\n    public void testDelete() {\n        Treap treap = new Treap();\n        TreapNode root = new TreapNode(20, null, null, null, 100);\n        TreapNode rootLeft = new TreapNode(15, root, null, null, 99);\n        TreapNode rootRight = new TreapNode(25, root, null, null, 98);\n        root.left = rootLeft;\n        root.right = rootRight;\n        TreapNode rootLeftLeft = new TreapNode(14, rootLeft, null, null, 97);\n        TreapNode rootLeftRight = new TreapNode(17, rootLeft, null, null, 96);\n        rootLeft.left = rootLeftLeft;\n        rootLeft.right = rootLeftRight;\n        treap.root = root;\n        Node delete = treap.delete(20);\n        Assert.assertEquals(delete.value, (Integer) 15); \n    }\n    \n    @Test\n    public void testHeapPropertyAfterInsertAndDelete() {\n        Treap treap = new Treap();\n        treap.insert(23);\n        treap.insert(13);\n        treap.insert(56);\n        treap.insert(1);\n        treap.insert(34);\n        treap.insert(56);\n        treap.insert(33);\n        treap.insert(21);\n        treap.insert(65);\n        treap.insert(45);\n        treap.insert(76);\n        treap.insert(99);\n        treap.insert(43);\n        treap.insert(46);\n        treap.insert(77);\n        treap.insert(88);\n        treap.insert(102);\n        treap.insert(18);\n        treap.insert(123);\n        treap.insert(256);\n        treap.insert(111);\n        treap.insert(331);\n        treap.insert(2);\n        treap.insert(3);\n        treap.insert(4);\n        \n        Assert.assertEquals(25, treap.size);\n        testTreeBSTProperties(treap.root);\n        testHeapProperties(treap.root);        \n        treap.delete(1);\n        treap.delete(45);\n        treap.delete(43);\n        treap.delete(331);\n        treap.delete(3);\n\n        Assert.assertEquals(20, treap.size);\n        testTreeBSTProperties(treap.root);\n        testHeapProperties(treap.root);        \n    }\n    \n    private void testHeapProperties(Node entry) {\n        if (entry != null) {\n            // test heap properties and BST properties\n            if (entry.left != null) {\n                Assert.assertTrue(((TreapNode)entry).priority >= ((TreapNode)entry.left).priority);\n            }\n            if (entry.right != null) {\n                Assert.assertTrue(((TreapNode)entry).priority >= ((TreapNode)entry.right).priority);\n            }\n            testHeapProperties(entry.left);\n            testHeapProperties(entry.right);\n        }\n    }\n\n}\n"
  },
  {
    "path": "Trees/src/test/java/org/intelligentjava/algos/trees/utils/ArrayUtilsTest.java",
    "content": "package org.intelligentjava.algos.trees.utils;\n\nimport org.junit.Assert;\nimport org.junit.Test;\n\n/**\n * @author Ignas Lelys\n * @created May 3, 2011\n *\n */\npublic class ArrayUtilsTest {\n    \n    @Test\n    public void testSwap() {\n        int[] testArr = {1, 2, 4, 3};\n        ArrayUtils.swap(testArr, 2, 3);\n        Assert.assertEquals(testArr[0], 1);\n        Assert.assertEquals(testArr[1], 2);\n        Assert.assertEquals(testArr[2], 3);\n        Assert.assertEquals(testArr[3], 4);\n    }\n\n}\n"
  },
  {
    "path": "Trees/src/test/java/org/intelligentjava/algos/trees/utils/HeapUtilsTest.java",
    "content": "package org.intelligentjava.algos.trees.utils;\n\nimport org.junit.Assert;\nimport org.junit.Test;\n\n/**\n * @author Ignas Lelys\n * @created Apr 18, 2011\n *\n */\npublic class HeapUtilsTest {\n    \n    @Test\n    public void testBuildHeap() {\n        int[] testData = {16, 4, 10, 14, 7, 9, 3, 2, 8, 1};\n        int[] expectedData = {16, 14, 10, 8, 7, 9, 3, 2, 4, 1};\n        HeapUtils.buildMaxHeap(testData);\n        for (int i = 0; i < testData.length; i++) {\n            Assert.assertTrue(testData[i] == expectedData[i]);\n        }\n    }\n    \n    @Test\n    public void testMaxHeapify() {\n        int[] testData = {16, 4, 10, 14, 7, 9, 3, 2, 8, 1};\n        int[] expectedData = {16, 14, 10, 8, 7, 9, 3, 2, 4, 1};\n        HeapUtils.maxHeapify(testData, 1);\n        for (int i = 0; i < testData.length; i++) {\n            Assert.assertTrue(testData[i] == expectedData[i]);\n        }\n    }\n\n}\n"
  },
  {
    "path": "Trees/src/test/java/org/intelligentjava/algos/trees/utils/MathUtilsTest.java",
    "content": "package org.intelligentjava.algos.trees.utils;\n\nimport org.junit.Assert;\nimport org.junit.Test;\n\n/**\n * @author Ignas Lelys\n * @created May 3, 2011\n *\n */\npublic class MathUtilsTest {\n    \n    @Test\n    public void testGetDigitFromNumber() {\n        Assert.assertEquals(MathUtils.getDigitFromNumber(2233445, 0), 5);\n        Assert.assertEquals(MathUtils.getDigitFromNumber(2233445, 1), 4);\n        Assert.assertEquals(MathUtils.getDigitFromNumber(2233445, 2), 4);\n        Assert.assertEquals(MathUtils.getDigitFromNumber(2233445, 3), 3);\n        Assert.assertEquals(MathUtils.getDigitFromNumber(2233445, 4), 3);\n        Assert.assertEquals(MathUtils.getDigitFromNumber(2233445, 5), 2);\n        Assert.assertEquals(MathUtils.getDigitFromNumber(2233445, 6), 2);\n    }\n\n}\n"
  }
]