├── .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 | [](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 | 
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 | 
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 | 
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 | 
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 | 
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 | 
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 | [](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 |
96 |
100 |
104 |
108 |
112 |
116 |
120 |
124 |
128 |
132 |
133 |
134 |
135 |
Step 1. Pivot value: 7 Swapping indexes: 2 and 9
136 |
140 |
144 |
148 |
152 |
156 |
160 |
164 |
168 |
172 |
176 |
177 |
178 |
179 |
Step 2. Pivot value: 7 Swapping indexes: 5 and 8
180 |
184 |
188 |
192 |
196 |
200 |
204 |
208 |
212 |
216 |
220 |
221 |
222 |
223 |
Step 3. Pivot value: 7 Swapping indexes: 6 and 7
224 |
228 |
232 |
236 |
240 |
244 |
248 |
252 |
256 |
260 |
264 |
265 |
266 |
267 |
Step 4. Pivot value: 7 Swapping indexes: 0 and 6
268 |
272 |
276 |
280 |
284 |
288 |
292 |
296 |
300 |
304 |
308 |
309 |
310 |
311 |
Step 5. Pivot value: 6 Swapping indexes: 0 and 5
312 |
316 |
320 |
324 |
328 |
332 |
336 |
340 |
344 |
348 |
352 |
353 |
354 |
355 |
Step 6. Pivot value: 5 Swapping indexes: 0 and 4
356 |
360 |
364 |
368 |
372 |
376 |
380 |
384 |
388 |
392 |
396 |
397 |
398 |
399 |
Step 7. Pivot value: 0 Swapping indexes: 0 and 0
400 |
404 |
408 |
412 |
416 |
420 |
424 |
428 |
432 |
436 |
440 |
441 |
442 |
443 |
Step 8. Pivot value: 1 Swapping indexes: 1 and 1
444 |
448 |
452 |
456 |
460 |
464 |
468 |
472 |
476 |
480 |
484 |
485 |
486 |
487 |
Step 9. Pivot value: 3 Swapping indexes: 2 and 3
488 |
492 |
496 |
500 |
504 |
508 |
512 |
516 |
520 |
524 |
528 |
529 |
530 |
531 |
Step 10. Pivot value: 10 Swapping indexes: 8 and 9
532 |
536 |
540 |
544 |
548 |
552 |
556 |
560 |
564 |
568 |
572 |
573 |
574 |
575 |
Step 11. Pivot value: 10 Swapping indexes: 7 and 8
576 |
580 |
584 |
588 |
592 |
596 |
600 |
604 |
608 |
612 |
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 |
--------------------------------------------------------------------------------