├── .gitignore ├── LICENSE ├── README.md ├── big-o-chart.png ├── bubble-sort.gif ├── insertion-sort.gif ├── merge-sort.gif ├── pom.xml ├── quick-sort.gif ├── quick-sort.html ├── selection-sort.gif └── src └── main └── java └── com └── zhokhov └── interview ├── data ├── ArrayList.java ├── BinaryTree.java ├── HashMap.java ├── LinkedList.java ├── Queue.java └── Stack.java ├── sorting ├── BubbleSort.java ├── InsertionSort.java ├── MergeSort.java ├── QuickSort.java └── SelectionSort.java └── util └── Console.java /.gitignore: -------------------------------------------------------------------------------- 1 | ### Java template 2 | *.class 3 | 4 | # Mobile Tools for Java (J2ME) 5 | .mtj.tmp/ 6 | 7 | # Package Files # 8 | *.jar 9 | *.war 10 | *.ear 11 | 12 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 13 | hs_err_pid* 14 | 15 | ### Eclipse template 16 | *.pydevproject 17 | .metadata 18 | .gradle 19 | bin/ 20 | tmp/ 21 | *.tmp 22 | *.bak 23 | *.swp 24 | *~.nib 25 | local.properties 26 | .settings/ 27 | .loadpath 28 | 29 | # Eclipse Core 30 | .project 31 | 32 | # External tool builders 33 | .externalToolBuilders/ 34 | 35 | # Locally stored "Eclipse launch configurations" 36 | *.launch 37 | 38 | # CDT-specific 39 | .cproject 40 | 41 | # JDT-specific (Eclipse Java Development Tools) 42 | .classpath 43 | 44 | # Java annotation processor (APT) 45 | .factorypath 46 | 47 | # PDT-specific 48 | .buildpath 49 | 50 | # sbteclipse plugin 51 | .target 52 | 53 | # TeXlipse plugin 54 | .texlipse 55 | 56 | ### Maven template 57 | target/ 58 | pom.xml.tag 59 | pom.xml.releaseBackup 60 | pom.xml.versionsBackup 61 | pom.xml.next 62 | release.properties 63 | dependency-reduced-pom.xml 64 | buildNumber.properties 65 | .mvn/timing.properties 66 | 67 | ### JetBrains template 68 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio 69 | 70 | *.iml 71 | 72 | ## Directory-based project format: 73 | .idea/ 74 | # if you remove the above rule, at least ignore the following: 75 | 76 | # User-specific stuff: 77 | # .idea/workspace.xml 78 | # .idea/tasks.xml 79 | # .idea/dictionaries 80 | 81 | # Sensitive or high-churn files: 82 | # .idea/dataSources.ids 83 | # .idea/dataSources.xml 84 | # .idea/sqlDataSources.xml 85 | # .idea/dynamic.xml 86 | # .idea/uiDesigner.xml 87 | 88 | # Gradle: 89 | # .idea/gradle.xml 90 | # .idea/libraries 91 | 92 | # Mongo Explorer plugin: 93 | # .idea/mongoSettings.xml 94 | 95 | ## File-based project format: 96 | *.ipr 97 | *.iws 98 | 99 | ## Plugin-specific files: 100 | 101 | # IntelliJ 102 | /out/ 103 | 104 | # mpeltonen/sbt-idea plugin 105 | .idea_modules/ 106 | 107 | # JIRA plugin 108 | atlassian-ide-plugin.xml 109 | 110 | # Crashlytics plugin (for Android Studio and IntelliJ) 111 | com_crashlytics_export_strings.xml 112 | crashlytics.properties 113 | crashlytics-build.properties 114 | 115 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | 203 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Data Structures and Algorithms in Java 2 | 3 | [![Analytics](https://ga-beacon.appspot.com/UA-71075299-1/interview/main-page)](https://github.com/igrigorik/ga-beacon) 4 | 5 | Very useful in interview process for Java Software Development Engineer (SDE). 6 | 7 | ## Big O Notation 8 | 9 | #### Big-O Complexity Chart 10 | ![Big-O Complexity Chart](https://raw.githubusercontent.com/donbeave/interview/master/big-o-chart.png) 11 | 12 | #### Constant — statement (one line of code) 13 | 14 | ```java 15 | a += 1; 16 | ``` 17 | 18 | Growth Rate: **1** 19 | 20 | #### Logarithmic — divide in half (binary search) 21 | 22 | ```java 23 | while (n > 1) { 24 | n = n / 2; 25 | } 26 | ``` 27 | 28 | Growth Rate: **log(n)** 29 | 30 | #### Linear — loop 31 | 32 | ```java 33 | for (int i = 0; i < n; i++) { 34 | // statements 35 | a += 1; 36 | } 37 | ``` 38 | 39 | Growth Rate: **n** 40 | 41 | The loop executes `N` times, so the sequence of statements also executes `N` times. If we assume the statements are `O(1)`, the total time for the for loop is `N * O(1)`, which is `O(N)` overall. 42 | 43 | #### Quadratic — Effective sorting algorithms 44 | 45 | ``` 46 | Mergesort, Quicksort, … 47 | ``` 48 | 49 | Growth Rate: **n*log(n)** 50 | 51 | #### Quadratic — double loop (nested loops) 52 | 53 | ```java 54 | for (int c = 0; c < n; c++) { 55 | for (int i = 0; i < n; i++) { 56 | // sequence of statements 57 | a += 1; 58 | } 59 | } 60 | ``` 61 | 62 | Growth Rate: **n^2** 63 | 64 | The outer loop executes N times. Every time the outer loop executes, the inner loop executes `M` times. As a result, the statements in the inner loop execute a total of `N * M` times. Thus, the complexity is `O(N * M)`. 65 | In a common special case where the stopping condition of the inner loop is `J < N` instead of `J < M` (i.e., the inner loop also executes `N` times), the total complexity for the two loops is `O(N2)`. 66 | 67 | #### Cubic — triple loop 68 | 69 | ```java 70 | for (c = 0; c < n; c++) { 71 | for (i = 0; i < n; i++) { 72 | for (x = 0; x < n; x++) { 73 | a += 1; 74 | } 75 | } 76 | } 77 | ``` 78 | 79 | Growth Rate: **n^3** 80 | 81 | #### Exponential — exhaustive search 82 | 83 | ``` 84 | Trying to break a password generating all possible combinations 85 | ``` 86 | 87 | Growth Rate: **2^n** 88 | 89 | ##### If-Then-Else 90 | 91 | ``` java 92 | if (cond) { 93 | block 1 (sequence of statements) 94 | } else { 95 | block 2 (sequence of statements) 96 | } 97 | ``` 98 | 99 | If `block 1` takes `O(1)` and `block 2` takes `O(N)`, the `if-then-else` statement would be `O(N)`. 100 | 101 | ##### Statements with function/ procedure calls 102 | 103 | When a statement involves a function/ procedure call, the complexity of the statement includes the complexity of the function/ procedure. Assume that you know that function/procedure `f` takes constant time, and that function/procedure `g` takes time proportional to (linear in) the value of its parameter `k`. Then the statements below have the time complexities indicated. 104 | 105 | `f(k)` has `O(1)` 106 | `g(k)` has `O(k)` 107 | 108 | When a loop is involved, the same rule applies. For example: 109 | 110 | ``` 111 | for J in 1 .. N loop 112 | g(J); 113 | end loop; 114 | ``` 115 | 116 | has complexity `(N2)`. The loop executes N times and each function/procedure call `g(N)` is complexity `O(N)`. 117 | 118 | ## Algorithms 119 | ## Simple Sorting 120 | 121 | ### Bubble Sort 122 | 123 | ![Bubble Sort animation](https://raw.githubusercontent.com/donbeave/interview/master/bubble-sort.gif) 124 | 125 | [Implementation](https://github.com/donbeave/interview/blob/master/src/main/java/com/zhokhov/interview/sorting/BubbleSort.java) 126 | 127 | The bubble sort is notoriously slow, but it’s conceptually the simplest of the sorting algorithms. 128 | 129 | ##### Sorting process 130 | 131 | 1. Compare two items. 132 | 2. If the one on the left is bigger, swap them. 133 | 3. Move one position right. 134 | 135 | ##### Efficiency 136 | 137 | For `10` data items, this is `45` comparisons (`9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1`). 138 | 139 | In general, where `N` is the number of items in the array, there are `N-1` comparisons on the first pass, `N-2` on the second, and so on. The formula for the sum of such a series is 140 | `(N–1) + (N–2) + (N–3) + ... + 1 = N*(N–1)/2 N*(N–1)/2 is 45 (10*9/2)` when `N` is `10`. 141 | 142 | ### Selection Sort 143 | 144 | ![Selection Sort animation](https://raw.githubusercontent.com/donbeave/interview/master/selection-sort.gif) 145 | 146 | [Implementation](https://github.com/donbeave/interview/blob/master/src/main/java/com/zhokhov/interview/sorting/SelectionSort.java) 147 | 148 | [Simple explanation](http://www.codenlearn.com/2011/07/simple-selection-sort.html) 149 | 150 | The selection sort improves on the bubble sort by reducing the number of swaps necessary from `O(N2)` to `O(N)`. Unfortunately, the number of comparisons remains `O(N2)`. However, the selection sort can still offer a significant improvement for large records that must be physically moved around in memory, causing the swap time to be much more important than the comparison time. 151 | 152 | ##### Efficiency 153 | 154 | The selection sort performs the same number of comparisons as the bubble sort: `N*(N-1)/2`. For `10` data items, this is `45` comparisons. However, `10` items require fewer than `10` swaps. With `100` items, `4,950` comparisons are required, but fewer than `100` swaps. For large values of `N`, the comparison times will dominate, so we would have to say that the selection sort runs in `O(N2)` time, just as the bubble sort did. 155 | 156 | ### Insertion Sort 157 | 158 | ![Insertion Sort animation](https://raw.githubusercontent.com/donbeave/interview/master/insertion-sort.gif) 159 | 160 | [Implementation](https://github.com/donbeave/interview/blob/master/src/main/java/com/zhokhov/interview/sorting/InsertionSort.java) 161 | 162 | [Simple explanation](http://www.codenlearn.com/2011/07/simple-insertion-sort.html) 163 | 164 | In most cases the insertion sort is the best of the elementary sorts described in this chapter. It still executes in `O(N2)` time, but it’s about twice as fast as the bubble sort and somewhat faster than the selection sort in normal situations. It’s also not too complex, although it’s slightly more involved than the bubble and selection sorts. It’s often used as the final stage of more sophisticated sorts, such as quicksort. 165 | 166 | ##### Efficiency 167 | 168 | How many comparisons and copies does this algorithm require? On the first pass, it compares a maximum of one item. On the second pass, it’s a maximum of two items, and so on, up to a maximum of N-1 comparisons on the last pass. This is `1 + 2 + 3 + ... + N-1 = N*(N-1)/2` 169 | 170 | However, because on each pass an average of only half of the maximum number of items are actually compared before the insertion point is found, we can divide by 2, which gives `N*(N-1)/4` 171 | 172 | The number of copies is approximately the same as the number of comparisons. However, a copy isn’t as time-consuming as a swap, so for random data this algorithm runs twice as fast as the bubble sort and faster than the selection sort. 173 | 174 | In any case, like the other sort routines in this chapter, the insertion sort runs in `O(N2)` time for random data. 175 | 176 | For data that is already sorted or almost sorted, the insertion sort does much better. When data is in order, the condition in the while loop is never true, so it becomes a simple statement in the outer loop, which executes `N-1` times. In this case the algorithm runs in `O(N)` time. If the data is almost sorted, insertion sort runs in almost `O(N)` time, which makes it a simple and efficient way to order a file that is only slightly out of order. 177 | 178 | ## Advanced Sorting 179 | 180 | ### Merge Sort 181 | 182 | ![Merge Sort animation](https://raw.githubusercontent.com/donbeave/interview/master/merge-sort.gif) 183 | 184 | [Implementation](https://github.com/donbeave/interview/blob/master/src/main/java/com/zhokhov/interview/sorting/MergeSort.java) 185 | 186 | [Simple explanation](http://www.codenlearn.com/2011/10/simple-merge-sort.html) 187 | 188 | mergesort is a much more efficient sorting technique than those we saw in "Simple Sorting", at least in terms of speed. While the bubble, insertion, and selection sorts take `O(N2)` time, the mergesort is `O(N*logN)`. 189 | 190 | For example, if `N` (the number of items to be sorted) is `10,000`, then `N2` is `100,000,000`, while `N*logN` is only `40,000`. If sorting this many items required `40` seconds with the mergesort, it would take almost `28` hours for the insertion sort. 191 | 192 | The mergesort is also fairly easy to implement. It’s conceptually easier than quicksort and the Shell short. 193 | 194 | The heart of the mergesort algorithm is the merging of two already-sorted arrays. Merging two sorted arrays `A` and `B` creates a third array, `C`, that contains all the elements of `A` and `B`, also arranged in sorted order. 195 | 196 | Similar to quicksort the list of element which should be sorted is divided into two lists. These lists are sorted independently and then combined. During the combination of the lists the elements are inserted (or merged) on the correct place in the list. 197 | 198 | You divide the half into two quarters, sort each of the quarters, and merge them to make a sorted half. 199 | 200 | ##### Sorting process 201 | 202 | 1. Assume the size of the left array is k, the size of the right array is m and the size of the total array is n (=k+m). 203 | 2. Create a helper array with the size n 204 | 3. Copy the elements of the left array into the left part of the helper array. This is position 0 until k-1. 205 | 4. Copy the elements of the right array into the right part of the helper array. This is position k until m-1. 206 | 5. Create an index variable i=0; and j=k+1 207 | 6. Loop over the left and the right part of the array and copy always the smallest value back into the original array. Once i=k all values have been copied back the original array. The values of the right array are already in place. 208 | 209 | ##### Efficiency 210 | 211 | As we noted, the mergesort runs in `O(N*logN)` time. There are `24` copies necessary to sort `8` items. `Log28` is `3`, so `8*log28` equals `24`. This shows that, for the case of `8` items, the number of copies is proportional to `N*log2N`. 212 | 213 | In the mergesort algorithm, the number of comparisons is always somewhat less than the number of copies. 214 | 215 | ##### Comparison with Quicksort 216 | 217 | Compared to quicksort the mergesort algorithm puts less effort in dividing the list but more into the merging of the solution. 218 | 219 | Quicksort can sort "inline" of an existing collection, e.g. it does not have to create a copy of the collection while Standard mergesort does require a copy of the array although there are (complex) implementations of mergesort which allow to avoid this copying. 220 | 221 | ### Quick Sort 222 | 223 | ![Quick Sort animation](https://raw.githubusercontent.com/donbeave/interview/master/quick-sort.gif) 224 | 225 | [Implementation](https://github.com/donbeave/interview/blob/master/src/main/java/com/zhokhov/interview/sorting/QuickSort.java) 226 | 227 | [Simple explanation](http://me.dt.in.th/page/Quicksort/) 228 | [Simple explanation 2](http://www.mycstutorials.com/articles/sorting/quicksort) 229 | 230 | Quicksort is undoubtedly the most popular sorting algorithm, and for good reason: In the majority of situations, it’s the fastest, operating in `O(N*logN)` time. (This is only true for internal or in-memory sorting; for sorting data in disk files, other algorithms may be better.) 231 | 232 | To understand quicksort, you should be familiar with the partitioning algorithm. 233 | 234 | Quicksort algorithm operates by partitioning an array into two sub-arrays and then calling itself recursively to quicksort each of these subarrays. 235 | 236 | ##### Sorting process 237 | 238 | [Preview](https://rawgit.com/donbeave/interview/master/quick-sort.html) 239 | 240 | If the array contains only one element or zero elements then the array is sorted. 241 | 242 | If the array contains more then one element then: 243 | 244 | 1. Select an element from the array. This element is called the "pivot element". For example select the element in the middle of the array. 245 | 2. All elements which are smaller then the pivot element are placed in one array and all elements which are larger are placed in another array. 246 | 3. Sort both arrays by recursively applying Quicksort to them. 247 | 4. Combine the arrays. 248 | 249 | Quicksort can be implemented to sort "in-place". This means that the sorting takes place in the array and that no additional array need to be created. 250 | 251 | ##### Efficiency 252 | 253 | Quicksort operates in `O(N*logN)` time. This is generally true of the divide-and-conquer algorithms, in which a recursive method divides a range of items into two groups and then calls itself to handle each group. In this situation the logarithm actually has a base of `2`: The running time is proportional to `N*log2N`. 254 | 255 | ##### Standard Java Array sorting 256 | 257 | Java offers a standard way of sorting Arrays with `Arrays.sort()`. This sort algorithm is a modified quicksort which show more frequently a complexity of `O(n log(n))`. See the Javadoc for details. 258 | 259 | ## Data Structures 260 | 261 | ### Stacks 262 | 263 | A stack allows access to only one data item: the last item inserted. If you remove this item, you can access the next-to-last item inserted, and so on. 264 | 265 | A stack is also a handy aid for algorithms applied to certain complex data structures. In "Binary Trees", we’ll see it used to help traverse the nodes of a tree. 266 | 267 | Notice how the order of the data is reversed. Because the last item pushed is the first one popped. 268 | 269 | ##### Efficiency 270 | 271 | Items can be both pushed and popped from the stack implemented in the Stack class in constant `O(1)` time. That is, the time is not dependent on how many items are in the stack and is therefore very quick. No comparisons or moves are necessary. 272 | 273 | ### Queues 274 | 275 | A queue is a data structure that is some- what like a stack, except that in a queue the first item inserted is the first to be removed (First-In-First-Out, `FIFO`), while in a stack, as we’ve seen, the last item inserted is the first to be removed (`LIFO`). 276 | 277 | #### Deques 278 | 279 | A deque is a double-ended queue. You can insert items at either end and delete them from either end. The methods might be called `insertLeft()` and `insertRight()`, and `removeLeft()` and `removeRight()`. 280 | 281 | #### Priority Queues 282 | 283 | A priority queue is a more specialized data structure than a stack or a queue. However, it’s a useful tool in a surprising number of situations. Like an ordinary queue, a priority queue has a front and a rear, and items are removed from the front. However, in a priority queue, items are ordered by key value so that the item with the lowest key (or in some implementations the highest key) is always at the front. Items are inserted in the proper position to maintain the order. 284 | 285 | ##### Efficiency 286 | 287 | In the priority-queue implementation we show here, insertion runs in `O(N)` time, while deletion takes `O(1)` time. 288 | 289 | ### Linked List 290 | 291 | Arrays had certain disadvantages as data storage structures. In an unordered array, searching is slow, whereas in an ordered array, insertion is slow. In both kinds of arrays, deletion is slow. Also, the size of an array can’t be changed after it’s created. 292 | 293 | We’ll look at a data storage structure that solves some of these problems: the linked list. Linked lists are probably the second most commonly used general-purpose storage structures after arrays. 294 | 295 | #### Links 296 | 297 | In a linked list, each data item is embedded in a link. A link is an object of a class called something like Link. Each Link object contains a reference (usually called next) to the next link in the list. 298 | 299 | The LinkList class contains only one data item: a reference to the first link on the list. This reference is called first. It’s the only permanent information the list maintains about the location of any of the links. It finds the other links by following the chain of references from first, using each link’s next field. 300 | 301 | #### Double-Ended Lists 302 | 303 | A double-ended list is similar to an ordinary linked list, but it has one additional feature: a reference to the last link as well as to the first. 304 | 305 | The reference to the last link permits you to insert a new link directly at the end of the list as well as at the beginning. Of course, you can insert a new link at the end of an ordinary single-ended list by iterating through the entire list until you reach the end, but this approach is inefficient. 306 | 307 | Access to the end of the list as well as the beginning makes the double-ended list suitable for certain situations that a single-ended list can’t handle efficiently. One such situation is implementing a queue; we’ll see how this technique works in the next section. 308 | 309 | ##### Linked-List Efficiency 310 | 311 | Insertion and deletion at the beginning of a linked list are very fast. They involve changing only one or two references, which takes `O(1)` time. 312 | 313 | Finding, deleting, or inserting next to a specific item requires searching through, on the average, half the items in the list. This requires `O(N)` comparisons. An array is also `O(N)` for these operations, but the linked list is nevertheless faster because nothing needs to be moved when an item is inserted or deleted. The increased effi- ciency can be significant, especially if a copy takes much longer than a comparison. 314 | 315 | Of course, another important advantage of linked lists over arrays is that a linked list uses exactly as much memory as it needs and can expand to fill all of available memory. 316 | 317 | #### Sorted Lists 318 | 319 | In the linked lists we’ve seen thus far, there was no requirement that data be stored in order. However, for certain applications it’s useful to maintain the data in sorted order within the list. A list with this characteristic is called a sorted list. 320 | 321 | In a sorted list, the items are arranged in sorted order by key value. Deletion is often limited to the smallest (or the largest) item in the list, which is at the start of the list, although sometimes `find()` and `delete()` methods, which search through the list for specified links, are used as well. 322 | 323 | ##### Efficiency of Sorted Linked Lists 324 | 325 | Insertion and deletion of arbitrary items in the sorted linked list require `O(N)` comparisons (`N/2` on the average) because the appropriate location must be found by stepping through the list. However, the minimum value can be found, or deleted, in `O(1)` time because it’s at the beginning of the list. If an application frequently accesses the minimum item, and fast insertion isn’t critical, then a sorted linked list is an effective choice. A priority queue might be implemented by a sorted linked list, for example. 326 | 327 | #### Doubly Linked Lists 328 | 329 | Let’s examine another variation on the linked list: the doubly linked list (not to be confused with the double-ended list). What’s the advantage of a doubly linked list? A potential problem with ordinary linked lists is that it’s difficult to traverse backward along the list. A statement like 330 | current=current.next 331 | steps conveniently to the next link, but there’s no corresponding way to go to the previous link. 332 | 333 | The doubly linked list provides this capability. It allows you to traverse backward as well as forward through the list. The secret is that each link has two references to other links instead of one. The first is to the next link, as in ordinary lists. The second is to the previous link. 334 | 335 | #### Doubly Linked List as Basis for Deques 336 | 337 | A doubly linked list can be used as the basis for a deque. In a deque you can insert and delete at either end, and the doubly linked list provides this capability. 338 | 339 | ### Iterator 340 | 341 | Objects containing references to items in data structures, used to traverse these structures, are commonly called iterators (or sometimes, as in certain Java classes, enumerators). 342 | 343 | ### Hash Tables 344 | 345 | One important concept is how a range of key values is transformed into a range of array index values. In a hash table this is accomplished with a hash function. However, for certain kinds of keys, no hash function is necessary; the key values can be used directly as array indices. 346 | 347 | Thus, we look for a way to squeeze a range of 0 to more than `7,000,000,000,000` into the range `0` to `100,000`. A simple approach is to use the **modulo operator** (`%`), which finds the remainder when one number is divided by another: 348 | 349 | ``` 350 | arrayIndex = hugeNumber % arraySize; 351 | ``` 352 | 353 | This is an example of a hash function. It hashes (converts) a number in a large range into a number in a smaller range. 354 | 355 | ##### Hashing Efficiency 356 | 357 | Insertion and searching in hash tables can approach `O(1)` time. If no collision occurs, only a call to the hash function and a single array reference are necessary to insert a new item or find an existing item. This is the minimum access time. 358 | 359 | ### Algorithms and Data Structures of JDK 7 360 | 361 | http://www.yetanothercoder.ru/2013/06/algorithms-and-data-structures-of-jdk-7.html 362 | 363 | # Top 10 Object Oriented Design Principles 364 | 365 | 1. **DRY (Don't repeat yourself)** — avoids duplication in code 366 | 2. **Encapsulate what changes** — hides implementation detail, helps in maintenance 367 | 3. **Open Closed design principle** — open for extension, closed for modification 368 | 4. **SRP (Single Responsibility Principle)** — one class should do one thing and do it well 369 | 5. **DIP (Dependency Inversion Principle)** — don't ask, let framework give to you 370 | 6. **Favor Composition over Inheritance** — code reuse without cost of inflexibility 371 | 7. **LSP (Liskov Substitution Principle)** — sub type must be substitutable for super type 372 | 8. **ISP (Interface Segregation Pricinciple)** — avoid monilithic interface, reduce pain on client side 373 | 9. **Programming for Interface** — helps in maintenance, improves flexibility 374 | 10. **Delegation principle** — don't do all things by yourself, delegate it 375 | 376 | ### TODO 377 | 378 | 1. triangular numbers 379 | 2. heap sort, binary search (BST) 380 | 3. OBJECT ORIENTED DESIGN. Major concepts, are the use of patterns necessary? 381 | 4. How does dynamic recompilation work in Resin (or any other Java servlet container) 382 | 5. write a O(log(n)) function 383 | 384 | ### Sources 385 | 386 | 1. [Data Structures and Algorithms in Java, second edition by Robert Lafore](http://rineshpk.weebly.com/uploads/1/8/2/0/1820991/data_structures_and_algorithms_in_javatqw_darksiderg.pdf) 387 | 2. [10 Object Oriented Design Principles Java Programmer should know](http://javarevisited.blogspot.com/2012/03/10-object-oriented-design-principles.html) 388 | 3. [Design Patterns](http://www.oodesign.com/) 389 | 4. [Algorithms for Dummies (Part 1): Big-O Notation and Sorting](http://adrianmejia.com/blog/2014/02/13/algorithms-for-dummies-part-1-sorting/) 390 | 5. [Big O notation](http://web.mit.edu/16.070/www/lecture/big_o.pdf) 391 | 6. [A beginner's guide to Big O notation](https://rob-bell.net/2009/06/a-beginners-guide-to-big-o-notation/) 392 | 7. [Big O Notation. Using not-boring math to measure code's efficiency](https://www.interviewcake.com/article/big-o-notation-time-and-space-complexity) 393 | 8. [Understanding Algorithm complexity, Asymptotic and Big-O notation](http://www.codenlearn.com/2011/07/understanding-algorithm-complexity.html) 394 | 9. [Big-O Algorithm Complexity Cheat Sheet](http://bigocheatsheet.com) 395 | 10. [Algorithms in Java](http://www.vogella.com/tutorials/JavaAlgorithms/article.html) 396 | 11. [Mergesort in Java](http://www.vogella.com/tutorials/JavaAlgorithmsMergesort/article.html) 397 | 12. [Quicksort in Java](http://www.vogella.com/tutorials/JavaAlgorithmsQuicksort/article.html) 398 | 399 | ``` 400 | You are free to use this code anywhere, copy, modify and redistribute at your own risk. 401 | Your are solely responsibly for any damage that may occur by using this code. 402 | 403 | This code is not tested for all boundary conditions. Use it at your own risk. 404 | ``` 405 | 406 | ## Contributors 407 | * [Alexey Zhokhov](http://www.zhokhov.com) 408 | 409 | ## Contributing 410 | 411 | Please contribute using [Github Flow](https://guides.github.com/introduction/flow/). Create a branch, add commits, and [open a pull request](https://github.com/donbeave/interview/compare/). 412 | 413 | ## Btw, 414 | 415 | You deserve to smell great. 416 | 417 | [![Scentbird](https://s3-eu-west-1.amazonaws.com/scentbird/github-logo-no-shadow.svg)](https://www.scentbird.com/r/d/donbeave) 418 | 419 | "Subscribe today and get your 2nd perfume FREE" 420 | -------------------------------------------------------------------------------- /big-o-chart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/donbeave/interview/644bcf293f3338767dd4ed63b4138a4c5937343b/big-o-chart.png -------------------------------------------------------------------------------- /bubble-sort.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/donbeave/interview/644bcf293f3338767dd4ed63b4138a4c5937343b/bubble-sort.gif -------------------------------------------------------------------------------- /insertion-sort.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/donbeave/interview/644bcf293f3338767dd4ed63b4138a4c5937343b/insertion-sort.gif -------------------------------------------------------------------------------- /merge-sort.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/donbeave/interview/644bcf293f3338767dd4ed63b4138a4c5937343b/merge-sort.gif -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | com.zhokhov 5 | interview 6 | jar 7 | 1.0-SNAPSHOT 8 | interview 9 | http://maven.apache.org 10 | 11 | -------------------------------------------------------------------------------- /quick-sort.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/donbeave/interview/644bcf293f3338767dd4ed63b4138a4c5937343b/quick-sort.gif -------------------------------------------------------------------------------- /quick-sort.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Quick Sort Algorithm. Step by step. 5 | 85 | 86 | 87 | 88 | 89 |

Quick Sort Algorithm. Step by step.

90 | 91 |
92 |
93 |
7
94 |
0
95 |
96 |
97 |
1
98 |
1
99 |
100 |
101 |
8
102 |
2
103 |
104 |
105 |
2
106 |
3
107 |
108 |
109 |
0
110 |
4
111 |
112 |
113 |
12
114 |
5
115 |
116 |
117 |
10
118 |
6
119 |
120 |
121 |
6
122 |
7
123 |
124 |
125 |
5
126 |
8
127 |
128 |
129 |
3
130 |
9
131 |
132 |
133 | 134 |
135 |
Step 1. Pivot value: 7   Swapping indexes: 2 and 9
136 |
137 |
7
138 |
0
139 |
140 |
141 |
1
142 |
1
143 |
144 |
145 |
3
146 |
2
147 |
148 |
149 |
2
150 |
3
151 |
152 |
153 |
0
154 |
4
155 |
156 |
157 |
12
158 |
5
159 |
160 |
161 |
10
162 |
6
163 |
164 |
165 |
6
166 |
7
167 |
168 |
169 |
5
170 |
8
171 |
172 |
173 |
8
174 |
9
175 |
176 |
177 | 178 |
179 |
Step 2. Pivot value: 7   Swapping indexes: 5 and 8
180 |
181 |
7
182 |
0
183 |
184 |
185 |
1
186 |
1
187 |
188 |
189 |
3
190 |
2
191 |
192 |
193 |
2
194 |
3
195 |
196 |
197 |
0
198 |
4
199 |
200 |
201 |
5
202 |
5
203 |
204 |
205 |
10
206 |
6
207 |
208 |
209 |
6
210 |
7
211 |
212 |
213 |
12
214 |
8
215 |
216 |
217 |
8
218 |
9
219 |
220 |
221 | 222 |
223 |
Step 3. Pivot value: 7   Swapping indexes: 6 and 7
224 |
225 |
7
226 |
0
227 |
228 |
229 |
1
230 |
1
231 |
232 |
233 |
3
234 |
2
235 |
236 |
237 |
2
238 |
3
239 |
240 |
241 |
0
242 |
4
243 |
244 |
245 |
5
246 |
5
247 |
248 |
249 |
6
250 |
6
251 |
252 |
253 |
10
254 |
7
255 |
256 |
257 |
12
258 |
8
259 |
260 |
261 |
8
262 |
9
263 |
264 |
265 | 266 |
267 |
Step 4. Pivot value: 7   Swapping indexes: 0 and 6
268 |
269 |
6
270 |
0
271 |
272 |
273 |
1
274 |
1
275 |
276 |
277 |
3
278 |
2
279 |
280 |
281 |
2
282 |
3
283 |
284 |
285 |
0
286 |
4
287 |
288 |
289 |
5
290 |
5
291 |
292 |
293 |
7
294 |
6
295 |
296 |
297 |
10
298 |
7
299 |
300 |
301 |
12
302 |
8
303 |
304 |
305 |
8
306 |
9
307 |
308 |
309 | 310 |
311 |
Step 5. Pivot value: 6   Swapping indexes: 0 and 5
312 |
313 |
5
314 |
0
315 |
316 |
317 |
1
318 |
1
319 |
320 |
321 |
3
322 |
2
323 |
324 |
325 |
2
326 |
3
327 |
328 |
329 |
0
330 |
4
331 |
332 |
333 |
6
334 |
5
335 |
336 |
337 |
7
338 |
6
339 |
340 |
341 |
10
342 |
7
343 |
344 |
345 |
12
346 |
8
347 |
348 |
349 |
8
350 |
9
351 |
352 |
353 | 354 |
355 |
Step 6. Pivot value: 5   Swapping indexes: 0 and 4
356 |
357 |
0
358 |
0
359 |
360 |
361 |
1
362 |
1
363 |
364 |
365 |
3
366 |
2
367 |
368 |
369 |
2
370 |
3
371 |
372 |
373 |
5
374 |
4
375 |
376 |
377 |
6
378 |
5
379 |
380 |
381 |
7
382 |
6
383 |
384 |
385 |
10
386 |
7
387 |
388 |
389 |
12
390 |
8
391 |
392 |
393 |
8
394 |
9
395 |
396 |
397 | 398 |
399 |
Step 7. Pivot value: 0   Swapping indexes: 0 and 0
400 |
401 |
0
402 |
0
403 |
404 |
405 |
1
406 |
1
407 |
408 |
409 |
3
410 |
2
411 |
412 |
413 |
2
414 |
3
415 |
416 |
417 |
5
418 |
4
419 |
420 |
421 |
6
422 |
5
423 |
424 |
425 |
7
426 |
6
427 |
428 |
429 |
10
430 |
7
431 |
432 |
433 |
12
434 |
8
435 |
436 |
437 |
8
438 |
9
439 |
440 |
441 | 442 |
443 |
Step 8. Pivot value: 1   Swapping indexes: 1 and 1
444 |
445 |
0
446 |
0
447 |
448 |
449 |
1
450 |
1
451 |
452 |
453 |
3
454 |
2
455 |
456 |
457 |
2
458 |
3
459 |
460 |
461 |
5
462 |
4
463 |
464 |
465 |
6
466 |
5
467 |
468 |
469 |
7
470 |
6
471 |
472 |
473 |
10
474 |
7
475 |
476 |
477 |
12
478 |
8
479 |
480 |
481 |
8
482 |
9
483 |
484 |
485 | 486 |
487 |
Step 9. Pivot value: 3   Swapping indexes: 2 and 3
488 |
489 |
0
490 |
0
491 |
492 |
493 |
1
494 |
1
495 |
496 |
497 |
2
498 |
2
499 |
500 |
501 |
3
502 |
3
503 |
504 |
505 |
5
506 |
4
507 |
508 |
509 |
6
510 |
5
511 |
512 |
513 |
7
514 |
6
515 |
516 |
517 |
10
518 |
7
519 |
520 |
521 |
12
522 |
8
523 |
524 |
525 |
8
526 |
9
527 |
528 |
529 | 530 |
531 |
Step 10. Pivot value: 10   Swapping indexes: 8 and 9
532 |
533 |
0
534 |
0
535 |
536 |
537 |
1
538 |
1
539 |
540 |
541 |
2
542 |
2
543 |
544 |
545 |
3
546 |
3
547 |
548 |
549 |
5
550 |
4
551 |
552 |
553 |
6
554 |
5
555 |
556 |
557 |
7
558 |
6
559 |
560 |
561 |
10
562 |
7
563 |
564 |
565 |
8
566 |
8
567 |
568 |
569 |
12
570 |
9
571 |
572 |
573 | 574 |
575 |
Step 11. Pivot value: 10   Swapping indexes: 7 and 8
576 |
577 |
0
578 |
0
579 |
580 |
581 |
1
582 |
1
583 |
584 |
585 |
2
586 |
2
587 |
588 |
589 |
3
590 |
3
591 |
592 |
593 |
5
594 |
4
595 |
596 |
597 |
6
598 |
5
599 |
600 |
601 |
7
602 |
6
603 |
604 |
605 |
8
606 |
7
607 |
608 |
609 |
10
610 |
8
611 |
612 |
613 |
12
614 |
9
615 |
616 |
617 | 618 | 619 | 620 | -------------------------------------------------------------------------------- /selection-sort.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/donbeave/interview/644bcf293f3338767dd4ed63b4138a4c5937343b/selection-sort.gif -------------------------------------------------------------------------------- /src/main/java/com/zhokhov/interview/data/ArrayList.java: -------------------------------------------------------------------------------- 1 | /* 2 | * You are free to use this code anywhere, copy, modify and redistribute at your 3 | * own risk. 4 | * Your are solely responsibly for any damage that may occur by using this code. 5 | * 6 | * This code is not tested for all boundary conditions. Use it at your own risk. 7 | * 8 | * Original code: http://www.journaldev.com/110/how-to-implement-arraylist-with-array-in-java 9 | */ 10 | package com.zhokhov.interview.data; 11 | 12 | /** 13 | * @author Alexey Zhokhov 14 | */ 15 | public class ArrayList { 16 | 17 | private static final int SIZE_FACTOR = 5; 18 | 19 | private Object data[]; 20 | 21 | private int index; 22 | 23 | private int size; 24 | 25 | public ArrayList() { 26 | this.data = new Object[SIZE_FACTOR]; 27 | this.size = SIZE_FACTOR; 28 | } 29 | 30 | public void add(Object item) { 31 | System.out.println("index:" + this.index + "size:" + this.size + "data size:" + this.data.length); 32 | 33 | if (this.index == this.size - 1) { 34 | //we need to increase the size of data[] 35 | increaseSizeAndReallocate(); 36 | } 37 | 38 | data[this.index] = item; 39 | this.index++; 40 | } 41 | 42 | private void increaseSizeAndReallocate() { 43 | this.size = this.size + SIZE_FACTOR; 44 | 45 | // TODO: Arrays.copyOf() 46 | Object newData[] = new Object[this.size]; 47 | 48 | // TODO: System.arraycopy(data, 0, newData, 0, data.length); 49 | for (int i = 0; i < data.length; i++) { 50 | newData[i] = data[i]; 51 | } 52 | 53 | this.data = newData; 54 | 55 | System.out.println("***index:" + this.index + "size:" + this.size + "data size:" + this.data.length); 56 | } 57 | 58 | public Object get(int index) throws Exception { 59 | if (index > this.index - 1) { 60 | throw new Exception("ArrayIndexOutOfBound"); 61 | } 62 | if (index < 0) { 63 | throw new Exception("Negative Value"); 64 | } 65 | 66 | return this.data[index]; 67 | } 68 | 69 | public void remove(int removeIndex) throws Exception { 70 | if (removeIndex > this.index - 1) { 71 | throw new Exception("ArrayIndexOutOfBound"); 72 | } 73 | if (removeIndex < 0) { 74 | throw new Exception("Negative Value"); 75 | } 76 | System.out.println("Object getting removed:" + this.data[removeIndex]); 77 | 78 | for (int i = removeIndex; i < this.data.length - 1; i++) { 79 | data[i] = data[i + 1]; 80 | } 81 | 82 | this.index--; 83 | } 84 | 85 | public static void main(String[] args) throws Exception { 86 | ArrayList mal = new ArrayList(); 87 | mal.add("1"); 88 | mal.add("2"); 89 | mal.add("3"); 90 | mal.add("4"); 91 | mal.add("5"); 92 | mal.add("6"); 93 | mal.add("7"); 94 | mal.add("8"); 95 | mal.add("9"); 96 | mal.add("10"); 97 | 98 | // remove by index 99 | mal.remove(5); 100 | 101 | System.out.println(mal.get(7)); 102 | } 103 | 104 | } -------------------------------------------------------------------------------- /src/main/java/com/zhokhov/interview/data/BinaryTree.java: -------------------------------------------------------------------------------- 1 | /* 2 | * You are free to use this code anywhere, copy, modify and redistribute at your 3 | * own risk. 4 | * Your are solely responsibly for any damage that may occur by using this code. 5 | * 6 | * This code is not tested for all boundary conditions. Use it at your own risk. 7 | * 8 | * Original code: http://www.newthinktank.com/2013/03/binary-tree-in-java/ 9 | */ 10 | package com.zhokhov.interview.data; 11 | 12 | /** 13 | * @author Alexey Zhokhov 14 | */ 15 | public class BinaryTree { 16 | 17 | private class Node { 18 | 19 | int key; 20 | String name; 21 | 22 | Node leftChild; 23 | Node rightChild; 24 | 25 | //Node parent; 26 | 27 | Node(int key, String name) { 28 | 29 | this.key = key; 30 | this.name = name; 31 | 32 | } 33 | 34 | public String toString() { 35 | 36 | return name + " has the key " + key; 37 | 38 | /* 39 | * return name + " has the key " + key + "\nLeft Child: " + leftChild + 40 | * "\nRight Child: " + rightChild + "\n"; 41 | */ 42 | 43 | } 44 | 45 | } 46 | 47 | Node root; 48 | 49 | public void addNode(int key, String name) { 50 | 51 | // Create a new Node and initialize it 52 | 53 | Node newNode = new Node(key, name); 54 | 55 | // If there is no root this becomes root 56 | 57 | if (root == null) { 58 | 59 | root = newNode; 60 | 61 | } else { 62 | 63 | // Set root as the Node we will start 64 | // with as we traverse the tree 65 | 66 | Node focusNode = root; 67 | 68 | // Future parent for our new Node 69 | 70 | Node parent; 71 | 72 | while (true) { 73 | 74 | // root is the top parent so we start 75 | // there 76 | 77 | parent = focusNode; 78 | 79 | // Check if the new node should go on 80 | // the left side of the parent node 81 | 82 | if (key < focusNode.key) { 83 | 84 | // Switch focus to the left child 85 | 86 | focusNode = focusNode.leftChild; 87 | 88 | // If the left child has no children 89 | 90 | if (focusNode == null) { 91 | 92 | // then place the new node on the left of it 93 | 94 | parent.leftChild = newNode; 95 | return; // All Done 96 | 97 | } 98 | 99 | } else { // If we get here put the node on the right 100 | 101 | focusNode = focusNode.rightChild; 102 | 103 | // If the right child has no children 104 | 105 | if (focusNode == null) { 106 | 107 | // then place the new node on the right of it 108 | 109 | parent.rightChild = newNode; 110 | return; // All Done 111 | 112 | } 113 | 114 | } 115 | 116 | } 117 | } 118 | 119 | } 120 | 121 | // All nodes are visited in ascending order 122 | // Recursion is used to go to one node and 123 | // then go to its child nodes and so forth 124 | 125 | public void inOrderTraverseTree(Node focusNode) { 126 | 127 | if (focusNode != null) { 128 | 129 | // Traverse the left node 130 | 131 | inOrderTraverseTree(focusNode.leftChild); 132 | 133 | // Visit the currently focused on node 134 | 135 | System.out.println(focusNode); 136 | 137 | // Traverse the right node 138 | 139 | inOrderTraverseTree(focusNode.rightChild); 140 | 141 | } 142 | 143 | } 144 | 145 | public void preorderTraverseTree(Node focusNode) { 146 | 147 | if (focusNode != null) { 148 | 149 | System.out.println(focusNode); 150 | 151 | preorderTraverseTree(focusNode.leftChild); 152 | preorderTraverseTree(focusNode.rightChild); 153 | 154 | } 155 | 156 | } 157 | 158 | public void postOrderTraverseTree(Node focusNode) { 159 | 160 | if (focusNode != null) { 161 | 162 | postOrderTraverseTree(focusNode.leftChild); 163 | postOrderTraverseTree(focusNode.rightChild); 164 | 165 | System.out.println(focusNode); 166 | 167 | } 168 | 169 | } 170 | 171 | public Node findNode(int key) { 172 | 173 | // Start at the top of the tree 174 | 175 | Node focusNode = root; 176 | 177 | // While we haven't found the Node 178 | // keep looking 179 | 180 | while (focusNode.key != key) { 181 | 182 | // If we should search to the left 183 | 184 | if (key < focusNode.key) { 185 | 186 | // Shift the focus Node to the left child 187 | 188 | focusNode = focusNode.leftChild; 189 | 190 | } else { 191 | 192 | // Shift the focus Node to the right child 193 | 194 | focusNode = focusNode.rightChild; 195 | 196 | } 197 | 198 | // The node wasn't found 199 | 200 | if (focusNode == null) 201 | return null; 202 | 203 | } 204 | 205 | return focusNode; 206 | 207 | } 208 | 209 | // TODO 210 | /* 211 | int depth(Node u) { 212 | int d = 0; 213 | while (u != r) { 214 | u = u.parent; 215 | d++; 216 | } 217 | return d; 218 | } 219 | */ 220 | 221 | int size(Node u) { 222 | if (u == null) return 0; 223 | return 1 + size(u.leftChild) + size(u.rightChild); 224 | } 225 | 226 | public static void main(String[] args) { 227 | 228 | BinaryTree theTree = new BinaryTree(); 229 | 230 | theTree.addNode(50, "Boss"); 231 | 232 | theTree.addNode(25, "Vice President"); 233 | 234 | theTree.addNode(15, "Office Manager"); 235 | 236 | theTree.addNode(30, "Secretary"); 237 | 238 | theTree.addNode(75, "Sales Manager"); 239 | 240 | theTree.addNode(85, "Salesman 1"); 241 | 242 | // Different ways to traverse binary trees 243 | 244 | // theTree.inOrderTraverseTree(theTree.root); 245 | 246 | // theTree.preorderTraverseTree(theTree.root); 247 | 248 | // theTree.postOrderTraverseTree(theTree.root); 249 | 250 | // Find the node with key 75 251 | 252 | System.out.println("\nNode with the key 75"); 253 | 254 | System.out.println(theTree.findNode(75)); 255 | 256 | } 257 | } -------------------------------------------------------------------------------- /src/main/java/com/zhokhov/interview/data/HashMap.java: -------------------------------------------------------------------------------- 1 | /* 2 | * You are free to use this code anywhere, copy, modify and redistribute at your 3 | * own risk. 4 | * Your are solely responsibly for any damage that may occur by using this code. 5 | * 6 | * This code is not tested for all boundary conditions. Use it at your own risk. 7 | * 8 | * Original code: http://www.algolist.net/Data_structures/Hash_table/Simple_example 9 | */ 10 | package com.zhokhov.interview.data; 11 | 12 | /** 13 | * @author Alexey Zhokhov 14 | */ 15 | public class HashMap { 16 | 17 | private final static int TABLE_SIZE = 128; 18 | 19 | private class HashEntry { 20 | 21 | private int key; 22 | private int value; 23 | 24 | HashEntry(int key, int value) { 25 | this.key = key; 26 | this.value = value; 27 | } 28 | 29 | public int getKey() { 30 | return key; 31 | } 32 | 33 | public int getValue() { 34 | return value; 35 | } 36 | 37 | } 38 | 39 | HashEntry[] table; 40 | 41 | HashMap() { 42 | table = new HashEntry[TABLE_SIZE]; 43 | 44 | for (int i = 0; i < TABLE_SIZE; i++) { 45 | table[i] = null; 46 | } 47 | } 48 | 49 | public int get(int key) { 50 | int hash = (key % TABLE_SIZE); 51 | 52 | while (table[hash] != null && table[hash].getKey() != key) { 53 | hash = (hash + 1) % TABLE_SIZE; 54 | } 55 | 56 | if (table[hash] == null) 57 | return -1; 58 | else 59 | return table[hash].getValue(); 60 | } 61 | 62 | public void put(int key, int value) { 63 | int hash = (key % TABLE_SIZE); 64 | 65 | while (table[hash] != null && table[hash].getKey() != key) { 66 | hash = (hash + 1) % TABLE_SIZE; 67 | } 68 | 69 | table[hash] = new HashEntry(key, value); 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /src/main/java/com/zhokhov/interview/data/LinkedList.java: -------------------------------------------------------------------------------- 1 | /* 2 | * You are free to use this code anywhere, copy, modify and redistribute at your 3 | * own risk. 4 | * Your are solely responsibly for any damage that may occur by using this code. 5 | * 6 | * This code is not tested for all boundary conditions. Use it at your own risk. 7 | * 8 | * Original code: http://www.mycstutorials.com/articles/data_structures/linkedlists 9 | */ 10 | package com.zhokhov.interview.data; 11 | 12 | /** 13 | * @author Alexey Zhokhov 14 | */ 15 | public class LinkedList { 16 | 17 | // reference to the head node. 18 | private Node head; 19 | private int listCount; 20 | 21 | // LinkedList constructor 22 | public LinkedList() { 23 | // this is an empty list, so the reference to the head node 24 | // is set to a new node with no data 25 | head = new Node(null); 26 | listCount = 0; 27 | } 28 | 29 | public void add(Object data) 30 | // post: appends the specified element to the end of this list. 31 | { 32 | Node temp = new Node(data); 33 | Node current = head; 34 | // starting at the head node, crawl to the end of the list 35 | while (current.getNext() != null) { 36 | current = current.getNext(); 37 | } 38 | // the last node's "next" reference set to our new node 39 | current.setNext(temp); 40 | listCount++;// increment the number of elements variable 41 | } 42 | 43 | public void add(Object data, int index) 44 | // post: inserts the specified element at the specified position in this list. 45 | { 46 | Node temp = new Node(data); 47 | Node current = head; 48 | // crawl to the requested index or the last element in the list, 49 | // whichever comes first 50 | for (int i = 1; i < index && current.getNext() != null; i++) { 51 | current = current.getNext(); 52 | } 53 | // set the new node's next-node reference to this node's next-node reference 54 | temp.setNext(current.getNext()); 55 | // now set this node's next-node reference to the new node 56 | current.setNext(temp); 57 | listCount++;// increment the number of elements variable 58 | } 59 | 60 | public Object get(int index) 61 | // post: returns the element at the specified position in this list. 62 | { 63 | // index must be 1 or higher 64 | if (index <= 0) 65 | return null; 66 | 67 | Node current = head.getNext(); 68 | for (int i = 1; i < index; i++) { 69 | if (current.getNext() == null) 70 | return null; 71 | 72 | current = current.getNext(); 73 | } 74 | return current.getData(); 75 | } 76 | 77 | public boolean remove(int index) 78 | // post: removes the element at the specified position in this list. 79 | { 80 | // if the index is out of range, exit 81 | if (index < 1 || index > size()) 82 | return false; 83 | 84 | Node current = head; 85 | for (int i = 1; i < index; i++) { 86 | if (current.getNext() == null) 87 | return false; 88 | 89 | current = current.getNext(); 90 | } 91 | current.setNext(current.getNext().getNext()); 92 | listCount--; // decrement the number of elements variable 93 | return true; 94 | } 95 | 96 | public int size() 97 | // post: returns the number of elements in this list. 98 | { 99 | return listCount; 100 | } 101 | 102 | public String toString() { 103 | Node current = head.getNext(); 104 | String output = ""; 105 | while (current != null) { 106 | output += "[" + current.getData().toString() + "]"; 107 | current = current.getNext(); 108 | } 109 | return output; 110 | } 111 | 112 | private class Node { 113 | // reference to the next node in the chain, 114 | // or null if there isn't one. 115 | Node next; 116 | // data carried by this node. 117 | // could be of any type you need. 118 | Object data; 119 | 120 | 121 | // Node constructor 122 | public Node(Object _data) { 123 | next = null; 124 | data = _data; 125 | } 126 | 127 | // another Node constructor if we want to 128 | // specify the node to point to. 129 | public Node(Object _data, Node _next) { 130 | next = _next; 131 | data = _data; 132 | } 133 | 134 | // these methods should be self-explanatory 135 | public Object getData() { 136 | return data; 137 | } 138 | 139 | public void setData(Object _data) { 140 | data = _data; 141 | } 142 | 143 | public Node getNext() { 144 | return next; 145 | } 146 | 147 | public void setNext(Node _next) { 148 | next = _next; 149 | } 150 | } 151 | 152 | } -------------------------------------------------------------------------------- /src/main/java/com/zhokhov/interview/data/Queue.java: -------------------------------------------------------------------------------- 1 | /* 2 | * You are free to use this code anywhere, copy, modify and redistribute at your 3 | * own risk. 4 | * Your are solely responsibly for any damage that may occur by using this code. 5 | * 6 | * This code is not tested for all boundary conditions. Use it at your own risk. 7 | * 8 | * Original code: http://www.mycstutorials.com/articles/data_structures/queues 9 | */ 10 | package com.zhokhov.interview.data; 11 | 12 | /** 13 | * @author Alexey Zhokhov 14 | */ 15 | public class Queue { 16 | 17 | private LinkedList list; 18 | 19 | // Queue constructor 20 | public Queue() { 21 | // Create a new LinkedList. 22 | list = new LinkedList(); 23 | } 24 | 25 | public boolean isEmpty() 26 | // Post: Returns true if the queue is empty. Otherwise, false. 27 | { 28 | return (list.size() == 0); 29 | } 30 | 31 | public void enqueue(Object item) 32 | // Post: An item is added to the back of the queue. 33 | { 34 | // Append the item to the end of our linked list. 35 | list.add(item); 36 | } 37 | 38 | public Object dequeue() 39 | // Pre: this.isEmpty() == false 40 | // Post: The item at the front of the queue is returned and 41 | // deleted from the queue. Returns null if precondition 42 | // not met. 43 | { 44 | // Store a reference to the item at the front of the queue 45 | // so that it does not get garbage collected when we 46 | // remove it from the list. 47 | // Note: list.get(...) returns null if item not found at 48 | // specified index. See postcondition. 49 | Object item = list.get(1); 50 | // Remove the item from the list. 51 | // My implementation of the linked list is based on the 52 | // J2SE API reference. In both, elements start at 1, 53 | // unlike arrays which start at 0. 54 | list.remove(1); 55 | 56 | // Return the item 57 | return item; 58 | } 59 | 60 | public Object peek() 61 | // Pre: this.isEmpty() == false 62 | // Post: The item at the front of the queue is returned and 63 | // deleted from the queue. Returns null if precondition 64 | // not met. 65 | { 66 | // This method is very similar to dequeue(). 67 | // See Queue.dequeue() for comments. 68 | return list.get(1); 69 | } 70 | 71 | } -------------------------------------------------------------------------------- /src/main/java/com/zhokhov/interview/data/Stack.java: -------------------------------------------------------------------------------- 1 | /* 2 | * You are free to use this code anywhere, copy, modify and redistribute at your 3 | * own risk. 4 | * Your are solely responsibly for any damage that may occur by using this code. 5 | * 6 | * This code is not tested for all boundary conditions. Use it at your own risk. 7 | * 8 | * Original code: http://www.mycstutorials.com/articles/data_structures/stacks 9 | */ 10 | package com.zhokhov.interview.data; 11 | 12 | /** 13 | * @author Alexey Zhokhov 14 | */ 15 | public class Stack { 16 | 17 | private LinkedList list; 18 | 19 | // Stack constructor 20 | public Stack() { 21 | // Create a new LinkedList. 22 | list = new LinkedList(); 23 | } 24 | 25 | public boolean isEmpty() 26 | // Post: Returns true if the stack is empty. Otherwise, false. 27 | { 28 | return (list.size() == 0); 29 | } 30 | 31 | public void push(Object item) 32 | // Post: An item is added to the back of the stack. 33 | { 34 | // Append the item to the end of our linked list. 35 | list.add(item); 36 | } 37 | 38 | public Object pop() 39 | // Pre: this.isEmpty() == false 40 | // Post: The item at the front of the stack is returned and 41 | // deleted from the stack. Returns null if precondition 42 | // not met. 43 | { 44 | // Store a reference to the item at the front of the stack 45 | // so that it does not get garbage collected when we 46 | // remove it from the list. 47 | // Note: list.get(...) returns null if item not found at 48 | // specified index. See postcondition. 49 | Object item = list.get(list.size()); 50 | // Remove the item from the list. 51 | // My implementation of the linked list is based on the 52 | // J2SE API reference. In both, elements start at 1, 53 | // unlike arrays which start at 0. 54 | list.remove(list.size()); 55 | // Return the item 56 | return item; 57 | } 58 | 59 | public Object peek() 60 | // Pre: this.isEmpty() == false 61 | // Post: The item at the front of the stack is returned and 62 | // deleted from the stack. Returns null if precondition 63 | // not met. 64 | { 65 | // This method is very similar to pop(). 66 | // See Stack.pop() for comments. 67 | return list.get(list.size()); 68 | } 69 | } -------------------------------------------------------------------------------- /src/main/java/com/zhokhov/interview/sorting/BubbleSort.java: -------------------------------------------------------------------------------- 1 | /* 2 | * You are free to use this code anywhere, copy, modify and redistribute at your 3 | * own risk. 4 | * Your are solely responsibly for any damage that may occur by using this code. 5 | * 6 | * This code is not tested for all boundary conditions. Use it at your own risk. 7 | */ 8 | package com.zhokhov.interview.sorting; 9 | 10 | import static com.zhokhov.interview.util.Console.*; 11 | 12 | /** 13 | * @author Alexey Zhokhov 14 | */ 15 | public class BubbleSort { 16 | 17 | private int COMPARISONS_COUNT; 18 | private int SWAPS_COUNT; 19 | private int LOOP_COUNT; 20 | 21 | public void sort(int[] array) { 22 | COMPARISONS_COUNT = 0; 23 | SWAPS_COUNT = 0; 24 | LOOP_COUNT = 0; 25 | 26 | for (int reverseIndex = array.length - 1; reverseIndex > 1; reverseIndex--) { 27 | LOOP_COUNT++; 28 | ____grey("------\nreverseIndex: " + reverseIndex); 29 | 30 | for (int i = 0; i < reverseIndex; i++) { 31 | LOOP_COUNT++; 32 | ____grey("i: " + i); 33 | 34 | COMPARISONS_COUNT++; 35 | 36 | if (array[i] > array[i + 1]) { 37 | SWAPS_COUNT++; 38 | ____blue("Swapping: " + i + " and " + (i + 1)); 39 | 40 | // Swap code 41 | int temp = array[i]; 42 | 43 | array[i] = array[i + 1]; 44 | array[i + 1] = temp; 45 | 46 | __red("==> "); 47 | __dump(array); 48 | System.out.println(""); 49 | } 50 | } 51 | } 52 | } 53 | 54 | public static void main(String[] args) { 55 | int array[] = {7, 1, 8, 2, 0, 12, 10, 6, 5, 3}; 56 | 57 | __yellow("\nNew array: "); 58 | __dump(array); 59 | 60 | System.out.println("\nSorting\n"); 61 | 62 | BubbleSort bubbleSort = new BubbleSort(); 63 | bubbleSort.sort(array); 64 | 65 | __green("\nResult: "); 66 | __dump(array); 67 | 68 | ____grey("\nStatistics"); 69 | __green(" Comparisons: "); 70 | System.out.print(bubbleSort.COMPARISONS_COUNT); 71 | __green("\n Swaps: "); 72 | System.out.print(bubbleSort.SWAPS_COUNT); 73 | __green("\n Loops: "); 74 | System.out.println(bubbleSort.LOOP_COUNT); 75 | } 76 | 77 | } -------------------------------------------------------------------------------- /src/main/java/com/zhokhov/interview/sorting/InsertionSort.java: -------------------------------------------------------------------------------- 1 | /* 2 | * You are free to use this code anywhere, copy, modify and redistribute at your 3 | * own risk. 4 | * Your are solely responsibly for any damage that may occur by using this code. 5 | * 6 | * This code is not tested for all boundary conditions. Use it at your own risk. 7 | * 8 | * Original code: http://www.codenlearn.com/2011/07/simple-insertion-sort.html 9 | */ 10 | package com.zhokhov.interview.sorting; 11 | 12 | import static com.zhokhov.interview.util.Console.*; 13 | 14 | /** 15 | * @author Alexey Zhokhov 16 | */ 17 | public class InsertionSort { 18 | 19 | private int COMPARISONS_COUNT; 20 | private int LOOP_COUNT; 21 | 22 | public void sort(int array[]) { 23 | COMPARISONS_COUNT = 0; 24 | LOOP_COUNT = 0; 25 | 26 | // Ignore the first element [0] 27 | // start from the element [1] -- Get that element and insert 28 | for (int index = 1; index < array.length; index++) { 29 | LOOP_COUNT++; 30 | ____cyan("\n--------\nindex: " + index); 31 | 32 | insert(array, index); 33 | } 34 | } 35 | 36 | private void insert(int array[], int currentIndex) { 37 | // value of the element to be inserted 38 | int value = array[currentIndex]; 39 | 40 | ____grey("value: " + value); 41 | ____grey("currentIndex: " + currentIndex); 42 | 43 | // iterate in the loop for all elements below the currentIndex 44 | int reverseIndex = currentIndex; 45 | 46 | ____grey("reverseIndex: " + reverseIndex); 47 | 48 | for (int i = currentIndex - 1; i >= 0; i--) { 49 | LOOP_COUNT++; 50 | ____grey("\ni: " + i); 51 | 52 | COMPARISONS_COUNT++; 53 | // If the array element is greater than the value 54 | // move the array element to the next higher index 55 | if (array[i] >= value) { 56 | ____blue("Move element " + array[i] + " to position " + (i + 1)); 57 | ____blue("new reverseIndex: " + i); 58 | 59 | array[i + 1] = array[i]; 60 | reverseIndex = i; 61 | 62 | System.out.print("[" + value + "]"); 63 | __red(" ==> "); 64 | __dump(array); 65 | } else { 66 | ____grey("breaking"); 67 | 68 | break; 69 | } 70 | } 71 | 72 | ____grey("\nreverseIndex (after loop): " + reverseIndex + ", put value here"); 73 | 74 | array[reverseIndex] = value; 75 | 76 | __red("==> "); 77 | __dump(array); 78 | } 79 | 80 | /* 81 | * A sample merge method to help understand the insert routine. 82 | * This below function is not used by the insertion sort. 83 | * 84 | * This is here only for explanation purpose. 85 | */ 86 | private void sampleInsert(int array[], int value) { 87 | ____grey("value: " + value); 88 | 89 | int reverseIndex = array.length - 1; 90 | 91 | ____grey("reverseIndex: " + reverseIndex); 92 | 93 | // start the loop from last element 94 | for (int i = array.length - 2; i >= 0; i--) { 95 | ____grey("\ni: " + i); 96 | 97 | // If the array element is greater than the value 98 | // move the array element to the next index 99 | // i.e one level higher on the index. 100 | if (array[i] >= value) { 101 | ____blue("Move element to: " + (i + 1)); 102 | ____blue("new reverseIndex: " + i); 103 | 104 | array[i + 1] = array[i]; 105 | reverseIndex = i; 106 | } else { 107 | ____grey("breaking"); 108 | 109 | break; 110 | } 111 | } 112 | 113 | ____grey("\nreverseIndex (after loop): " + reverseIndex + ", put value here"); 114 | 115 | array[reverseIndex] = value; 116 | } 117 | 118 | public static void main(String[] args) { 119 | int array[] = {7, 1, 8, 2, 0, 12, 10, 7, 5, 3}; 120 | 121 | __yellow("\nNew array: "); 122 | __dump(array); 123 | 124 | System.out.println("\nSorting"); 125 | 126 | InsertionSort insertionSort = new InsertionSort(); 127 | insertionSort.sort(array); 128 | 129 | __green("\nResult: "); 130 | __dump(array); 131 | 132 | ____grey("\nStatistics"); 133 | __green(" Comparisons: "); 134 | System.out.print(insertionSort.COMPARISONS_COUNT); 135 | __green("\n Loops: "); 136 | System.out.println(insertionSort.LOOP_COUNT); 137 | 138 | System.out.print("\n"); 139 | System.out.println("***********************\n"); 140 | System.out.println("Insert item to sorted array."); 141 | 142 | int sortedArray[] = {1, 2, 3, 4, 5, 6, Integer.MAX_VALUE}; 143 | 144 | __yellow("\nNew array: "); 145 | __dump(array); 146 | 147 | System.out.println("\nInserting"); 148 | 149 | insertionSort.sampleInsert(sortedArray, 4); 150 | 151 | __green("\nResult: "); 152 | __dump(sortedArray); 153 | } 154 | 155 | } 156 | -------------------------------------------------------------------------------- /src/main/java/com/zhokhov/interview/sorting/MergeSort.java: -------------------------------------------------------------------------------- 1 | /* 2 | * You are free to use this code anywhere, copy, modify and redistribute at your 3 | * own risk. 4 | * Your are solely responsibly for any damage that may occur by using this code. 5 | * 6 | * This code is not tested for all boundary conditions. Use it at your own risk. 7 | * 8 | * Original code: http://www.codenlearn.com/2011/10/simple-merge-sort.html 9 | */ 10 | package com.zhokhov.interview.sorting; 11 | 12 | import static com.zhokhov.interview.util.Console.*; 13 | 14 | /** 15 | * @author Alexey Zhokhov 16 | */ 17 | public class MergeSort { 18 | 19 | private int COMPARISONS_COUNT; 20 | private int LOOP_COUNT; 21 | 22 | public void sort(int[] array) { 23 | COMPARISONS_COUNT = 0; 24 | LOOP_COUNT = 0; 25 | 26 | mergeSort(array, 0, array.length - 1); 27 | } 28 | 29 | /* 30 | * The mergeSort algorithm implementation 31 | */ 32 | private void mergeSort(int[] array, int left, int right) { 33 | __grey("\nmergeSort, left: " + left + ", right: " + right + " ==> "); 34 | ____purple("" + (left < right)); 35 | 36 | COMPARISONS_COUNT++; 37 | if (left < right) { 38 | // split the array into 2 39 | int center = (left + right) / 2; 40 | 41 | ____grey("center: " + center); 42 | 43 | // sort the left and right array 44 | mergeSort(array, left, center); 45 | mergeSort(array, center + 1, right); 46 | 47 | ____grey("Merging, center: " + center); 48 | 49 | // merge the result 50 | merge(array, left, center + 1, right); 51 | } 52 | } 53 | 54 | /* 55 | * The merge method used by the mergeSort algorithm implementation. 56 | */ 57 | private void merge(int[] array, int leftArrayBegin, 58 | int rightArrayBegin, int rightArrayEnd) { 59 | int leftArrayEnd = rightArrayBegin - 1; 60 | 61 | int numElements = rightArrayEnd - leftArrayBegin + 1; 62 | int[] resultArray = new int[numElements]; 63 | int resultArrayBegin = 0; 64 | 65 | ____grey(" leftArrayBegin: " + leftArrayBegin); 66 | ____grey(" leftArrayEnd: " + leftArrayEnd); 67 | ____grey(" rightArrayBegin: " + rightArrayBegin); 68 | ____grey(" rightArrayEnd: " + rightArrayEnd); 69 | 70 | // Find the smallest element in both these array and add it to the result 71 | // array i.e you may have a array of the form [1,5] [2,4] 72 | // We need to sort the above as [1,2,4,5] 73 | while (leftArrayBegin <= leftArrayEnd && rightArrayBegin <= rightArrayEnd) { 74 | COMPARISONS_COUNT++; 75 | 76 | if (array[leftArrayBegin] <= array[rightArrayBegin]) { 77 | resultArray[resultArrayBegin++] = array[leftArrayBegin++]; 78 | 79 | ____blue(" new leftArrayBegin: " + leftArrayBegin); 80 | } else { 81 | resultArray[resultArrayBegin++] = array[rightArrayBegin++]; 82 | 83 | ____blue(" new rightArrayBegin: " + rightArrayBegin); 84 | } 85 | } 86 | 87 | // After the main loop completed we may have few more elements in 88 | // left array copy them first 89 | while (leftArrayBegin <= leftArrayEnd) { 90 | COMPARISONS_COUNT++; 91 | 92 | resultArray[resultArrayBegin++] = array[leftArrayBegin++]; 93 | 94 | ____blue(" [post] new leftArrayBegin: " + leftArrayBegin); 95 | } 96 | 97 | // After the main loop completed we may have few more elements in 98 | // right array copy them 99 | while (rightArrayBegin <= rightArrayEnd) { 100 | COMPARISONS_COUNT++; 101 | 102 | resultArray[resultArrayBegin++] = array[rightArrayBegin++]; 103 | 104 | ____blue(" [post] new rightArrayBegin: " + rightArrayBegin); 105 | } 106 | 107 | // Copy resultArray back to the main array 108 | for (int i = numElements - 1; i >= 0; i--, rightArrayEnd--) { 109 | LOOP_COUNT++; 110 | 111 | array[rightArrayEnd] = resultArray[i]; 112 | } 113 | 114 | __red("==> "); 115 | __dump(array); 116 | } 117 | 118 | /* 119 | * A sample merge method to help understand the merge routine. 120 | * This below function is not used by the merge sort. 121 | * 122 | * This is here only for explanation purpose. 123 | */ 124 | public int[] sampleMerge(int[] leftArray, int[] rightArray) { 125 | int leftArrayEnd = leftArray.length - 1; 126 | int rightArrayEnd = rightArray.length - 1; 127 | int leftArrayBegin = 0; 128 | int rightArrayBegin = 0; 129 | 130 | int numElements = leftArray.length + rightArray.length; 131 | int[] resultArray = new int[numElements]; 132 | int resultArrayBegin = 0; 133 | 134 | ____grey(" leftArrayBegin: " + leftArrayBegin); 135 | ____grey(" leftArrayEnd: " + leftArrayEnd); 136 | ____grey(" rightArrayBegin: " + rightArrayBegin); 137 | ____grey(" rightArrayEnd: " + rightArrayEnd); 138 | 139 | // Find the smallest element in both these array and add it to the temp 140 | // array i.e you may have a array of the form [1,5] [2,4] 141 | // We need to sort the above as [1,2,4,5] 142 | while (leftArrayBegin <= leftArrayEnd && rightArrayBegin <= rightArrayEnd) { 143 | if (leftArray[leftArrayBegin] <= rightArray[rightArrayBegin]) { 144 | resultArray[resultArrayBegin++] = leftArray[leftArrayBegin++]; 145 | 146 | ____blue(" new leftArrayBegin: " + leftArrayBegin); 147 | } else { 148 | resultArray[resultArrayBegin++] = rightArray[rightArrayBegin++]; 149 | 150 | ____blue(" new rightArrayBegin: " + rightArrayBegin); 151 | } 152 | } 153 | 154 | // After the main loop completed we may have few more elements in 155 | // left array copy them first 156 | while (leftArrayBegin <= leftArrayEnd) { 157 | resultArray[resultArrayBegin++] = leftArray[leftArrayBegin++]; 158 | 159 | ____blue(" [post] new leftArrayBegin: " + leftArrayBegin); 160 | } 161 | 162 | // After the main loop completed we may have few more elements in 163 | // right array copy them 164 | while (rightArrayBegin <= rightArrayEnd) { 165 | resultArray[resultArrayBegin++] = rightArray[rightArrayBegin++]; 166 | 167 | ____blue(" [post] new rightArrayBegin: " + rightArrayBegin); 168 | } 169 | 170 | return resultArray; 171 | } 172 | 173 | public static void main(String args[]) { 174 | int array[] = {7, 1, 8, 2, 0, 12, 10, 7, 5, 3}; 175 | 176 | __yellow("\nNew array: "); 177 | __dump(array); 178 | 179 | System.out.println("\nSorting"); 180 | 181 | MergeSort mergeSort = new MergeSort(); 182 | mergeSort.sort(array); 183 | 184 | __green("\nResult: "); 185 | __dump(array); 186 | 187 | ____grey("\nStatistics"); 188 | __green(" Comparisons: "); 189 | System.out.print(mergeSort.COMPARISONS_COUNT); 190 | __green("\n Loops: "); 191 | System.out.println(mergeSort.LOOP_COUNT); 192 | 193 | System.out.print("\n"); 194 | System.out.println("***********************\n"); 195 | System.out.println("Now demo a simple merge routine."); 196 | 197 | int leftArray[] = {1, 3, 5, 7}; 198 | int rightArray[] = {2, 4, 6, 8, 10}; 199 | 200 | __yellow("\nLeft array: "); 201 | __dump(leftArray); 202 | __yellow("Right array: "); 203 | __dump(rightArray); 204 | 205 | System.out.println("\nMerging"); 206 | 207 | int[] mergedArray = mergeSort.sampleMerge(leftArray, rightArray); 208 | 209 | __green("\nResult: "); 210 | __dump(mergedArray); 211 | } 212 | 213 | } -------------------------------------------------------------------------------- /src/main/java/com/zhokhov/interview/sorting/QuickSort.java: -------------------------------------------------------------------------------- 1 | /* 2 | * You are free to use this code anywhere, copy, modify and redistribute at your 3 | * own risk. 4 | * Your are solely responsibly for any damage that may occur by using this code. 5 | * 6 | * This code is not tested for all boundary conditions. Use it at your own risk. 7 | * 8 | * Original code: http://www.mycstutorials.com/articles/sorting/quicksort 9 | */ 10 | package com.zhokhov.interview.sorting; 11 | 12 | import static com.zhokhov.interview.util.Console.*; 13 | 14 | /** 15 | * @author Alexey Zhokhov 16 | */ 17 | public class QuickSort { 18 | 19 | private int COMPARISONS_COUNT; 20 | private int SWAPS_COUNT; 21 | 22 | public void sort(int array[]) { 23 | COMPARISONS_COUNT = 0; 24 | SWAPS_COUNT = 0; 25 | 26 | quickSort(array, 0, array.length - 1); 27 | } 28 | 29 | /* 30 | * The quickSort algorithm implementation 31 | */ 32 | private void quickSort(int array[], int startIndex, int endIndex) { 33 | __grey("\nquickSort, startIndex: " + startIndex + ", endIndex: " + endIndex + " ==> "); 34 | ____purple("" + (endIndex - startIndex >= 1)); 35 | 36 | COMPARISONS_COUNT++; 37 | // check that there are at least two elements to sort 38 | // if there is only one element in the partition, do not do any sorting 39 | if (endIndex - startIndex >= 1) { 40 | int rightIndex = partition(array, startIndex, endIndex); 41 | 42 | // quicksort the left partition 43 | quickSort(array, startIndex, rightIndex - 1); 44 | 45 | // quicksort the right partition 46 | quickSort(array, rightIndex + 1, endIndex); 47 | } 48 | } 49 | 50 | private int partition(int array[], int startIndex, int endIndex) { 51 | // index of left-to-right scan 52 | int leftIndex = startIndex; 53 | 54 | // index of right-to-left scan 55 | int rightIndex = endIndex; 56 | 57 | // set the pivot as the first element in the partition 58 | int pivot = array[startIndex]; 59 | 60 | ____grey("pivot: " + pivot); 61 | 62 | // while the scan indices from left and right have not met 63 | while (rightIndex > leftIndex) { 64 | COMPARISONS_COUNT++; 65 | 66 | // from the left, look for the first 67 | // element greater than the pivot 68 | while (array[leftIndex] <= pivot && leftIndex <= endIndex && rightIndex > leftIndex) { 69 | COMPARISONS_COUNT++; 70 | 71 | leftIndex++; 72 | 73 | ____blue(" new leftIndex: " + leftIndex); 74 | } 75 | 76 | // from the right, look for the first 77 | // element not greater than the pivot 78 | while (array[rightIndex] > pivot && rightIndex >= startIndex && rightIndex >= leftIndex) { 79 | COMPARISONS_COUNT++; 80 | 81 | rightIndex--; 82 | 83 | ____blue(" new rightIndex: " + rightIndex); 84 | } 85 | 86 | COMPARISONS_COUNT++; 87 | // if the left seekindex is still smaller than 88 | // the right index, swap the corresponding elements 89 | if (rightIndex > leftIndex) { 90 | swap(array, leftIndex, rightIndex); 91 | } 92 | } 93 | 94 | // after the indices have crossed, swap the last element in 95 | // the left partition with the pivot 96 | swap(array, startIndex, rightIndex); 97 | 98 | return rightIndex; 99 | } 100 | 101 | private void swap(int array[], int index1, int index2) { 102 | SWAPS_COUNT++; 103 | ____blue("Swapping: " + index1 + " and " + index2); 104 | 105 | int temp = array[index1]; 106 | 107 | array[index1] = array[index2]; 108 | array[index2] = temp; 109 | 110 | __red("==> "); 111 | __dump(array); 112 | System.out.println(""); 113 | } 114 | 115 | public static void main(String[] args) { 116 | int array[] = {7, 1, 8, 2, 0, 12, 10, 6, 5, 3}; 117 | 118 | __yellow("\nNew array: "); 119 | __dump(array); 120 | 121 | System.out.println("\nSorting"); 122 | 123 | QuickSort quickSort = new QuickSort(); 124 | quickSort.sort(array); 125 | 126 | __green("\nResult: "); 127 | __dump(array); 128 | 129 | ____grey("\nStatistics"); 130 | __green(" Comparisons: "); 131 | System.out.print(quickSort.COMPARISONS_COUNT); 132 | __green("\n Swaps: "); 133 | System.out.println(quickSort.SWAPS_COUNT); 134 | } 135 | 136 | } 137 | -------------------------------------------------------------------------------- /src/main/java/com/zhokhov/interview/sorting/SelectionSort.java: -------------------------------------------------------------------------------- 1 | /* 2 | * You are free to use this code anywhere, copy, modify and redistribute at your 3 | * own risk. 4 | * Your are solely responsibly for any damage that may occur by using this code. 5 | * 6 | * This code is not tested for all boundary conditions. Use it at your own risk. 7 | * 8 | * Original code: http://www.codenlearn.com/2011/07/simple-selection-sort.html 9 | */ 10 | package com.zhokhov.interview.sorting; 11 | 12 | import static com.zhokhov.interview.util.Console.*; 13 | 14 | /** 15 | * @author Alexey Zhokhov 16 | */ 17 | public class SelectionSort { 18 | 19 | private int COMPARISONS_COUNT; 20 | private int SWAPS_COUNT; 21 | private int LOOP_COUNT; 22 | 23 | public void sort(int array[]) { 24 | COMPARISONS_COUNT = 0; 25 | SWAPS_COUNT = 0; 26 | LOOP_COUNT = 0; 27 | 28 | // Start from first 29 | for (int index = 0; index < array.length; index++) { 30 | LOOP_COUNT++; 31 | ____cyan("\n--------\nindex: " + index); 32 | 33 | 34 | // find the next smallest element 35 | int minIndex = findNextSmallestElement(index, array); 36 | 37 | ____grey("found smallest element index: " + minIndex); 38 | 39 | SWAPS_COUNT++; 40 | ____blue("Swapping: " + index + " and " + minIndex); 41 | 42 | // Swap code 43 | int temp = array[minIndex]; 44 | 45 | array[minIndex] = array[index]; 46 | array[index] = temp; 47 | 48 | __red("==> "); 49 | __dump(array); 50 | } 51 | } 52 | 53 | /* 54 | * Finds the smallest element starting startIndex 55 | * 56 | * @ returns the index of the smallest element. 57 | */ 58 | private int findNextSmallestElement(int startIndex, int array[]) { 59 | int minIndex = startIndex; 60 | 61 | int value = array[startIndex]; 62 | 63 | for (int i = startIndex; i < array.length; i++) { 64 | LOOP_COUNT++; 65 | COMPARISONS_COUNT++; 66 | if (value > array[i]) { 67 | minIndex = i; 68 | value = array[minIndex]; 69 | } 70 | } 71 | 72 | return minIndex; 73 | } 74 | 75 | public static void main(String[] args) { 76 | int array[] = {7, 1, 8, 2, 0, 12, 10, 6, 5, 3}; 77 | 78 | __yellow("\nNew array: "); 79 | __dump(array); 80 | 81 | System.out.println("\nSorting"); 82 | 83 | SelectionSort selectionSort = new SelectionSort(); 84 | selectionSort.sort(array); 85 | 86 | __green("\nResult: "); 87 | __dump(array); 88 | 89 | ____grey("\nStatistics"); 90 | __green(" Comparisons: "); 91 | System.out.print(selectionSort.COMPARISONS_COUNT); 92 | __green("\n Swaps: "); 93 | System.out.print(selectionSort.SWAPS_COUNT); 94 | __green("\n Loops: "); 95 | System.out.println(selectionSort.LOOP_COUNT); 96 | } 97 | 98 | } 99 | -------------------------------------------------------------------------------- /src/main/java/com/zhokhov/interview/util/Console.java: -------------------------------------------------------------------------------- 1 | package com.zhokhov.interview.util; 2 | 3 | /** 4 | * @author Alexey Zhokhov 5 | */ 6 | public class Console { 7 | 8 | public static final String ANSI_RESET = "\u001B[0m"; 9 | public static final String ANSI_RED = "\u001B[31m"; 10 | public static final String ANSI_GREEN = "\u001B[32m"; 11 | public static final String ANSI_YELLOW = "\u001B[33m"; 12 | public static final String ANSI_BLUE = "\u001B[34m"; 13 | public static final String ANSI_PURPLE = "\u001B[35m"; 14 | public static final String ANSI_CYAN = "\u001B[36m"; 15 | public static final String ANSI_GREY = "\u001B[37m"; 16 | 17 | public static String red(String s) { 18 | return ANSI_RED + s + ANSI_RESET; 19 | } 20 | 21 | public static String green(String s) { 22 | return ANSI_GREEN + s + ANSI_RESET; 23 | } 24 | 25 | public static String yellow(String s) { 26 | return ANSI_YELLOW + s + ANSI_RESET; 27 | } 28 | 29 | public static String blue(String s) { 30 | return ANSI_BLUE + s + ANSI_RESET; 31 | } 32 | 33 | public static String purple(String s) { 34 | return ANSI_PURPLE + s + ANSI_RESET; 35 | } 36 | 37 | public static String cyan(String s) { 38 | return ANSI_CYAN + s + ANSI_RESET; 39 | } 40 | 41 | public static String grey(String s) { 42 | return ANSI_GREY + s + ANSI_RESET; 43 | } 44 | 45 | public static void __red(String s) { 46 | System.out.print(red(s)); 47 | } 48 | 49 | public static void __green(String s) { 50 | System.out.print(green(s)); 51 | } 52 | 53 | public static void __yellow(String s) { 54 | System.out.print(yellow(s)); 55 | } 56 | 57 | public static void __blue(String s) { 58 | System.out.print(blue(s)); 59 | } 60 | 61 | public static void __purple(String s) { 62 | System.out.print(purple(s)); 63 | } 64 | 65 | public static void __cyan(String s) { 66 | System.out.print(cyan(s)); 67 | } 68 | 69 | public static void __grey(String s) { 70 | System.out.print(grey(s)); 71 | } 72 | 73 | public static void ____red(String s) { 74 | System.out.println(red(s)); 75 | } 76 | 77 | public static void ____green(String s) { 78 | System.out.println(green(s)); 79 | } 80 | 81 | public static void ____yellow(String s) { 82 | System.out.println(yellow(s)); 83 | } 84 | 85 | public static void ____blue(String s) { 86 | System.out.println(blue(s)); 87 | } 88 | 89 | public static void ____purple(String s) { 90 | System.out.println(purple(s)); 91 | } 92 | 93 | public static void ____cyan(String s) { 94 | System.out.println(cyan(s)); 95 | } 96 | 97 | public static void ____grey(String s) { 98 | System.out.println(grey(s)); 99 | } 100 | 101 | /* 102 | * Utility for dumping the array 103 | */ 104 | public static void __dump(int[] array) { 105 | for (int i : array) System.out.print(i + " "); 106 | 107 | System.out.print("\n"); 108 | } 109 | 110 | } 111 | --------------------------------------------------------------------------------