├── .gitignore ├── .idea ├── compiler.xml ├── copyright │ └── profiles_settings.xml ├── gradle.xml ├── misc.xml ├── modules.xml └── runConfigurations.xml ├── LICENCE ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── duy │ │ └── algorithm │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── duy │ │ │ └── algorithm │ │ │ ├── AbstractAppCompatActivity.java │ │ │ ├── AbstractSortAlgorithmFragment.java │ │ │ ├── AppAboutActivity.java │ │ │ ├── MainActivity.java │ │ │ ├── SettingsActivity.java │ │ │ ├── SortAlgorithmFragment.java │ │ │ ├── SortCompletionListener.java │ │ │ ├── SortSpeedTestFragmentSort.java │ │ │ ├── algorithms │ │ │ ├── AlgorithmThread.java │ │ │ ├── IDataHandler.java │ │ │ ├── SortAlgorithmThread.java │ │ │ └── algo │ │ │ │ ├── BogoSortThread.java │ │ │ │ ├── BubbleSortThread.java │ │ │ │ ├── CocktailShakerSortThread.java │ │ │ │ ├── CountingSortThread.java │ │ │ │ ├── InsertionSortThread.java │ │ │ │ ├── MergeSortThread.java │ │ │ │ ├── QuickSortThread.java │ │ │ │ ├── SelectionSortThread.java │ │ │ │ └── ShellSortThread.java │ │ │ ├── customview │ │ │ ├── EditTextInputArray.java │ │ │ ├── LogView.java │ │ │ └── SortView.java │ │ │ ├── notify │ │ │ └── RateManager.java │ │ │ ├── userinterface │ │ │ └── ThemeEngine.java │ │ │ └── utils │ │ │ └── ArrayUtils.java │ └── res │ │ ├── drawable-hdpi │ │ ├── ic_check_white_24dp.png │ │ ├── ic_color_lens_white_24dp.png │ │ ├── ic_compare_white_24dp.png │ │ ├── ic_info_white_24dp.png │ │ ├── ic_language_white_24dp.png │ │ ├── ic_list_white_24dp.png │ │ ├── ic_pause_white_24dp.png │ │ ├── ic_play_arrow_white_24dp.png │ │ ├── ic_settings_backup_restore_white_24dp.png │ │ └── ic_settings_white_24dp.png │ │ ├── drawable-mdpi │ │ ├── ic_check_white_24dp.png │ │ ├── ic_color_lens_white_24dp.png │ │ ├── ic_compare_white_24dp.png │ │ ├── ic_info_white_24dp.png │ │ ├── ic_language_white_24dp.png │ │ ├── ic_list_white_24dp.png │ │ ├── ic_pause_white_24dp.png │ │ ├── ic_play_arrow_white_24dp.png │ │ ├── ic_settings_backup_restore_white_24dp.png │ │ └── ic_settings_white_24dp.png │ │ ├── drawable-xhdpi │ │ ├── ic_check_white_24dp.png │ │ ├── ic_color_lens_white_24dp.png │ │ ├── ic_compare_white_24dp.png │ │ ├── ic_info_white_24dp.png │ │ ├── ic_language_white_24dp.png │ │ ├── ic_list_white_24dp.png │ │ ├── ic_pause_white_24dp.png │ │ ├── ic_play_arrow_white_24dp.png │ │ ├── ic_settings_backup_restore_white_24dp.png │ │ └── ic_settings_white_24dp.png │ │ ├── drawable-xxhdpi │ │ ├── ic_check_white_24dp.png │ │ ├── ic_color_lens_white_24dp.png │ │ ├── ic_compare_white_24dp.png │ │ ├── ic_info_white_24dp.png │ │ ├── ic_language_white_24dp.png │ │ ├── ic_list_white_24dp.png │ │ ├── ic_pause_white_24dp.png │ │ ├── ic_play_arrow_white_24dp.png │ │ ├── ic_settings_backup_restore_white_24dp.png │ │ └── ic_settings_white_24dp.png │ │ ├── drawable-xxxhdpi │ │ ├── ic_check_white_24dp.png │ │ ├── ic_color_lens_white_24dp.png │ │ ├── ic_compare_white_24dp.png │ │ ├── ic_info_white_24dp.png │ │ ├── ic_language_white_24dp.png │ │ ├── ic_list_white_24dp.png │ │ ├── ic_pause_white_24dp.png │ │ ├── ic_play_arrow_white_24dp.png │ │ ├── ic_settings_backup_restore_white_24dp.png │ │ └── ic_settings_white_24dp.png │ │ ├── layout │ │ ├── activity_app_about.xml │ │ ├── activity_main.xml │ │ ├── content_app_about.xml │ │ ├── content_main.xml │ │ ├── control_panel.xml │ │ ├── fragment_control.xml │ │ ├── fragment_log.xml │ │ ├── fragment_multi_sort.xml │ │ ├── fragment_sort.xml │ │ ├── log_item.xml │ │ └── nav_header.xml │ │ ├── menu │ │ └── menu_drawer.xml │ │ ├── mipmap-hdpi │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── splash.png │ │ ├── mipmap-xhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxxhdpi │ │ └── ic_launcher.png │ │ ├── values-vi │ │ └── strings.xml │ │ ├── values-w820dp │ │ └── dimens.xml │ │ ├── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── do_not_translate.xml │ │ ├── key_pref.xml │ │ ├── strings.xml │ │ └── styles.xml │ │ └── xml │ │ └── setting.xml │ └── test │ └── java │ └── com │ └── duy │ └── algorithm │ └── ExampleUnitTest.java ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── screenshot ├── Screenshot_20170205-132701_framed.png ├── Screenshot_20170205-132705_framed.png ├── Screenshot_20170205-132709_framed.png ├── Screenshot_20170205-132717_framed.png ├── Screenshot_20170205-132727_framed.png ├── Screenshot_20170205-132741_framed.png └── Screenshot_20170205-132753_framed.png └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | ### Android ### 2 | # Built application files 3 | *.apk 4 | *.ap_ 5 | 6 | # Files for the ART/Dalvik VM 7 | *.dex 8 | 9 | # Java class files 10 | *.class 11 | 12 | # Generated files 13 | bin/ 14 | gen/ 15 | out/ 16 | 17 | # Gradle files 18 | .gradle/ 19 | build/ 20 | 21 | # Local configuration file (sdk path, etc) 22 | local.properties 23 | 24 | # Proguard folder generated by Eclipse 25 | proguard/ 26 | 27 | # Log Files 28 | *.log 29 | 30 | # Android Studio Navigation editor temp files 31 | .navigation/ 32 | 33 | # Android Studio captures folder 34 | captures/ 35 | 36 | # Intellij 37 | *.iml 38 | .idea/workspace.xml 39 | .idea/tasks.xml 40 | .idea/gradle.xml 41 | .idea/dictionaries 42 | .idea/libraries 43 | 44 | # External native build folder generated in Android Studio 2.2 and later 45 | .externalNativeBuild 46 | 47 | # Freeline 48 | freeline.py 49 | freeline/ 50 | freeline_project_description.json 51 | 52 | ### Android Patch ### 53 | gen-external-apklibs 54 | 55 | ### Java ### 56 | # Compiled class file 57 | 58 | # Log file 59 | 60 | # BlueJ files 61 | *.ctxt 62 | 63 | # Mobile Tools for Java (J2ME) 64 | .mtj.tmp/ 65 | 66 | # Package Files # 67 | *.jar 68 | *.war 69 | *.ear 70 | *.zip 71 | *.tar.gz 72 | *.rar 73 | 74 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 75 | hs_err_pid* 76 | 77 | ### JetBrains ### 78 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm 79 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 80 | 81 | # User-specific stuff: 82 | .idea/**/workspace.xml 83 | .idea/**/tasks.xml 84 | 85 | # Sensitive or high-churn files: 86 | .idea/**/dataSources/ 87 | .idea/**/dataSources.ids 88 | .idea/**/dataSources.xml 89 | .idea/**/dataSources.local.xml 90 | .idea/**/sqlDataSources.xml 91 | .idea/**/dynamic.xml 92 | .idea/**/uiDesigner.xml 93 | 94 | # Gradle: 95 | .idea/**/gradle.xml 96 | .idea/**/libraries 97 | 98 | # CMake 99 | cmake-build-debug/ 100 | 101 | # Mongo Explorer plugin: 102 | .idea/**/mongoSettings.xml 103 | 104 | ## File-based project format: 105 | *.iws 106 | 107 | ## Plugin-specific files: 108 | 109 | # IntelliJ 110 | /out/ 111 | 112 | # mpeltonen/sbt-idea plugin 113 | .idea_modules/ 114 | 115 | # JIRA plugin 116 | atlassian-ide-plugin.xml 117 | 118 | # Cursive Clojure plugin 119 | .idea/replstate.xml 120 | 121 | # Crashlytics plugin (for Android Studio and IntelliJ) 122 | com_crashlytics_export_strings.xml 123 | crashlytics.properties 124 | crashlytics-build.properties 125 | fabric.properties 126 | 127 | ### JetBrains Patch ### 128 | # Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 129 | 130 | # *.iml 131 | # modules.xml 132 | # .idea/misc.xml 133 | # *.ipr 134 | 135 | # Sonarlint plugin 136 | .idea/sonarlint 137 | 138 | ### Windows ### 139 | # Windows thumbnail cache files 140 | Thumbs.db 141 | ehthumbs.db 142 | ehthumbs_vista.db 143 | 144 | # Folder config file 145 | Desktop.ini # Nope 146 | desktop.ini 147 | 148 | # Recycle Bin used on file shares 149 | $RECYCLE.BIN/ 150 | 151 | # Windows Installer files 152 | *.cab 153 | *.msi 154 | *.msm 155 | *.msp 156 | 157 | # Windows shortcuts 158 | *.lnk 159 | 160 | ### Gradle ### 161 | .gradle 162 | /build/ 163 | 164 | # Ignore Gradle GUI config 165 | gradle-app.setting 166 | 167 | # Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) 168 | !gradle-wrapper.jar 169 | 170 | # Cache of project 171 | .gradletasknamecache 172 | 173 | # # Work around https://youtrack.jetbrains.com/issue/IDEA-116898 174 | # gradle/wrapper/gradle-wrapper.properties 175 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 18 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 19 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 46 | 47 | 48 | 49 | 50 | 1.8 51 | 52 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /LICENCE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | 204 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Sort Algorithm 2 | Visualization and comparison of sorting algorithms 3 | 4 | [![Get it on Google Play](https://developer.android.com/images/brand/en_generic_rgb_wo_60.png)](https://play.google.com/store/apps/details?id=com.duy.sortalgorithm.free) 5 | 6 | You feel it difficult to understand the sort algorithm? 7 | Sort Simulation app will help you to more easily visualize, simulate the application step by step operation of sorting algorithms. 8 | The sorting algorithm is modeled: 9 | 10 | - Bubble sort 11 | - Insertion sort 12 | - Selection sort 13 | - Quick sort 14 | - Shell sort 15 | - Megre sort 16 | - Cocktail sort 17 | * It also compares the slow pace of the sorting algorithm 18 | * Animate sort 19 | 20 | There are 2 types of data entry (click the gear icon to open the control panel): 21 | - Manual: enter the array to be sorted 22 | - Auto: automatically generate random data 23 | 24 | Some screenshot's 25 | 26 | ![](screenshot/Screenshot_20170205-132705_framed.png) 27 | ![](screenshot/Screenshot_20170205-132709_framed.png) 28 | ![](screenshot/Screenshot_20170205-132717_framed.png) 29 | ![](screenshot/Screenshot_20170205-132727_framed.png) 30 | ![](screenshot/Screenshot_20170205-132741_framed.png) 31 | ![](screenshot/Screenshot_20170205-132753_framed.png) 32 | 33 | ## License 34 | 35 | Copyright 2016 Tran Le Duy 36 | 37 | Licensed under the Apache License, Version 2.0 (the "License"); 38 | you may not use this file except in compliance with the License. 39 | You may obtain a copy of the License at 40 | 41 | http://www.apache.org/licenses/LICENSE-2.0 42 | 43 | Unless required by applicable law or agreed to in writing, software 44 | distributed under the License is distributed on an "AS IS" BASIS, 45 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 46 | See the License for the specific language governing permissions and 47 | limitations under the License. 48 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 25 5 | buildToolsVersion "25.0.2" 6 | defaultConfig { 7 | applicationId "com.duy.sortalgorithm.free" 8 | minSdkVersion 14 9 | targetSdkVersion 25 10 | versionCode 4 11 | versionName "1.3" 12 | } 13 | buildTypes { 14 | release { 15 | minifyEnabled true 16 | shrinkResources true 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | debug { 20 | minifyEnabled false 21 | applicationIdSuffix ".debug" 22 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 23 | } 24 | } 25 | } 26 | 27 | dependencies { 28 | compile fileTree(dir: 'libs', include: ['*.jar']) 29 | compile 'com.android.support:appcompat-v7:25.1.1' 30 | compile 'com.android.support:design:25.1.1' 31 | compile 'com.sothree.slidinguppanel:library:3.3.1' 32 | compile 'com.android.support:cardview-v7:25.1.1' 33 | compile 'io.github.kobakei:ratethisapp:1.1.1' 34 | compile 'com.github.jorgecastilloprz:fabprogresscircle:1.01@aar' 35 | } 36 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | #Use 5 step of optimization 2 | #-optimizationpasses 5 3 | 4 | #When not preverifing in a case-insensitive filing system, such as Windows. This tool will unpack your processed jars,(if using windows you should then use): 5 | -dontusemixedcaseclassnames 6 | 7 | #Specifies not to ignore non-public library classes. As of version 4.5, this is the default setting 8 | -dontskipnonpubliclibraryclasses 9 | 10 | # Optimization is turned off by default. Dex does not like code run 11 | # through the ProGuard optimize and preverify steps (and performs some 12 | # of these optimizations on its own). 13 | -dontoptimize 14 | -dontpreverify 15 | 16 | -dontwarn android.support.** 17 | 18 | #Specifies to write out some more information during processing. If the program terminates with an exception, this option will print out the entire stack trace, instead of just the exception message. 19 | -verbose 20 | 21 | #The -optimizations option disables some arithmetic simplifications that Dalvik 1.0 and 1.5 can't handle. Note that the Dalvik VM also can't handle aggressive overloading (of static fields). 22 | #To understand or change this check http://proguard.sourceforge.net/index.html#/manual/optimizations.html 23 | #-optimizations !code/simplification/arithmetic,!field/*,!class/merging/* 24 | 25 | # Note that if you want to enable optimization, you cannot just 26 | # include optimization flags in your own project configuration file; 27 | # instead you will need to point to the 28 | # "proguard-android-optimize.txt" file instead of this one from your 29 | # project.properties file. 30 | 31 | #To repackage classes on a single package 32 | #-repackageclasses '' 33 | 34 | #Uncomment if using annotations to keep them. 35 | #-keepattributes *Annotation* 36 | 37 | #Keep classes that are referenced on the AndroidManifest 38 | -keep public class * extends android.app.Activity 39 | -keep public class * extends android.app.Application 40 | -keep public class * extends android.app.Service 41 | -keep public class * extends android.content.BroadcastReceiver 42 | -keep public class * extends android.content.ContentProvider 43 | -keep public class * extends android.app.backup.BackupAgentHelper 44 | -keep public class * extends android.preference.Preference 45 | -keep public class com.google.vending.licensing.ILicensingService 46 | -keep public class com.android.vending.licensing.ILicensingService 47 | #Compatibility library 48 | -keep public class * extends android.support.v4.app.Fragment 49 | -keep public class * extends android.app.Fragment 50 | 51 | #To maintain custom components names that are used on layouts XML. 52 | #Uncomment if having any problem with the approach below 53 | #-keep public class custom.components.package.and.name.** 54 | 55 | # keep setters in Views so that animations can still work. 56 | # see http://proguard.sourceforge.net/manual/examples.html#beans 57 | -keepclassmembers public class * extends android.view.View { 58 | void set*(***); 59 | *** get*(); 60 | } 61 | 62 | #To remove debug logs: 63 | -assumenosideeffects class android.util.Log { 64 | public static *** d(...); 65 | public static *** v(...); 66 | public static *** w(...); 67 | } 68 | 69 | #To avoid changing names of methods invoked on layout's onClick. 70 | # Uncomment and add specific method names if using onClick on layouts 71 | #-keepclassmembers class * { 72 | # public void onClickButton(android.view.View); 73 | #} 74 | 75 | #Maintain java native methods 76 | -keepclasseswithmembernames class * { 77 | native ; 78 | } 79 | 80 | 81 | #To maintain custom components names that are used on layouts XML: 82 | -keep public class * extends android.view.View { 83 | public (android.content.Context); 84 | } 85 | -keep public class * extends android.view.View { 86 | public (android.content.Context, android.util.AttributeSet); 87 | } 88 | -keep public class * extends android.view.View { 89 | public (android.content.Context, android.util.AttributeSet, int); 90 | } 91 | 92 | #Maintain enums 93 | -keepclassmembers enum * { 94 | public static **[] values(); 95 | public static ** valueOf(java.lang.String); 96 | } 97 | 98 | #To keep parcelable classes (to serialize - deserialize objects to sent through Intents) 99 | -keep class * implements android.os.Parcelable { 100 | public static final android.os.Parcelable$Creator *; 101 | } 102 | 103 | #Keep the R 104 | -keepclassmembers class **.R$* { 105 | public static ; 106 | } 107 | 108 | ###### ADDITIONAL OPTIONS NOT USED NORMALLY 109 | 110 | #To keep callback calls. Uncomment if using any 111 | #http://proguard.sourceforge.net/index.html#/manual/examples.html#callback 112 | #-keep class mypackage.MyCallbackClass { 113 | # void myCallbackMethod(java.lang.String); 114 | #} 115 | 116 | #Uncomment if using Serializable 117 | #-keepclassmembers class * implements java.io.Serializable { 118 | # private static final java.io.ObjectStreamField[] serialPersistentFields; 119 | # private void writeObject(java.io.ObjectOutputStream); 120 | # private void readObject(java.io.ObjectInputStream); 121 | # java.lang.Object writeReplace(); 122 | # java.lang.Object readResolve(); 123 | #} -------------------------------------------------------------------------------- /app/src/androidTest/java/com/duy/algorithm/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.duy.algorithm; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.assertEquals; 11 | 12 | /** 13 | * Instrumentation test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() throws Exception { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.duy.algorithm", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /app/src/main/java/com/duy/algorithm/AbstractAppCompatActivity.java: -------------------------------------------------------------------------------- 1 | package com.duy.algorithm; 2 | 3 | import android.content.ActivityNotFoundException; 4 | import android.content.Context; 5 | import android.content.DialogInterface; 6 | import android.content.Intent; 7 | import android.content.SharedPreferences; 8 | import android.content.res.Configuration; 9 | import android.content.res.Resources; 10 | import android.net.Uri; 11 | import android.os.Bundle; 12 | import android.preference.PreferenceManager; 13 | import android.support.annotation.Nullable; 14 | import android.support.v7.app.AlertDialog; 15 | import android.support.v7.app.AppCompatActivity; 16 | import android.util.Log; 17 | import android.view.View; 18 | import android.view.inputmethod.InputMethodManager; 19 | import android.widget.EditText; 20 | import android.widget.Toast; 21 | 22 | import com.duy.algorithm.userinterface.ThemeEngine; 23 | import com.kobakei.ratethisapp.RateThisApp; 24 | 25 | import java.util.Locale; 26 | 27 | 28 | /** 29 | * abstract theme for app 30 | *

31 | * auto set theme when user changed theme 32 | *

33 | * Created by Duy on 19/7/2016 34 | */ 35 | public abstract class AbstractAppCompatActivity extends AppCompatActivity 36 | implements SharedPreferences.OnSharedPreferenceChangeListener { 37 | public static final String TAG = "MainActivity"; 38 | protected SharedPreferences mPreferences; 39 | public static final String APP_ID = BuildConfig.APPLICATION_ID; 40 | 41 | 42 | /** 43 | * set theme and init mHistoryDatabase for history 44 | * 45 | * @param savedInstanceState 46 | */ 47 | @Override 48 | protected void onCreate(@Nullable Bundle savedInstanceState) { 49 | super.onCreate(savedInstanceState); 50 | 51 | // getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, 52 | // WindowManager.LayoutParams.FLAG_FULLSCREEN); 53 | // if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { 54 | // Window w = getWindow(); // in Activity's onCreate() for instance 55 | // w.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, 56 | // WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); 57 | // } 58 | mPreferences = PreferenceManager.getDefaultSharedPreferences(this); 59 | 60 | setLocale(false); 61 | 62 | //set theme for app 63 | setTheme(false); 64 | } 65 | 66 | /** 67 | * set language 68 | * 69 | * @param create 70 | */ 71 | 72 | private void setLocale(boolean create) { 73 | Locale locale; 74 | String code = mPreferences.getString(getString(R.string.key_pref_lang), "default_lang"); 75 | if (code.equals("default_lang")) { 76 | Log.d(TAG, "setLocale: default"); 77 | locale = Locale.getDefault(); 78 | } else { 79 | locale = new Locale(code); 80 | } 81 | Locale.setDefault(locale); 82 | Configuration config = new Configuration(); 83 | config.locale = locale; 84 | Resources resources = getResources(); 85 | resources.updateConfiguration(config, resources.getDisplayMetrics()); 86 | if (create) recreate(); 87 | } 88 | 89 | 90 | @Override 91 | public void onBackPressed() { 92 | super.onBackPressed(); 93 | } 94 | 95 | @Override 96 | protected void onStart() { 97 | super.onStart(); 98 | if (mPreferences != null) 99 | mPreferences.registerOnSharedPreferenceChangeListener(this); 100 | // Monitor launch times and interval from installation 101 | RateThisApp.onStart(this); 102 | // If the criteria is satisfied, "Rate this app" dialog will be shown 103 | RateThisApp.showRateDialogIfNeeded(this); 104 | RateThisApp.setCallback(new RateThisApp.Callback() { 105 | @Override 106 | public void onYesClicked() { 107 | rateApp(null); 108 | } 109 | 110 | @Override 111 | public void onNoClicked() { 112 | } 113 | 114 | @Override 115 | public void onCancelClicked() { 116 | } 117 | }); 118 | 119 | } 120 | 121 | @Override 122 | protected void onResume() { 123 | super.onResume(); 124 | } 125 | 126 | /** 127 | * set theme for app 128 | * 129 | * @param recreate -call method onCreate 130 | */ 131 | protected void setTheme(boolean recreate) { 132 | String name = mPreferences.getString(getResources().getString(R.string.key_pref_theme), ""); 133 | ThemeEngine themeEngine = new ThemeEngine(getApplicationContext()); 134 | int themeId = themeEngine.getTheme(name); 135 | if (themeId != ThemeEngine.THEME_NOT_FOUND) { 136 | super.setTheme(themeId); 137 | if (recreate) recreate(); 138 | Log.d(TAG, "Set theme ok"); 139 | } else { 140 | Log.d(TAG, "Theme not found"); 141 | } 142 | } 143 | 144 | @Override 145 | public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String s) { 146 | if (s.equals(getResources().getString(R.string.key_pref_theme))) { 147 | setTheme(true); 148 | } else if (s.equals(getString(R.string.key_pref_lang))) { 149 | setLocale(true); 150 | Toast.makeText(this, getString(R.string.change_lang_msg), Toast.LENGTH_SHORT).show(); 151 | } 152 | } 153 | 154 | @Override 155 | protected void onPause() { 156 | super.onPause(); 157 | } 158 | 159 | @Override 160 | protected void onDestroy() { 161 | super.onDestroy(); 162 | if (mPreferences != null) 163 | mPreferences.unregisterOnSharedPreferenceChangeListener(this); 164 | } 165 | 166 | 167 | /** 168 | * share app 169 | */ 170 | public void shareApp(View view) { 171 | Intent intent = new Intent(); 172 | intent.setAction(Intent.ACTION_SEND); 173 | intent.putExtra(Intent.EXTRA_TEXT, "http://play.google.com/store/apps/details?id=" + APP_ID); 174 | intent.setType("text/plain"); 175 | startActivity(intent); 176 | } 177 | 178 | /** 179 | * show dialog with title and messenger 180 | * 181 | * @param title - title 182 | * @param msg - messenger 183 | */ 184 | protected void showDialog(String title, String msg) { 185 | AlertDialog.Builder builder = new AlertDialog.Builder(this); 186 | builder.setTitle(title).setMessage(msg); 187 | builder.setNegativeButton(this.getString(R.string.close), new DialogInterface.OnClickListener() { 188 | @Override 189 | public void onClick(DialogInterface dialogInterface, int i) { 190 | dialogInterface.cancel(); 191 | } 192 | }); 193 | builder.create().show(); 194 | } 195 | 196 | /** 197 | * show dialog with title and messenger 198 | * 199 | * @param msg - messenger 200 | */ 201 | protected void showDialog(String msg) { 202 | this.showDialog("", msg); 203 | } 204 | 205 | 206 | 207 | public void rateApp(View view) { 208 | Uri uri = Uri.parse("market://details?id=" + APP_ID); 209 | Intent goToMarket = new Intent(Intent.ACTION_VIEW, uri); 210 | // To count with Play market backstack, After pressing back button, 211 | // to taken back to our application, we need to add following flags to intent. 212 | goToMarket.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY | 213 | Intent.FLAG_ACTIVITY_MULTIPLE_TASK); 214 | try { 215 | startActivity(goToMarket); 216 | } catch (ActivityNotFoundException e) { 217 | startActivity(new Intent(Intent.ACTION_VIEW, 218 | Uri.parse("http://play.google.com/store/apps/details?id=" + APP_ID))); 219 | } 220 | } 221 | 222 | public void moreApp(View view) { 223 | Uri uri = Uri.parse("market://search?q=pub:Trần Lê Duy"); 224 | Intent goToMarket = new Intent(Intent.ACTION_VIEW, uri); 225 | // To count with Play market backstack, After pressing back button, 226 | // to taken back to our application, we need to add following flags to intent. 227 | goToMarket.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY | 228 | 229 | Intent.FLAG_ACTIVITY_MULTIPLE_TASK); 230 | try { 231 | startActivity(goToMarket); 232 | } catch (ActivityNotFoundException e) { 233 | startActivity(new Intent(Intent.ACTION_VIEW, 234 | Uri.parse("http://play.google.com/store/search?q=pub:Trần Lê Duy"))); 235 | } 236 | } 237 | 238 | protected void hideKeyboard(EditText editText) { 239 | InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); 240 | imm.hideSoftInputFromWindow(editText.getWindowToken(), 0); 241 | } 242 | 243 | 244 | } 245 | -------------------------------------------------------------------------------- /app/src/main/java/com/duy/algorithm/AbstractSortAlgorithmFragment.java: -------------------------------------------------------------------------------- 1 | package com.duy.algorithm; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.Nullable; 5 | import android.support.design.widget.FloatingActionButton; 6 | import android.support.v4.app.Fragment; 7 | import android.util.Log; 8 | import android.view.LayoutInflater; 9 | import android.view.View; 10 | import android.view.ViewGroup; 11 | import android.widget.Button; 12 | import android.widget.EditText; 13 | import android.widget.SeekBar; 14 | import android.widget.TextView; 15 | 16 | import com.github.jorgecastilloprz.FABProgressCircle; 17 | import com.sothree.slidinguppanel.SlidingUpPanelLayout; 18 | 19 | import static com.duy.algorithm.algorithms.AlgorithmThread.KEY_ALGORITHM; 20 | 21 | /** 22 | * Created by DUy on 04-Feb-17. 23 | */ 24 | 25 | public abstract class AbstractSortAlgorithmFragment extends Fragment implements SortCompletionListener { 26 | final String TAG = AbstractSortAlgorithmFragment.class.getSimpleName(); 27 | protected View mRootView; 28 | protected FloatingActionButton mPlay; 29 | protected FABProgressCircle mPlayAnimation; 30 | protected TextView txtInfo; 31 | protected EditText mEditNumber; 32 | protected SeekBar mTimeBar; 33 | protected TextView txtProgress; 34 | protected Button btnRandom; 35 | protected EditText mEditArray; 36 | protected SlidingUpPanelLayout mSlidingUpPanelLayout; 37 | 38 | @Nullable 39 | @Override 40 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 41 | mRootView = getView(inflater, container); 42 | return mRootView; 43 | } 44 | 45 | @Override 46 | public void onActivityCreated(@Nullable Bundle savedInstanceState) { 47 | super.onActivityCreated(savedInstanceState); 48 | 49 | createSortView(); 50 | 51 | mPlay = (FloatingActionButton) findViewById(R.id.fab); 52 | mPlayAnimation = (FABProgressCircle) findViewById(R.id.fabProgressCircle); 53 | txtProgress = (TextView) findViewById(R.id.txt_process); 54 | mTimeBar = (SeekBar) findViewById(R.id.seek_bar_time); 55 | 56 | /** 57 | * length of array and array 58 | */ 59 | mEditNumber = (EditText) findViewById(R.id.edit_length); 60 | mEditArray = (EditText) findViewById(R.id.edit_entry); 61 | 62 | btnRandom = (Button) findViewById(R.id.ckb_random); 63 | 64 | mSlidingUpPanelLayout = (SlidingUpPanelLayout) findViewById(R.id.sliding_layout); 65 | 66 | //set up fragment 67 | setupFragment(getArguments().getString(KEY_ALGORITHM)); 68 | 69 | txtProgress.setText(" " + (mTimeBar.getProgress() + 10)); 70 | //set time delay for thread 71 | mTimeBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { 72 | @Override 73 | public void onProgressChanged(SeekBar seekBar, int value, boolean fromUser) { 74 | txtProgress.setText(" " + (value + 10)); 75 | setDelayTime(value); 76 | } 77 | 78 | @Override 79 | public void onStartTrackingTouch(SeekBar seekBar) { 80 | 81 | } 82 | 83 | @Override 84 | public void onStopTrackingTouch(SeekBar seekBar) { 85 | 86 | } 87 | }); 88 | btnRandom.setOnClickListener(new View.OnClickListener() { 89 | @Override 90 | public void onClick(View v) { 91 | generateRandomData(); 92 | // mSlidingUpPanelLayout.setPanelState(SlidingUpPanelLayout.PanelState.COLLAPSED); 93 | } 94 | }); 95 | 96 | mPlay.setImageResource(R.drawable.ic_play_arrow_white_24dp); 97 | mPlay.setOnClickListener(new View.OnClickListener() { 98 | @Override 99 | public void onClick(View v) { 100 | fabClick(); 101 | } 102 | }); 103 | 104 | } 105 | 106 | protected abstract void fabClick(); 107 | 108 | protected abstract void createSortView(); 109 | 110 | /** 111 | * start thread sort 112 | */ 113 | protected abstract void startSort(); 114 | 115 | /** 116 | * pause all thread sort 117 | */ 118 | protected abstract void pauseSort(); 119 | 120 | /** 121 | * resume all thread 122 | */ 123 | protected abstract void resumeSort(); 124 | 125 | protected abstract void setDelayTime(int value); 126 | 127 | /** 128 | * create random data 129 | */ 130 | protected abstract void generateRandomData(); 131 | 132 | public abstract void setupFragment(String name); 133 | 134 | /** 135 | * find view by id and return view, if view is null, find view in parent activity 136 | * 137 | * @param viewId - id of view 138 | * @return view 139 | */ 140 | public View findViewById(int viewId) { 141 | View view; 142 | view = mRootView.findViewById(viewId); 143 | if (view != null) return view; 144 | return getActivity().findViewById(viewId); 145 | } 146 | 147 | /** 148 | * get container view and store it to mRootView 149 | * 150 | * @return - container view 151 | */ 152 | public abstract View getView(LayoutInflater inflater, ViewGroup v); 153 | 154 | /** 155 | * check input empty and create data if need 156 | * 157 | * @return - true if success, otherwise false 158 | */ 159 | public abstract boolean createData(); 160 | 161 | /** 162 | * enable some view of needed 163 | */ 164 | public void enableView() { 165 | Log.d(TAG, "enableView: "); 166 | if (getActivity() != null) { 167 | getActivity().runOnUiThread(new Runnable() { 168 | @Override 169 | public void run() { 170 | mEditArray.setEnabled(true); 171 | mEditNumber.setEnabled(true); 172 | btnRandom.setEnabled(true); 173 | } 174 | }); 175 | } 176 | } 177 | 178 | /** 179 | * disable some view if needed 180 | */ 181 | public void disableView() { 182 | Log.d(TAG, "disableView: "); 183 | if (getActivity() != null) { 184 | getActivity().runOnUiThread(new Runnable() { 185 | @Override 186 | public void run() { 187 | mEditArray.setEnabled(false); 188 | mEditNumber.setEnabled(false); 189 | btnRandom.setEnabled(false); 190 | } 191 | }); 192 | } 193 | } 194 | 195 | @Override 196 | public void onResume() { 197 | super.onResume(); 198 | // resumeSort(); 199 | } 200 | 201 | @Override 202 | public void onPause() { 203 | super.onPause(); 204 | Log.d(TAG, "onPause: "); 205 | try { 206 | pauseSort(); enableView(); 207 | 208 | } catch (Exception e) { 209 | e.printStackTrace(); 210 | } 211 | } 212 | 213 | @Override 214 | public void onDestroy() { 215 | super.onDestroy(); 216 | 217 | } 218 | 219 | @Override 220 | public void onSortCompleted() { 221 | 222 | } 223 | 224 | } 225 | -------------------------------------------------------------------------------- /app/src/main/java/com/duy/algorithm/AppAboutActivity.java: -------------------------------------------------------------------------------- 1 | package com.duy.algorithm; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | import android.net.Uri; 6 | import android.os.Bundle; 7 | import android.support.v7.widget.Toolbar; 8 | import android.view.MenuItem; 9 | 10 | public class AppAboutActivity extends AbstractAppCompatActivity { 11 | 12 | @Override 13 | protected void onCreate(Bundle savedInstanceState) { 14 | super.onCreate(savedInstanceState); 15 | setContentView(R.layout.activity_app_about); 16 | Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 17 | setSupportActionBar(toolbar); 18 | getSupportActionBar().setHomeButtonEnabled(true); 19 | getSupportActionBar().setDisplayHomeAsUpEnabled(true); 20 | 21 | } 22 | 23 | public Intent getOpenFacebookIntent(Context context) { 24 | try { 25 | context.getPackageManager().getPackageInfo("com.facebook.katana", 0); 26 | return new Intent(Intent.ACTION_VIEW, Uri.parse("fb://page/883398988363238")); 27 | } catch (Exception e) { 28 | return new Intent(Intent.ACTION_VIEW, Uri.parse("https://www.facebook.com/com.duy.calculator.n.plus/")); 29 | } 30 | } 31 | 32 | @Override 33 | public boolean onOptionsItemSelected(MenuItem item) { 34 | int id = item.getItemId(); 35 | if (id == android.R.id.home) { 36 | finish(); 37 | } 38 | return super.onOptionsItemSelected(item); 39 | } 40 | 41 | 42 | } 43 | -------------------------------------------------------------------------------- /app/src/main/java/com/duy/algorithm/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.duy.algorithm; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | import android.os.Handler; 6 | import android.support.annotation.NonNull; 7 | import android.support.annotation.Nullable; 8 | import android.support.design.widget.NavigationView; 9 | import android.support.v4.app.Fragment; 10 | import android.support.v4.app.FragmentManager; 11 | import android.support.v4.app.FragmentTransaction; 12 | import android.support.v4.view.GravityCompat; 13 | import android.support.v4.widget.DrawerLayout; 14 | import android.support.v7.app.ActionBarDrawerToggle; 15 | import android.support.v7.widget.Toolbar; 16 | import android.view.MenuItem; 17 | import android.view.View; 18 | 19 | import com.sothree.slidinguppanel.SlidingUpPanelLayout; 20 | 21 | import static com.duy.algorithm.algorithms.AlgorithmThread.ALGORITHM_NAME.BUBBLE_SORT; 22 | import static com.duy.algorithm.algorithms.AlgorithmThread.ALGORITHM_NAME.COCKTAIL_SORT; 23 | import static com.duy.algorithm.algorithms.AlgorithmThread.ALGORITHM_NAME.INSERTION_SORT; 24 | import static com.duy.algorithm.algorithms.AlgorithmThread.ALGORITHM_NAME.MERGE_SORT; 25 | import static com.duy.algorithm.algorithms.AlgorithmThread.ALGORITHM_NAME.QUICK_SORT; 26 | import static com.duy.algorithm.algorithms.AlgorithmThread.ALGORITHM_NAME.SELECTION_SORT; 27 | import static com.duy.algorithm.algorithms.AlgorithmThread.ALGORITHM_NAME.SHELL_SORT; 28 | 29 | /** 30 | * Created by DUy on 02-Feb-17. 31 | */ 32 | 33 | public class MainActivity extends AbstractAppCompatActivity implements NavigationView.OnNavigationItemSelectedListener { 34 | private DrawerLayout drawerLayout; 35 | private NavigationView navigationView; 36 | private SlidingUpPanelLayout slidingUpPanelLayout; 37 | private Handler handler = new Handler(); 38 | 39 | @Override 40 | protected void onCreate(@Nullable Bundle savedInstanceState) { 41 | super.onCreate(savedInstanceState); 42 | setContentView(R.layout.activity_main); 43 | 44 | Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 45 | setSupportActionBar(toolbar); 46 | 47 | navigationView = (NavigationView) findViewById(R.id.nav_view); 48 | navigationView.setNavigationItemSelectedListener(this); 49 | 50 | drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); 51 | 52 | ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawerLayout, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close); 53 | drawerLayout.setDrawerListener(toggle); 54 | toggle.syncState(); 55 | 56 | slidingUpPanelLayout = (SlidingUpPanelLayout) findViewById(R.id.sliding_layout); 57 | 58 | // logAdapter = new LogAdapter(this); 59 | // mLogger = (RecyclerView) findViewById(R.id.rc_logger); 60 | // LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this); 61 | // linearLayoutManager.setStackFromEnd(true); 62 | // mLogger.setHasFixedSize(true); 63 | // mLogger.setAdapter(logAdapter); 64 | } 65 | 66 | public int getStatusBarHeight() { 67 | int result = 0; 68 | int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android"); 69 | if (resourceId > 0) { 70 | result = getResources().getDimensionPixelSize(resourceId); 71 | } 72 | return result; 73 | } 74 | 75 | @Override 76 | protected void onResume() { 77 | super.onResume(); 78 | } 79 | 80 | @Override 81 | public void onBackPressed() { 82 | if (drawerLayout.isDrawerOpen(GravityCompat.START)) { 83 | drawerLayout.closeDrawers(); 84 | return; 85 | } 86 | if (slidingUpPanelLayout.getPanelState() == SlidingUpPanelLayout.PanelState.EXPANDED) { 87 | slidingUpPanelLayout.setPanelState(SlidingUpPanelLayout.PanelState.COLLAPSED); 88 | return; 89 | } 90 | super.onBackPressed(); 91 | } 92 | 93 | @Override 94 | public boolean onNavigationItemSelected(@NonNull MenuItem item) { 95 | SortAlgorithmFragment algorithmFragment = null; 96 | SortSpeedTestFragmentSort sortSpeedTestFragment = null; 97 | setTitle(item.getTitle().toString()); 98 | int id = item.getItemId(); 99 | switch (id) { 100 | case R.id.nav_bubble_sort: 101 | algorithmFragment = SortAlgorithmFragment.newInstance(BUBBLE_SORT); 102 | commit(algorithmFragment); 103 | break; 104 | case R.id.nav_insert_sort: 105 | algorithmFragment = SortAlgorithmFragment.newInstance(INSERTION_SORT); 106 | commit(algorithmFragment); 107 | break; 108 | case R.id.nav_merge_sort: 109 | algorithmFragment = SortAlgorithmFragment.newInstance(MERGE_SORT); 110 | commit(algorithmFragment); 111 | break; 112 | case R.id.nav_quick_sort: 113 | algorithmFragment = SortAlgorithmFragment.newInstance(QUICK_SORT); 114 | commit(algorithmFragment); 115 | break; 116 | case R.id.nav_select_sort: 117 | algorithmFragment = SortAlgorithmFragment.newInstance(SELECTION_SORT); 118 | commit(algorithmFragment); 119 | break; 120 | case R.id.nav_shell_sort: 121 | algorithmFragment = SortAlgorithmFragment.newInstance(SHELL_SORT); 122 | commit(algorithmFragment); 123 | break; 124 | case R.id.nav_sort_test: 125 | sortSpeedTestFragment = SortSpeedTestFragmentSort.newInstance(SHELL_SORT); 126 | commit(sortSpeedTestFragment); 127 | break; 128 | case R.id.nav_setting: 129 | startActivity(new Intent(getApplicationContext(), SettingsActivity.class)); 130 | break; 131 | case R.id.nav_info: 132 | startActivity(new Intent(getApplicationContext(), AppAboutActivity.class)); 133 | break; 134 | case R.id.nav_cocktail_sort: 135 | algorithmFragment = SortAlgorithmFragment.newInstance(COCKTAIL_SORT); 136 | commit(algorithmFragment); 137 | break; 138 | } 139 | drawerLayout.closeDrawers(); 140 | return true; 141 | } 142 | 143 | @Override 144 | protected void onStop() { 145 | super.onStop(); 146 | } 147 | 148 | private void commit(Fragment algorithmFragment) { 149 | FragmentManager fragmentManager = getSupportFragmentManager(); 150 | FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); 151 | fragmentTransaction.replace(R.id.container, algorithmFragment); 152 | fragmentTransaction.commit(); 153 | } 154 | 155 | public void openDrawer(View view) { 156 | drawerLayout.openDrawer(GravityCompat.START); 157 | // if (view != null) view.setVisibility(View.GONE); 158 | } 159 | 160 | 161 | public void showLog(String log) { 162 | // logAdapter.showLog(log); 163 | // mLogger.scrollToPosition(logAdapter.getItemCount() - 1); 164 | } 165 | 166 | public void clearLog() { 167 | // logAdapter.clear(); 168 | } 169 | 170 | public void showLog(String message, int[] array) { 171 | } 172 | } 173 | -------------------------------------------------------------------------------- /app/src/main/java/com/duy/algorithm/SettingsActivity.java: -------------------------------------------------------------------------------- 1 | package com.duy.algorithm; 2 | 3 | 4 | import android.os.Bundle; 5 | import android.preference.PreferenceActivity; 6 | import android.preference.PreferenceFragment; 7 | 8 | /** 9 | * Setting for calcualtor 10 | *

11 | * Include precision of calculate. Font, theme, style. Dev mode, trace mode. 12 | */ 13 | public class SettingsActivity extends PreferenceActivity { 14 | @Override 15 | protected void onCreate(Bundle savedInstanceState) { 16 | super.onCreate(savedInstanceState); 17 | setTitle(R.string.setting); 18 | getFragmentManager().beginTransaction().replace(android.R.id.content, new MyPreferenceFragment()).commit(); 19 | } 20 | 21 | @Override 22 | protected void onResume() { 23 | super.onResume(); 24 | } 25 | 26 | public static class MyPreferenceFragment extends PreferenceFragment { 27 | @Override 28 | public void onCreate(final Bundle savedInstanceState) { 29 | super.onCreate(savedInstanceState); 30 | addPreferencesFromResource(R.xml.setting); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /app/src/main/java/com/duy/algorithm/SortAlgorithmFragment.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Naman Dwivedi 3 | * 4 | * Licensed under the GNU General Public License v3 5 | * 6 | * This is free software: you can redistribute it and/or modify it 7 | * under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 9 | * 10 | * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; 11 | * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the GNU General Public License for more details. 13 | */ 14 | 15 | package com.duy.algorithm; 16 | 17 | import android.os.Bundle; 18 | import android.util.Log; 19 | import android.view.LayoutInflater; 20 | import android.view.View; 21 | import android.view.ViewGroup; 22 | import android.widget.Toast; 23 | 24 | import com.duy.algorithm.algorithms.SortAlgorithmThread; 25 | import com.duy.algorithm.algorithms.algo.BubbleSortThread; 26 | import com.duy.algorithm.algorithms.algo.CocktailShakerSortThread; 27 | import com.duy.algorithm.algorithms.algo.InsertionSortThread; 28 | import com.duy.algorithm.algorithms.algo.MergeSortThread; 29 | import com.duy.algorithm.algorithms.algo.QuickSortThread; 30 | import com.duy.algorithm.algorithms.algo.SelectionSortThread; 31 | import com.duy.algorithm.algorithms.algo.ShellSortThread; 32 | import com.duy.algorithm.customview.LogView; 33 | import com.duy.algorithm.customview.SortView; 34 | import com.duy.algorithm.utils.ArrayUtils; 35 | 36 | import java.util.regex.Pattern; 37 | 38 | import static com.duy.algorithm.algorithms.AlgorithmThread.ALGORITHM_NAME.BUBBLE_SORT; 39 | import static com.duy.algorithm.algorithms.AlgorithmThread.ALGORITHM_NAME.COCKTAIL_SORT; 40 | import static com.duy.algorithm.algorithms.AlgorithmThread.ALGORITHM_NAME.INSERTION_SORT; 41 | import static com.duy.algorithm.algorithms.AlgorithmThread.ALGORITHM_NAME.MERGE_SORT; 42 | import static com.duy.algorithm.algorithms.AlgorithmThread.ALGORITHM_NAME.QUICK_SORT; 43 | import static com.duy.algorithm.algorithms.AlgorithmThread.ALGORITHM_NAME.SELECTION_SORT; 44 | import static com.duy.algorithm.algorithms.AlgorithmThread.ALGORITHM_NAME.SHELL_SORT; 45 | import static com.duy.algorithm.algorithms.AlgorithmThread.COMMAND_START_ALGORITHM; 46 | import static com.duy.algorithm.algorithms.AlgorithmThread.KEY_ALGORITHM; 47 | 48 | public class SortAlgorithmFragment extends AbstractSortAlgorithmFragment { 49 | 50 | private final static String TAG = SortAlgorithmFragment.class.getSimpleName(); 51 | protected SortAlgorithmThread thread; 52 | private SortView mSortView; 53 | private int mCountData = 50; 54 | private LogView mLogger; 55 | 56 | public static SortAlgorithmFragment newInstance(String algorithm) { 57 | SortAlgorithmFragment fragment = new SortAlgorithmFragment(); 58 | Bundle bundle = new Bundle(); 59 | bundle.putString(KEY_ALGORITHM, algorithm); 60 | fragment.setArguments(bundle); 61 | return fragment; 62 | } 63 | 64 | @Override 65 | public View getView(LayoutInflater inflater, ViewGroup container) { 66 | return inflater.inflate(R.layout.fragment_sort, container, false); 67 | } 68 | 69 | @Override 70 | protected void createSortView() { 71 | mSortView = (SortView) findViewById(R.id.sortView); 72 | mLogger = (LogView) findViewById(R.id.rc_log); 73 | mLogger.setmEmptyView(findViewById(R.id.empty_view)); 74 | } 75 | 76 | @Override 77 | public void setupFragment(String algorithmKey) { 78 | switch (algorithmKey) { 79 | case BUBBLE_SORT: 80 | thread = new BubbleSortThread(mSortView, getActivity()); 81 | break; 82 | case INSERTION_SORT: 83 | thread = new InsertionSortThread(mSortView, getActivity()); 84 | break; 85 | case SELECTION_SORT: 86 | thread = new SelectionSortThread(mSortView, getActivity()); 87 | break; 88 | case QUICK_SORT: 89 | thread = new QuickSortThread(mSortView, getActivity()); 90 | break; 91 | case MERGE_SORT: 92 | thread = new MergeSortThread(mSortView, getActivity()); 93 | break; 94 | case SHELL_SORT: 95 | thread = new ShellSortThread(mSortView, getActivity()); 96 | break; 97 | case COCKTAIL_SORT: 98 | thread = new CocktailShakerSortThread(mSortView, getActivity()); 99 | break; 100 | } 101 | thread.setStarted(false); 102 | thread.setCompletionListener(this); 103 | thread.setLogger(mLogger); 104 | generateRandomData(); 105 | } 106 | 107 | @Override 108 | public void enableView() { 109 | mEditArray.setEnabled(true); 110 | mEditNumber.setEnabled(true); 111 | btnRandom.setEnabled(true); 112 | } 113 | 114 | 115 | @Override 116 | protected void setDelayTime(int value) { 117 | if (thread.isStarted()) 118 | thread.setDelayTime(value + 10); 119 | } 120 | 121 | @Override 122 | protected void startSort() { 123 | if (createData()) { 124 | thread.sendMessage(COMMAND_START_ALGORITHM); 125 | mPlay.setImageResource(R.drawable.ic_pause_white_24dp); 126 | mPlayAnimation.show(); 127 | disableView(); 128 | } 129 | } 130 | 131 | @Override 132 | protected void fabClick() { 133 | if (!thread.isStarted()) {//If you have sorted or not sorted 134 | startSort(); 135 | } else { //if it is sorting, pause or resume thread 136 | if (thread.isPaused()) 137 | resumeSort(); 138 | else 139 | pauseSort(); 140 | } 141 | } 142 | 143 | 144 | @Override 145 | public void generateRandomData() { 146 | //check empty length of array 147 | if (mEditNumber.getText().toString().isEmpty()) { 148 | mCountData = Integer.parseInt(mEditNumber.getHint().toString()); 149 | } else { 150 | mCountData = Integer.parseInt(mEditNumber.getText().toString()); 151 | } 152 | 153 | int[] array = ArrayUtils.createIntArray(mCountData); 154 | thread.setData(array); 155 | mEditArray.setText(ArrayUtils.arrayToString(array)); 156 | } 157 | 158 | @Override 159 | public boolean createData() { 160 | Log.d(TAG, "createData: "); 161 | 162 | //set time sleep for thread 163 | int delayTime = mTimeBar.getProgress(); 164 | thread.setDelayTime(delayTime); 165 | 166 | //check empty length of array 167 | if (mEditNumber.getText().toString().isEmpty()) { 168 | mCountData = Integer.parseInt(mEditNumber.getHint().toString()); 169 | } else { 170 | mCountData = Integer.parseInt(mEditNumber.getText().toString()); 171 | } 172 | 173 | String raw = mEditArray.getText().toString(); 174 | final String strArray[] = raw.split(Pattern.quote(",")); 175 | if (strArray.length == mCountData) { 176 | int[] array = ArrayUtils.arrayStringToInt(strArray); 177 | 178 | //If receive an error during conversion 179 | if (array[0] == -1) { 180 | return false; 181 | } 182 | thread.setData(array); 183 | return true; 184 | } else { 185 | // mSlidingUpPanelLayout.setPanelState(SlidingUpPanelLayout.PanelState.EXPANDED); 186 | if (strArray.length > mCountData) { 187 | Toast.makeText(getActivity(), "Please remove " + 188 | +(strArray.length - mCountData) 189 | + " entry of array, length of array is " 190 | + strArray.length, Toast.LENGTH_LONG).show(); 191 | } else { 192 | Toast.makeText(getActivity(), "Please add " 193 | + (-strArray.length + mCountData) 194 | + " entry of array, length of array is " 195 | + strArray.length, Toast.LENGTH_LONG).show(); 196 | } 197 | 198 | return false; 199 | } 200 | } 201 | 202 | @Override 203 | public void pauseSort() { 204 | if (thread.isStarted()) { 205 | thread.setPaused(true); 206 | mPlay.setImageResource(R.drawable.ic_play_arrow_white_24dp); 207 | mPlayAnimation.hide(); 208 | disableView(); 209 | } 210 | } 211 | 212 | @Override 213 | protected void resumeSort() { 214 | if (thread.isPaused()) { 215 | thread.setPaused(false); 216 | mPlay.setImageResource(R.drawable.ic_pause_white_24dp); 217 | mPlayAnimation.show(); 218 | disableView(); 219 | } 220 | } 221 | 222 | @Override 223 | public void onSortCompleted() { 224 | if (getActivity() != null) { 225 | getActivity().runOnUiThread(new Runnable() { 226 | @Override 227 | public void run() { 228 | Toast.makeText(getActivity().getApplicationContext(), R.string.sorted, Toast.LENGTH_SHORT).show(); 229 | enableView(); 230 | mPlayAnimation.hide(); 231 | mPlay.setImageResource(R.drawable.ic_settings_backup_restore_white_24dp); 232 | } 233 | }); 234 | } 235 | super.onSortCompleted(); 236 | } 237 | } 238 | -------------------------------------------------------------------------------- /app/src/main/java/com/duy/algorithm/SortCompletionListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Naman Dwivedi 3 | * 4 | * Licensed under the GNU General Public License v3 5 | * 6 | * This is free software: you can redistribute it and/or modify it 7 | * under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 9 | * 10 | * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; 11 | * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the GNU General Public License for more details. 13 | */ 14 | 15 | package com.duy.algorithm; 16 | 17 | public interface SortCompletionListener { 18 | 19 | void onSortCompleted(); 20 | } 21 | -------------------------------------------------------------------------------- /app/src/main/java/com/duy/algorithm/SortSpeedTestFragmentSort.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Naman Dwivedi 3 | * 4 | * Licensed under the GNU General Public License v3 5 | * 6 | * This is free software: you can redistribute it and/or modify it 7 | * under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 9 | * 10 | * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; 11 | * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the GNU General Public License for more details. 13 | */ 14 | 15 | package com.duy.algorithm; 16 | 17 | import android.os.Bundle; 18 | import android.util.Log; 19 | import android.view.LayoutInflater; 20 | import android.view.View; 21 | import android.view.ViewGroup; 22 | import android.widget.Toast; 23 | 24 | import com.duy.algorithm.algorithms.AlgorithmThread; 25 | import com.duy.algorithm.algorithms.SortAlgorithmThread; 26 | import com.duy.algorithm.algorithms.algo.BubbleSortThread; 27 | import com.duy.algorithm.algorithms.algo.CocktailShakerSortThread; 28 | import com.duy.algorithm.algorithms.algo.InsertionSortThread; 29 | import com.duy.algorithm.algorithms.algo.MergeSortThread; 30 | import com.duy.algorithm.algorithms.algo.QuickSortThread; 31 | import com.duy.algorithm.algorithms.algo.SelectionSortThread; 32 | import com.duy.algorithm.algorithms.algo.ShellSortThread; 33 | import com.duy.algorithm.customview.SortView; 34 | import com.duy.algorithm.utils.ArrayUtils; 35 | import com.sothree.slidinguppanel.SlidingUpPanelLayout; 36 | 37 | import java.util.regex.Pattern; 38 | 39 | import static com.duy.algorithm.algorithms.AlgorithmThread.KEY_ALGORITHM; 40 | 41 | public class SortSpeedTestFragmentSort extends AbstractSortAlgorithmFragment { 42 | private final static String TAG = SortSpeedTestFragmentSort.class.getSimpleName(); 43 | private final int mCount = 7; 44 | private SortAlgorithmThread[] threads = new SortAlgorithmThread[mCount]; 45 | private SortView[] mSortViews = new SortView[mCount]; 46 | private int mCountData = 50; 47 | private int numThreadCompleted = 0; 48 | 49 | public static SortSpeedTestFragmentSort newInstance(String algorithm) { 50 | SortSpeedTestFragmentSort fragment = new SortSpeedTestFragmentSort(); 51 | Bundle bundle = new Bundle(); 52 | bundle.putString(KEY_ALGORITHM, algorithm); 53 | fragment.setArguments(bundle); 54 | return fragment; 55 | } 56 | 57 | @Override 58 | public View getView(LayoutInflater inflater, ViewGroup v) { 59 | return inflater.inflate(R.layout.fragment_multi_sort, v, false); 60 | } 61 | 62 | @Override 63 | protected void createSortView() { 64 | mSortViews[0] = (SortView) findViewById(R.id.sortView0); 65 | mSortViews[0].setName(R.string.bubble_sort); 66 | 67 | mSortViews[1] = (SortView) findViewById(R.id.sortView1); 68 | mSortViews[1].setName(R.string.insert_sort); 69 | 70 | mSortViews[2] = (SortView) findViewById(R.id.sortView2); 71 | mSortViews[2].setName(R.string.selection_sort); 72 | 73 | mSortViews[3] = (SortView) findViewById(R.id.sortView3); 74 | mSortViews[3].setName(R.string.quick_sort); 75 | 76 | mSortViews[4] = (SortView) findViewById(R.id.sortView4); 77 | mSortViews[4].setName(R.string.merge_sort); 78 | 79 | mSortViews[5] = (SortView) findViewById(R.id.sortView5); 80 | mSortViews[5].setName(R.string.shell_sort); 81 | 82 | mSortViews[6] = (SortView) findViewById(R.id.sortView6); 83 | mSortViews[6].setName(R.string.cocktail_sort); 84 | } 85 | 86 | @Override 87 | protected void setDelayTime(int value) { 88 | for (AlgorithmThread thread : threads) { 89 | thread.setDelayTime(value + 10); 90 | } 91 | } 92 | 93 | @Override 94 | protected void fabClick() { 95 | boolean ended = true; 96 | 97 | for (AlgorithmThread thread : threads) { 98 | if (thread.isStarted()) { 99 | ended = false; 100 | break; 101 | } 102 | } 103 | 104 | if (ended) {//If you have sorted or not sorted 105 | startSort(); 106 | } else { //if it is sorting, pause or resume threads 107 | boolean isAllPause = true; 108 | for (AlgorithmThread thread : threads) { 109 | if (!thread.isPaused()) { 110 | isAllPause = false; 111 | break; 112 | } 113 | } 114 | if (isAllPause) { 115 | resumeSort(); 116 | } else { 117 | pauseSort(); 118 | } 119 | } 120 | } 121 | 122 | protected void startSort() { 123 | if (createData()) { 124 | numThreadCompleted = 0; 125 | for (AlgorithmThread thread : threads) { 126 | thread.sendMessage(AlgorithmThread.COMMAND_START_ALGORITHM); 127 | } 128 | mPlay.setImageResource(R.drawable.ic_pause_white_24dp); 129 | mPlayAnimation.show(); 130 | disableView(); 131 | } 132 | } 133 | 134 | @Override 135 | public void setupFragment(String name) { 136 | mEditNumber.setText("50"); 137 | mTimeBar.setProgress(100); 138 | 139 | threads[0] = new BubbleSortThread(mSortViews[0], getActivity()); 140 | threads[1] = new InsertionSortThread(mSortViews[1], getActivity()); 141 | threads[2] = new SelectionSortThread(mSortViews[2], getActivity()); 142 | threads[3] = new QuickSortThread(mSortViews[3], getActivity()); 143 | threads[4] = new MergeSortThread(mSortViews[4], getActivity()); 144 | threads[5] = new ShellSortThread(mSortViews[5], getActivity()); 145 | threads[6] = new CocktailShakerSortThread(mSortViews[6], getActivity()); 146 | //disable animate 147 | for (SortAlgorithmThread thread : threads) { 148 | thread.setSwapAnimateEnable(false); 149 | thread.setCompletionListener(this); 150 | 151 | } 152 | generateRandomData(); 153 | } 154 | 155 | @Override 156 | protected void generateRandomData() { 157 | //check empty length of array 158 | if (mEditNumber.getText().toString().isEmpty()) { 159 | mCountData = Integer.parseInt(mEditNumber.getHint().toString()); 160 | } else { 161 | mCountData = Integer.parseInt(mEditNumber.getText().toString()); 162 | } 163 | 164 | int[] array = ArrayUtils.createIntArray(mCountData); 165 | for (SortAlgorithmThread thread : threads) { 166 | thread.setData(array.clone()); 167 | } 168 | mEditArray.setText(ArrayUtils.arrayToString(array)); 169 | } 170 | 171 | 172 | @Override 173 | public boolean createData() { 174 | Log.d(TAG, "createData: "); 175 | 176 | //set time sleep for threads[ 177 | int delayTime = mTimeBar.getProgress(); 178 | for (AlgorithmThread thread : threads) { 179 | thread.setDelayTime(delayTime); 180 | } 181 | 182 | //check empty length of array 183 | if (mEditNumber.getText().toString().isEmpty()) { 184 | mCountData = Integer.parseInt(mEditNumber.getHint().toString()); 185 | } else { 186 | mCountData = Integer.parseInt(mEditNumber.getText().toString()); 187 | } 188 | 189 | String raw = mEditArray.getText().toString(); 190 | final String strArray[] = raw.split(Pattern.quote(",")); 191 | if (strArray.length == mCountData) { 192 | int[] array = ArrayUtils.arrayStringToInt(strArray); 193 | 194 | //If receive an error during conversion 195 | if (array[0] == -1) { 196 | return false; 197 | } 198 | for (SortAlgorithmThread thread : threads) { 199 | thread.setData(array.clone()); 200 | } 201 | return true; 202 | } else { 203 | mSlidingUpPanelLayout.setPanelState(SlidingUpPanelLayout.PanelState.EXPANDED); 204 | if (strArray.length > mCountData) { 205 | Toast.makeText(getActivity(), "Please remove " + 206 | +(strArray.length - mCountData) 207 | + " entry of array, length of array is " 208 | + strArray.length, Toast.LENGTH_LONG).show(); 209 | } else { 210 | Toast.makeText(getActivity(), "Please add " 211 | + (-strArray.length + mCountData) 212 | + " entry of array, length of array is " 213 | + strArray.length, Toast.LENGTH_LONG).show(); 214 | } 215 | 216 | return false; 217 | } 218 | } 219 | 220 | @Override 221 | protected void pauseSort() { 222 | for (AlgorithmThread thread : threads) { 223 | thread.setPaused(true); 224 | mPlay.setImageResource(R.drawable.ic_play_arrow_white_24dp); 225 | mPlayAnimation.hide(); 226 | } 227 | } 228 | 229 | @Override 230 | protected void resumeSort() { 231 | for (AlgorithmThread thread : threads) { 232 | thread.setPaused(false); 233 | } 234 | mPlay.setImageResource(R.drawable.ic_pause_white_24dp); 235 | mPlayAnimation.show(); 236 | } 237 | 238 | @Override 239 | public void onSortCompleted() { 240 | numThreadCompleted++; 241 | if (numThreadCompleted == threads.length) { 242 | if (getActivity() != null) { 243 | getActivity().runOnUiThread(new Runnable() { 244 | @Override 245 | public void run() { 246 | Toast.makeText(getActivity().getApplicationContext(), R.string.sorted, 247 | Toast.LENGTH_SHORT).show(); 248 | enableView(); 249 | mPlayAnimation.hide(); 250 | mPlay.setImageResource(R.drawable.ic_settings_backup_restore_white_24dp); 251 | } 252 | }); 253 | } 254 | } 255 | super.onSortCompleted(); 256 | 257 | } 258 | } 259 | -------------------------------------------------------------------------------- /app/src/main/java/com/duy/algorithm/algorithms/AlgorithmThread.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Naman Dwivedi 3 | * 4 | * Licensed under the GNU General Public License v3 5 | * 6 | * This is free software: you can redistribute it and/or modify it 7 | * under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 9 | * 10 | * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; 11 | * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the GNU General Public License for more details. 13 | */ 14 | 15 | package com.duy.algorithm.algorithms; 16 | 17 | import android.app.Activity; 18 | import android.os.Handler; 19 | import android.os.HandlerThread; 20 | import android.os.Message; 21 | 22 | import com.duy.algorithm.SortCompletionListener; 23 | import com.duy.algorithm.customview.LogView; 24 | 25 | import java.util.concurrent.atomic.AtomicBoolean; 26 | 27 | public class AlgorithmThread extends HandlerThread { 28 | public static final String KEY_ALGORITHM = "KEY_ALGORITHM"; 29 | public static final String COMMAND_START_ALGORITHM = "start"; 30 | private final static String TAG = "AlgorithmThread"; 31 | private final AtomicBoolean paused = new AtomicBoolean(false); 32 | private final Object pauseLock = new Object(); 33 | protected Activity activity; 34 | protected long delayTime = 50; 35 | private SortCompletionListener completionListener; 36 | private boolean started; 37 | private Handler mHandler; 38 | private LogView mLogger; 39 | 40 | public AlgorithmThread() { 41 | super(""); 42 | } 43 | 44 | public long getDelayTime() { 45 | return delayTime; 46 | } 47 | 48 | public void setDelayTime(long delayTime) { 49 | this.delayTime = delayTime; 50 | } 51 | 52 | public void sleep() { 53 | sleepFor(delayTime); 54 | } 55 | 56 | public void sleepFor(long time) { 57 | try { 58 | sleep(time); 59 | if (isPaused()) 60 | pauseExecution(); 61 | else resumeExecution(); 62 | } catch (InterruptedException e) { 63 | e.printStackTrace(); 64 | Thread.currentThread().interrupt(); 65 | } 66 | } 67 | 68 | public String getString(int resID){ 69 | return activity.getString(resID); 70 | } 71 | 72 | public void startExecution() { 73 | started = true; 74 | sleepFor(delayTime * 2); 75 | } 76 | 77 | /** 78 | * pause thread 79 | */ 80 | private void pauseExecution() { 81 | if (paused.get()) { 82 | synchronized (getPauseLock()) { 83 | if (paused.get()) { 84 | try { 85 | getPauseLock().wait(); 86 | } catch (InterruptedException ignored) { 87 | } 88 | } 89 | } 90 | } 91 | } 92 | 93 | /** 94 | * resume thread 95 | */ 96 | private void resumeExecution() { 97 | synchronized (pauseLock) { 98 | pauseLock.notifyAll(); 99 | } 100 | } 101 | 102 | private Object getPauseLock() { 103 | return pauseLock; 104 | } 105 | 106 | public boolean isPaused() { 107 | return paused.get(); 108 | } 109 | 110 | public void setPaused(boolean b) { 111 | paused.set(b); 112 | if (!b) { 113 | synchronized (getPauseLock()) { 114 | getPauseLock().notify(); 115 | } 116 | } 117 | } 118 | 119 | public boolean isStarted() { 120 | return started; 121 | } 122 | 123 | public void setStarted(boolean started) { 124 | this.started = started; 125 | } 126 | 127 | public void showLog(final String log) { 128 | activity.runOnUiThread(new Runnable() { 129 | @Override 130 | public void run() { 131 | if (mLogger != null) 132 | mLogger.addLog(log); 133 | } 134 | }); 135 | } 136 | 137 | public void showLog(final String message, final int[] array) { 138 | activity.runOnUiThread(new Runnable() { 139 | @Override 140 | public void run() { 141 | if (mLogger != null) 142 | mLogger.addLog(message, array.clone()); 143 | 144 | } 145 | }); 146 | } 147 | 148 | public void setCompletionListener(SortCompletionListener completionListener) { 149 | this.completionListener = completionListener; 150 | } 151 | 152 | public void prepareHandler(final IDataHandler dataHandler) { 153 | mHandler = new Handler(getLooper(), new Handler.Callback() { 154 | @Override 155 | public boolean handleMessage(Message msg) { 156 | if (msg.obj instanceof String) { 157 | dataHandler.onMessageReceived((String) msg.obj); 158 | } else { 159 | dataHandler.onDataReceived(msg.obj); 160 | } 161 | return true; 162 | } 163 | }); 164 | 165 | } 166 | 167 | /** 168 | * send data 169 | * 170 | * @param data 171 | */ 172 | public void sendData(Object data) { 173 | mHandler.obtainMessage(1, data).sendToTarget(); 174 | } 175 | 176 | /** 177 | * send command 178 | * 179 | * @param message 180 | */ 181 | public void sendMessage(String message) { 182 | mHandler.obtainMessage(1, message).sendToTarget(); 183 | } 184 | 185 | /** 186 | * completed sort 187 | */ 188 | public void onCompleted() { 189 | if (completionListener != null) completionListener.onSortCompleted(); 190 | started = false; 191 | } 192 | 193 | public void setLogger(LogView mLogger) { 194 | this.mLogger = mLogger; 195 | } 196 | 197 | public static final class ALGORITHM_NAME { 198 | public static final String BUBBLE_SORT = "BUBBLE_SORT"; 199 | public static final String INSERTION_SORT = "INSERTION_SORT"; 200 | public static final String SELECTION_SORT = "SELECTION_SORT"; 201 | public static final String QUICK_SORT = "QUICK_SORT"; 202 | public static final String SHELL_SORT = "SHELL_SORT"; 203 | public static final String MERGE_SORT = "MERGE_SORT"; 204 | public static final String COCKTAIL_SORT = "COCKTAIL_SORT"; 205 | public static final String BOGO_SORT = "BOGO_SORT"; 206 | public static final String COUNTING_SORT = "COUNTING_SORT"; 207 | } 208 | } 209 | -------------------------------------------------------------------------------- /app/src/main/java/com/duy/algorithm/algorithms/IDataHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Naman Dwivedi 3 | * 4 | * Licensed under the GNU General Public License v3 5 | * 6 | * This is free software: you can redistribute it and/or modify it 7 | * under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 9 | * 10 | * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; 11 | * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the GNU General Public License for more details. 13 | */ 14 | 15 | package com.duy.algorithm.algorithms; 16 | 17 | public interface IDataHandler { 18 | 19 | void onDataReceived(Object data); 20 | 21 | void onMessageReceived(String message); 22 | } 23 | 24 | -------------------------------------------------------------------------------- /app/src/main/java/com/duy/algorithm/algorithms/SortAlgorithmThread.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Naman Dwivedi 3 | * 4 | * Licensed under the GNU General Public License v3 5 | * 6 | * This is free software: you can redistribute it and/or modify it 7 | * under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 9 | * 10 | * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; 11 | * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the GNU General Public License for more details. 13 | */ 14 | 15 | package com.duy.algorithm.algorithms; 16 | 17 | 18 | import android.support.annotation.UiThread; 19 | 20 | import com.duy.algorithm.customview.SortView; 21 | 22 | public class SortAlgorithmThread extends AlgorithmThread implements IDataHandler { 23 | 24 | public static final String TAG = SortAlgorithmThread.class.getSimpleName(); 25 | public SortView mSortView; 26 | private boolean isPrepared = false; 27 | private boolean swapAnimateEnable = true; 28 | 29 | public void prepare() { 30 | if (isPrepared) return; 31 | start(); 32 | prepareHandler(this); 33 | isPrepared = true; 34 | } 35 | 36 | /** 37 | * set array data for view 38 | * 39 | * @param array 40 | */ 41 | @UiThread 42 | public void setData(final int[] array) { 43 | prepare(); 44 | activity.runOnUiThread(new Runnable() { 45 | @Override 46 | public void run() { 47 | mSortView.setCompletePosition(-1); 48 | mSortView.setArray(array); 49 | mSortView.setTime(0); 50 | mSortView.invalidate(); 51 | } 52 | }); 53 | sendData(array); 54 | } 55 | 56 | /** 57 | * highlight swap 58 | */ 59 | @UiThread 60 | public void onSwapping(final int one, final int two) { 61 | 62 | if (swapAnimateEnable) { //some cases without effect 63 | mSortView.setSwapPosition(one, two, false); 64 | //xA always smaller xB 65 | int delta = mSortView.getDelta(); 66 | long timeSleep; 67 | if (delta == 0) { 68 | timeSleep = 1; 69 | } else { 70 | timeSleep = (long) (delayTime * 1.5 / delta); 71 | } 72 | while (delta >= 0) { 73 | activity.runOnUiThread(new Runnable() { 74 | @Override 75 | public void run() { 76 | mSortView.incPositionSwap(2); 77 | } 78 | }); 79 | sleepFor(timeSleep); 80 | delta -= 2; 81 | } 82 | } else { 83 | activity.runOnUiThread(new Runnable() { 84 | @Override 85 | public void run() { 86 | mSortView.setSwapPosition(one, two); 87 | } 88 | }); 89 | sleep(); 90 | } 91 | } 92 | 93 | /** 94 | * highlight swap 95 | */ 96 | @UiThread 97 | public void onSwapped() { 98 | activity.runOnUiThread(new Runnable() { 99 | @Override 100 | public void run() { 101 | mSortView.setSwapPosition(-1, -1); 102 | } 103 | }); 104 | sleep(); 105 | } 106 | 107 | /** 108 | * highlight swap 109 | */ 110 | @UiThread 111 | public void onSwapped(boolean b) { 112 | activity.runOnUiThread(new Runnable() { 113 | @Override 114 | public void run() { 115 | mSortView.setSwapPosition(-1, -1); 116 | } 117 | }); 118 | } 119 | 120 | /** 121 | * highlight trace 122 | * 123 | * @param position - position for trace 124 | */ 125 | public void onTrace(final int position) { 126 | activity.runOnUiThread(new Runnable() { 127 | @Override 128 | public void run() { 129 | mSortView.setTracePosition(position); 130 | } 131 | }); 132 | } 133 | 134 | /** 135 | * highlight target 136 | * 137 | * @param position-position for target 138 | */ 139 | public void onTarget(final int position) { 140 | activity.runOnUiThread(new Runnable() { 141 | @Override 142 | public void run() { 143 | mSortView.setTargetPosition(position); 144 | } 145 | }); 146 | } 147 | 148 | @Override 149 | public void onDataReceived(Object data) { 150 | 151 | } 152 | 153 | @Override 154 | public void onMessageReceived(String message) { 155 | 156 | } 157 | 158 | /** 159 | * array is sorted 160 | */ 161 | @Override 162 | public void onCompleted() { 163 | finishSorting(); 164 | super.onCompleted(); 165 | } 166 | 167 | 168 | private void finishSorting() { 169 | for (int i = 0; i < mSortView.getSizeArray(); i++) { 170 | mSortView.setCompletePosition(i); 171 | activity.runOnUiThread(new Runnable() { 172 | @Override 173 | public void run() { 174 | mSortView.invalidate(); 175 | } 176 | }); 177 | sleepFor(delayTime / 3); 178 | } 179 | 180 | activity.runOnUiThread(new Runnable() { 181 | @Override 182 | public void run() { 183 | // mSortView.setCompletePosition(-1); 184 | mSortView.setTracePosition(-1); 185 | mSortView.invalidate(); 186 | } 187 | }); 188 | } 189 | 190 | @Override 191 | public void sleep() { 192 | activity.runOnUiThread(new Runnable() { 193 | @Override 194 | public void run() { 195 | // mSortView.setCompletePosition(-1); 196 | mSortView.addTimeUnit(1); 197 | mSortView.invalidate(); 198 | } 199 | }); 200 | super.sleep(); 201 | } 202 | 203 | public boolean isSwapAnimateEnable() { 204 | return swapAnimateEnable; 205 | } 206 | 207 | public void setSwapAnimateEnable(boolean swapAnimateEnable) { 208 | this.swapAnimateEnable = swapAnimateEnable; 209 | } 210 | } 211 | -------------------------------------------------------------------------------- /app/src/main/java/com/duy/algorithm/algorithms/algo/BogoSortThread.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Naman Dwivedi 3 | * 4 | * Licensed under the GNU General Public License v3 5 | * 6 | * This is free software: you can redistribute it and/or modify it 7 | * under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 9 | * 10 | * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; 11 | * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the GNU General Public License for more details. 13 | */ 14 | 15 | package com.duy.algorithm.algorithms.algo; 16 | 17 | 18 | import android.app.Activity; 19 | 20 | import com.duy.algorithm.R; 21 | import com.duy.algorithm.algorithms.AlgorithmThread; 22 | import com.duy.algorithm.algorithms.SortAlgorithmThread; 23 | import com.duy.algorithm.customview.SortView; 24 | import com.duy.algorithm.utils.ArrayUtils; 25 | 26 | public class BogoSortThread extends SortAlgorithmThread { 27 | 28 | int[] array; 29 | 30 | public BogoSortThread(SortView sortView, Activity activity) { 31 | this.mSortView = sortView; 32 | this.activity = activity; 33 | } 34 | 35 | 36 | public boolean bogoIsSorted(int[] arr) { 37 | for (int i = 1; i < arr.length; i++) 38 | if (arr[i] < arr[i - 1]) 39 | return false; 40 | return true; 41 | } 42 | 43 | public void sort() { 44 | showLog("Original array - ", array); 45 | 46 | while (!bogoIsSorted(array)) { 47 | for (int i = 0; i < array.length; i++) { 48 | showLog("Doing iteration - " + i); 49 | 50 | 51 | int j = (int) (Math.random() * array.length); 52 | onSwapping(i, j); 53 | sleep(); 54 | showLog("Swapping " + array[i] + " and " + array[j]); 55 | 56 | ArrayUtils.swap(array, i, j); 57 | 58 | onSwapping(i, j); 59 | sleep(); 60 | } 61 | //sleep(100.0); 62 | } 63 | showLog(getString(R.string.arr_sorted), array); 64 | onCompleted(); 65 | } 66 | 67 | 68 | @Override 69 | public void onDataReceived(Object data) { 70 | super.onDataReceived(data); 71 | this.array = (int[]) data; 72 | } 73 | 74 | @Override 75 | public void onMessageReceived(String message) { 76 | super.onMessageReceived(message); 77 | if (message.equals(AlgorithmThread.COMMAND_START_ALGORITHM)) { 78 | startExecution(); 79 | sort(); 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /app/src/main/java/com/duy/algorithm/algorithms/algo/BubbleSortThread.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Naman Dwivedi 3 | * 4 | * Licensed under the GNU General Public License v3 5 | * 6 | * This is free software: you can redistribute it and/or modify it 7 | * under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 9 | * 10 | * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; 11 | * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the GNU General Public License for more details. 13 | */ 14 | 15 | package com.duy.algorithm.algorithms.algo; 16 | 17 | 18 | import android.app.Activity; 19 | 20 | import com.duy.algorithm.R; 21 | import com.duy.algorithm.algorithms.AlgorithmThread; 22 | import com.duy.algorithm.algorithms.SortAlgorithmThread; 23 | import com.duy.algorithm.customview.SortView; 24 | 25 | public class BubbleSortThread extends SortAlgorithmThread { 26 | 27 | int[] array; 28 | 29 | public BubbleSortThread(SortView sortView, Activity activity) { 30 | this.mSortView = sortView; 31 | this.activity = activity; 32 | } 33 | 34 | public void sort() { 35 | showLog(getString(R.string.original_arr), array); 36 | 37 | for (int i = array.length - 1; i >= 0; i--) { 38 | // showLog("i = " + i); 39 | boolean swapped = false; 40 | for (int j = 0; j < i; j++) { 41 | //handle trace 42 | onTrace(j); 43 | sleep(); 44 | 45 | if (array[j] > array[j + 1]) { 46 | //swapping 47 | onSwapping(j, j + 1); 48 | 49 | showLog("Swapping a[" + i + "]=" + array[j] + " and a[" + j + "]=" + array[j + 1]); 50 | int temp = array[j]; 51 | array[j] = array[j + 1]; 52 | array[j + 1] = temp; 53 | 54 | //swapped 55 | onSwapped(); 56 | swapped = true; 57 | } 58 | } 59 | if (!swapped) { 60 | break; 61 | } 62 | } 63 | showLog(getString(R.string.arr_sorted), array); 64 | 65 | onCompleted(); 66 | } 67 | 68 | @Override 69 | public void run() { 70 | super.run(); 71 | } 72 | 73 | 74 | @Override 75 | public void onDataReceived(Object data) { 76 | super.onDataReceived(data); 77 | this.array = (int[]) data; 78 | } 79 | 80 | @Override 81 | public void onMessageReceived(String message) { 82 | super.onMessageReceived(message); 83 | if (message.equals(AlgorithmThread.COMMAND_START_ALGORITHM)) { 84 | startExecution(); 85 | sort(); 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /app/src/main/java/com/duy/algorithm/algorithms/algo/CocktailShakerSortThread.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Naman Dwivedi 3 | * 4 | * Licensed under the GNU General Public License v3 5 | * 6 | * This is free software: you can redistribute it and/or modify it 7 | * under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 9 | * 10 | * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; 11 | * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the GNU General Public License for more details. 13 | */ 14 | 15 | package com.duy.algorithm.algorithms.algo; 16 | 17 | 18 | import android.app.Activity; 19 | 20 | import com.duy.algorithm.R; 21 | import com.duy.algorithm.algorithms.AlgorithmThread; 22 | import com.duy.algorithm.algorithms.SortAlgorithmThread; 23 | import com.duy.algorithm.customview.SortView; 24 | import com.duy.algorithm.utils.ArrayUtils; 25 | 26 | public class CocktailShakerSortThread extends SortAlgorithmThread { 27 | 28 | int[] array; 29 | 30 | public CocktailShakerSortThread(SortView sortView, Activity activity) { 31 | this.mSortView = sortView; 32 | this.activity = activity; 33 | } 34 | 35 | 36 | public void cocktailShakerSort() { 37 | int i = 0; 38 | while (i < array.length / 2) { 39 | for (int j = i; j < array.length - i - 1; j++) { 40 | showLog("Doing iteration - " + i); 41 | onTrace(j); 42 | sleep(); 43 | 44 | if (array[j] > array[j + 1]) { 45 | 46 | showLog("Swapping " + array[j] + " and " + array[j + 1]); 47 | onSwapping(j, j + 1); 48 | 49 | ArrayUtils.swap(array, j, j + 1); 50 | 51 | onSwapped(); 52 | } 53 | } 54 | for (int j = array.length - i - 1; j > i; j--) { 55 | showLog("Doing iteration - " + i); 56 | onTrace(j); 57 | sleep(); 58 | 59 | if (array[j] < array[j - 1]) { 60 | 61 | onSwapping(j, j - 1); 62 | showLog("Swapping " + array[j] + " and " + array[j - 1]); 63 | 64 | ArrayUtils.swap(array, j, j - 1); 65 | 66 | onSwapped(); 67 | } 68 | } 69 | i++; 70 | } 71 | } 72 | 73 | public void sort() { 74 | showLog(getString(R.string.original_arr), array); 75 | 76 | cocktailShakerSort(); 77 | showLog(getString(R.string.arr_sorted), array); 78 | 79 | onCompleted(); 80 | } 81 | 82 | 83 | @Override 84 | public void onDataReceived(Object data) { 85 | super.onDataReceived(data); 86 | this.array = (int[]) data; 87 | } 88 | 89 | @Override 90 | public void onMessageReceived(String message) { 91 | super.onMessageReceived(message); 92 | if (message.equals(AlgorithmThread.COMMAND_START_ALGORITHM)) { 93 | startExecution(); 94 | sort(); 95 | } 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /app/src/main/java/com/duy/algorithm/algorithms/algo/CountingSortThread.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Naman Dwivedi 3 | * 4 | * Licensed under the GNU General Public License v3 5 | * 6 | * This is free software: you can redistribute it and/or modify it 7 | * under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 9 | * 10 | * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; 11 | * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the GNU General Public License for more details. 13 | */ 14 | 15 | package com.duy.algorithm.algorithms.algo; 16 | 17 | 18 | import android.app.Activity; 19 | 20 | import com.duy.algorithm.R; 21 | import com.duy.algorithm.algorithms.AlgorithmThread; 22 | import com.duy.algorithm.utils.ArrayUtils; 23 | import com.duy.algorithm.algorithms.SortAlgorithmThread; 24 | import com.duy.algorithm.customview.SortView; 25 | 26 | public class CountingSortThread extends SortAlgorithmThread { 27 | 28 | int[] array; 29 | 30 | public CountingSortThread(SortView sortView, Activity activity) { 31 | this.mSortView = sortView; 32 | this.activity = activity; 33 | } 34 | 35 | 36 | public void sort() { 37 | showLog(getString(R.string.original_arr), array); 38 | 39 | 40 | int max = ArrayUtils.findMax(array); 41 | int[] counts = new int[max + 1]; 42 | for (int i = 0; i < array.length; i++) { 43 | showLog("Doing iteration - " + i); 44 | onTrace(i); 45 | sleep(); 46 | 47 | counts[array[i]]++; 48 | } 49 | int x = 0; 50 | for (int i = 0; i < array.length; i++) { 51 | showLog("Doing iteration - " + i); 52 | onTrace(i); 53 | sleep(); 54 | 55 | if (counts[x] == 0) 56 | x++; 57 | array[i] = x; 58 | counts[x]--; 59 | } 60 | 61 | showLog(getString(R.string.arr_sorted), array); 62 | 63 | onCompleted(); 64 | } 65 | 66 | @Override 67 | public void onDataReceived(Object data) { 68 | super.onDataReceived(data); 69 | this.array = (int[]) data; 70 | } 71 | 72 | @Override 73 | public void onMessageReceived(String message) { 74 | super.onMessageReceived(message); 75 | if (message.equals(AlgorithmThread.COMMAND_START_ALGORITHM)) { 76 | startExecution(); 77 | sort(); 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /app/src/main/java/com/duy/algorithm/algorithms/algo/InsertionSortThread.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Naman Dwivedi 3 | * 4 | * Licensed under the GNU General Public License v3 5 | * 6 | * This is free software: you can redistribute it and/or modify it 7 | * under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 9 | * 10 | * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; 11 | * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the GNU General Public License for more details. 13 | */ 14 | 15 | package com.duy.algorithm.algorithms.algo; 16 | 17 | import android.app.Activity; 18 | 19 | import com.duy.algorithm.R; 20 | import com.duy.algorithm.algorithms.AlgorithmThread; 21 | import com.duy.algorithm.algorithms.SortAlgorithmThread; 22 | import com.duy.algorithm.customview.SortView; 23 | import com.duy.algorithm.utils.ArrayUtils; 24 | 25 | public class InsertionSortThread extends SortAlgorithmThread { 26 | int[] array; 27 | 28 | public InsertionSortThread(SortView sortView, Activity activity) { 29 | this.mSortView = sortView; 30 | this.activity = activity; 31 | } 32 | 33 | public void sort() { 34 | showLog(getString(R.string.original_arr), array); 35 | 36 | 37 | int pos; 38 | for (int i = 1; i < array.length; i++) { 39 | pos = i; 40 | onTrace(i); 41 | sleep(); 42 | 43 | while (pos > 0 && array[pos] < array[pos - 1]) { 44 | onSwapping(pos, pos - 1);//swapping 45 | 46 | showLog("Swapping a[" + pos + "]=" + array[pos] 47 | + " and a[" + (pos - 1) + "]=" + array[pos - 1]); 48 | ArrayUtils.swap(array, pos, pos - 1); 49 | 50 | onSwapped(); 51 | pos--; 52 | } 53 | } 54 | showLog(getString(R.string.arr_sorted), array); 55 | 56 | onCompleted(); 57 | } 58 | 59 | 60 | @Override 61 | public void run() { 62 | super.run(); 63 | } 64 | 65 | 66 | @Override 67 | public void onDataReceived(Object data) { 68 | super.onDataReceived(data); 69 | this.array = (int[]) data; 70 | } 71 | 72 | @Override 73 | public void onMessageReceived(String message) { 74 | super.onMessageReceived(message); 75 | if (message.equals(AlgorithmThread.COMMAND_START_ALGORITHM)) { 76 | startExecution(); 77 | sort(); 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /app/src/main/java/com/duy/algorithm/algorithms/algo/MergeSortThread.java: -------------------------------------------------------------------------------- 1 | package com.duy.algorithm.algorithms.algo; 2 | 3 | import android.app.Activity; 4 | 5 | import com.duy.algorithm.R; 6 | import com.duy.algorithm.algorithms.AlgorithmThread; 7 | import com.duy.algorithm.algorithms.SortAlgorithmThread; 8 | import com.duy.algorithm.customview.SortView; 9 | 10 | public class MergeSortThread extends SortAlgorithmThread { 11 | 12 | private int[] array; 13 | private int[] aux; 14 | 15 | public MergeSortThread(SortView sortView, Activity activity) { 16 | this.mSortView = sortView; 17 | this.activity = activity; 18 | } 19 | 20 | private void merge(int lo, int mid, int hi) { 21 | int l = lo; 22 | int r = mid + 1; 23 | 24 | System.arraycopy(array, lo, aux, lo, hi + 1 - lo); 25 | 26 | for (int k = l; k <= hi; k++) { 27 | onTrace(k); 28 | sleep(); 29 | int rec = 0; 30 | if (l > mid) { 31 | rec = r; 32 | array[k] = aux[r++]; 33 | } else if (r > hi) { 34 | rec = l; 35 | array[k] = aux[l++]; 36 | } else if (aux[r] < aux[l]) { 37 | rec = r; 38 | array[k] = aux[r++]; 39 | } else { 40 | rec = l; 41 | array[k] = aux[l++]; 42 | } 43 | 44 | // onSwapping(rec, k); 45 | // sleep(); 46 | } 47 | 48 | 49 | } 50 | 51 | private void sort(int lo, int hi) { 52 | 53 | if (hi <= lo) return; 54 | int mid = lo + (hi - lo) / 2; 55 | sort(lo, mid); // 将左半部分排序 56 | sort(mid + 1, hi); // 将又半部分排序 57 | merge(lo, mid, hi); // 归并结果 58 | 59 | } 60 | 61 | 62 | public void sort() { 63 | showLog(getString(R.string.original_arr), array); 64 | 65 | aux = new int[array.length]; 66 | sort(0, array.length - 1); 67 | showLog(getString(R.string.arr_sorted), array); 68 | 69 | onCompleted(); 70 | } 71 | 72 | @Override 73 | public void run() { 74 | super.run(); 75 | } 76 | 77 | 78 | @Override 79 | public void onDataReceived(Object data) { 80 | super.onDataReceived(data); 81 | this.array = (int[]) data; 82 | } 83 | 84 | @Override 85 | public void onMessageReceived(String message) { 86 | super.onMessageReceived(message); 87 | if (message.equals(AlgorithmThread.COMMAND_START_ALGORITHM)) { 88 | startExecution(); 89 | sort(); 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /app/src/main/java/com/duy/algorithm/algorithms/algo/QuickSortThread.java: -------------------------------------------------------------------------------- 1 | package com.duy.algorithm.algorithms.algo; 2 | 3 | import android.app.Activity; 4 | 5 | import com.duy.algorithm.R; 6 | import com.duy.algorithm.algorithms.AlgorithmThread; 7 | import com.duy.algorithm.algorithms.SortAlgorithmThread; 8 | import com.duy.algorithm.customview.SortView; 9 | import com.duy.algorithm.utils.ArrayUtils; 10 | 11 | public class QuickSortThread extends SortAlgorithmThread { 12 | public static final String TAG = "QuickSort"; 13 | private int[] array; 14 | 15 | public QuickSortThread(SortView sortView, Activity activity) { 16 | this.mSortView = sortView; 17 | this.activity = activity; 18 | } 19 | 20 | private void sort(int l, int r) { 21 | int i = l; 22 | int j = r; 23 | int key = array[(l + r) / 2]; 24 | while (i <= j) { 25 | while (array[i] < key) { 26 | onTrace(i); 27 | sleep(); 28 | i++; 29 | } 30 | while (array[j] > key) { 31 | onTrace(j); 32 | sleep(); 33 | j--; 34 | } 35 | if (i <= j) { 36 | if (array[i] > array[j]) { 37 | onSwapping(i, j); 38 | 39 | ArrayUtils.swap(array, i, j); 40 | 41 | //swapped, show it 42 | onSwapped(); 43 | } 44 | i++; 45 | j--; 46 | } 47 | } 48 | if (i < r) sort(i, r); 49 | if (l < j) sort(l, j); 50 | } 51 | 52 | public void sort() { 53 | showLog(getString(R.string.original_arr), array); 54 | 55 | sort(0, array.length - 1); 56 | showLog(getString(R.string.arr_sorted), array); 57 | 58 | onCompleted(); 59 | } 60 | 61 | @Override 62 | public void run() { 63 | super.run(); 64 | } 65 | 66 | 67 | @Override 68 | public void onDataReceived(Object data) { 69 | super.onDataReceived(data); 70 | this.array = (int[]) data; 71 | } 72 | 73 | @Override 74 | public void onMessageReceived(String message) { 75 | super.onMessageReceived(message); 76 | if (message.equals(AlgorithmThread.COMMAND_START_ALGORITHM)) { 77 | startExecution(); 78 | sort(); 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /app/src/main/java/com/duy/algorithm/algorithms/algo/SelectionSortThread.java: -------------------------------------------------------------------------------- 1 | package com.duy.algorithm.algorithms.algo; 2 | 3 | import android.app.Activity; 4 | 5 | import com.duy.algorithm.R; 6 | import com.duy.algorithm.algorithms.AlgorithmThread; 7 | import com.duy.algorithm.algorithms.SortAlgorithmThread; 8 | import com.duy.algorithm.customview.SortView; 9 | 10 | /** 11 | * Created by amit on 21/11/16. 12 | */ 13 | 14 | public class SelectionSortThread extends SortAlgorithmThread { 15 | 16 | int[] array; 17 | 18 | public SelectionSortThread(SortView sortView, Activity activity) { 19 | this.mSortView = sortView; 20 | this.activity = activity; 21 | } 22 | 23 | public void sort() { 24 | showLog(getString(R.string.original_arr), array); 25 | 26 | 27 | int n = array.length; 28 | for (int i = 0; i < n - 1; i++) { 29 | int min_idx = i; 30 | onTarget(i); 31 | sleep(); 32 | 33 | for (int j = i + 1; j < n; j++) { 34 | onTrace(j); 35 | sleep(); 36 | 37 | if (array[j] < array[min_idx]) { 38 | min_idx = j; 39 | onTarget(j); 40 | } 41 | } 42 | 43 | //swapping 44 | onTarget(min_idx); 45 | onSwapping(min_idx, i); 46 | 47 | int temp = array[min_idx]; 48 | array[min_idx] = array[i]; 49 | array[i] = temp; 50 | 51 | showLog("Swapping " + array[i] + " and " + temp); 52 | 53 | //swapped 54 | onTarget(i); 55 | onSwapped(); 56 | 57 | 58 | } 59 | showLog(getString(R.string.arr_sorted), array); 60 | 61 | onCompleted(); 62 | } 63 | 64 | @Override 65 | public void run() { 66 | super.run(); 67 | } 68 | 69 | 70 | @Override 71 | public void onDataReceived(Object data) { 72 | super.onDataReceived(data); 73 | this.array = (int[]) data; 74 | } 75 | 76 | @Override 77 | public void onMessageReceived(String message) { 78 | super.onMessageReceived(message); 79 | if (message.equals(AlgorithmThread.COMMAND_START_ALGORITHM)) { 80 | startExecution(); 81 | sort(); 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /app/src/main/java/com/duy/algorithm/algorithms/algo/ShellSortThread.java: -------------------------------------------------------------------------------- 1 | package com.duy.algorithm.algorithms.algo; 2 | 3 | 4 | import android.app.Activity; 5 | 6 | import com.duy.algorithm.R; 7 | import com.duy.algorithm.algorithms.AlgorithmThread; 8 | import com.duy.algorithm.algorithms.SortAlgorithmThread; 9 | import com.duy.algorithm.customview.SortView; 10 | 11 | public class ShellSortThread extends SortAlgorithmThread { 12 | 13 | int[] array; 14 | 15 | public ShellSortThread(SortView sortView, Activity activity) { 16 | this.mSortView = sortView; 17 | this.activity = activity; 18 | } 19 | 20 | public void sort() { 21 | showLog(getString(R.string.original_arr), array); 22 | 23 | 24 | int h = 1; 25 | while (h < array.length) h = 3 * h + 1; 26 | while (h > 0) { 27 | h = h / 3; 28 | for (int k = 0; k < h; k++) { 29 | for (int i = h + k; i < array.length; i += h) { 30 | onTrace(i); 31 | sleep(); 32 | 33 | int key = array[i]; 34 | int j = i - h; 35 | 36 | while (j >= 0 && array[j] > key) { 37 | onSwapping(j, j + h); 38 | sleep(); 39 | 40 | array[j + h] = array[j]; 41 | onSwapped(false); 42 | j -= h; 43 | } 44 | array[j + h] = key; 45 | //-> invariant: array[0,h,2*h..j] is sorted 46 | } 47 | } 48 | //->invariant: each h-sub-array is sorted 49 | } 50 | 51 | showLog(getString(R.string.arr_sorted), array); 52 | 53 | onCompleted(); 54 | 55 | } 56 | 57 | 58 | @Override 59 | public void run() { 60 | super.run(); 61 | } 62 | 63 | 64 | @Override 65 | public void onDataReceived(Object data) { 66 | super.onDataReceived(data); 67 | this.array = (int[]) data; 68 | } 69 | 70 | @Override 71 | public void onMessageReceived(String message) { 72 | super.onMessageReceived(message); 73 | if (message.equals(AlgorithmThread.COMMAND_START_ALGORITHM)) { 74 | startExecution(); 75 | sort(); 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /app/src/main/java/com/duy/algorithm/customview/EditTextInputArray.java: -------------------------------------------------------------------------------- 1 | package com.duy.algorithm.customview; 2 | 3 | import android.content.Context; 4 | import android.support.v7.widget.AppCompatEditText; 5 | import android.text.InputType; 6 | import android.text.method.NumberKeyListener; 7 | import android.util.AttributeSet; 8 | 9 | /** 10 | * Created by DUy on 03-Feb-17. 11 | */ 12 | 13 | public class EditTextInputArray extends AppCompatEditText { 14 | 15 | public EditTextInputArray(Context context) { 16 | super(context); 17 | init(context); 18 | } 19 | 20 | public EditTextInputArray(Context context, AttributeSet attrs) { 21 | super(context, attrs); 22 | init(context); 23 | 24 | } 25 | 26 | public EditTextInputArray(Context context, AttributeSet attrs, int defStyleAttr) { 27 | super(context, attrs, defStyleAttr); 28 | init(context); 29 | 30 | } 31 | 32 | private void init(Context context) { 33 | setKeyListener(new NumberKeyListener() { 34 | @Override 35 | protected char[] getAcceptedChars() { 36 | return "1234567890,".toCharArray(); 37 | } 38 | 39 | @Override 40 | public int getInputType() { 41 | return InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS; 42 | } 43 | }); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /app/src/main/java/com/duy/algorithm/customview/LogView.java: -------------------------------------------------------------------------------- 1 | package com.duy.algorithm.customview; 2 | 3 | import android.content.Context; 4 | import android.support.annotation.Nullable; 5 | import android.support.v7.widget.LinearLayoutManager; 6 | import android.support.v7.widget.RecyclerView; 7 | import android.util.AttributeSet; 8 | import android.view.LayoutInflater; 9 | import android.view.View; 10 | import android.view.ViewGroup; 11 | import android.widget.TextView; 12 | 13 | import com.duy.algorithm.R; 14 | 15 | import java.util.ArrayList; 16 | 17 | /** 18 | * Created by DUy on 04-Feb-17. 19 | */ 20 | 21 | public class LogView extends RecyclerView { 22 | private LogAdapter mLogAdapter; 23 | private View mEmptyView; 24 | 25 | public LogView(Context context) { 26 | super(context); 27 | setup(context); 28 | } 29 | 30 | public LogView(Context context, @Nullable AttributeSet attrs) { 31 | super(context, attrs); 32 | setup(context); 33 | 34 | } 35 | 36 | public LogView(Context context, @Nullable AttributeSet attrs, int defStyle) { 37 | super(context, attrs, defStyle); 38 | setup(context); 39 | 40 | } 41 | 42 | private void setup(Context context) { 43 | if (!isInEditMode()) { 44 | LinearLayoutManager linearLayoutManager = new LinearLayoutManager(context); 45 | linearLayoutManager.setStackFromEnd(true); 46 | setLayoutManager(linearLayoutManager); 47 | mLogAdapter = new LogView.LogAdapter(context); 48 | setAdapter(mLogAdapter); 49 | } 50 | } 51 | 52 | public void addLog(String log) { 53 | mLogAdapter.addLog(log); 54 | if (mEmptyView != null) mEmptyView.setVisibility(GONE); 55 | scrollToPosition(mLogAdapter.getItemCount() - 1); 56 | } 57 | 58 | public void addLog(String log, int[] array) { 59 | if (mEmptyView != null) mEmptyView.setVisibility(GONE); 60 | 61 | String str = "["; 62 | for (int i = 0; i < array.length - 1; i++) { 63 | str += array[i]; 64 | str += ", "; 65 | } 66 | if (array.length > 0) { 67 | str += array[array.length - 1]; 68 | str += "]"; 69 | } 70 | mLogAdapter.addLog(log + " " + str); 71 | scrollToPosition(mLogAdapter.getItemCount() - 1); 72 | 73 | } 74 | 75 | public void setmEmptyView(View mEmptyView) { 76 | this.mEmptyView = mEmptyView; 77 | } 78 | 79 | public static class LogAdapter extends Adapter { 80 | private ArrayList mLogs = new ArrayList<>(); 81 | private Context context; 82 | 83 | public LogAdapter(Context context) { 84 | this.context = context; 85 | } 86 | 87 | 88 | @Override 89 | public LogHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) { 90 | View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.log_item, viewGroup, false); 91 | return new LogHolder(v); 92 | } 93 | 94 | @Override 95 | public void onBindViewHolder(LogHolder itemHolder, int i) { 96 | itemHolder.txtLog.setText(mLogs.get(i)); 97 | } 98 | 99 | @Override 100 | public int getItemCount() { 101 | return (null != mLogs ? mLogs.size() : 0); 102 | } 103 | 104 | public void addLog(String log) { 105 | mLogs.add(log); 106 | notifyItemInserted(getItemCount() - 1); 107 | } 108 | 109 | public void clearLog() { 110 | notifyItemRangeRemoved(0, getItemCount()); 111 | mLogs.clear(); 112 | } 113 | 114 | public static class LogHolder extends ViewHolder { 115 | 116 | TextView txtLog; 117 | 118 | public LogHolder(View view) { 119 | super(view); 120 | txtLog = (TextView) view.findViewById(R.id.txt_log); 121 | } 122 | 123 | } 124 | 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /app/src/main/java/com/duy/algorithm/customview/SortView.java: -------------------------------------------------------------------------------- 1 | package com.duy.algorithm.customview; 2 | 3 | import android.content.Context; 4 | import android.content.res.TypedArray; 5 | import android.graphics.Canvas; 6 | import android.graphics.Color; 7 | import android.graphics.Paint; 8 | import android.graphics.Path; 9 | import android.graphics.Rect; 10 | import android.os.Handler; 11 | import android.support.annotation.UiThread; 12 | import android.util.AttributeSet; 13 | import android.util.Log; 14 | import android.view.View; 15 | 16 | import com.duy.algorithm.R; 17 | 18 | /** 19 | * create by Mr.Duy on 02-Feb-17 20 | */ 21 | public class SortView extends View { 22 | 23 | public static final String TAG = "SortView"; 24 | private static final String NO_DATA = "No Data!"; 25 | private float[][] tmp = new float[2][2]; //save coordinate of two index bar 26 | private int[] array; //input data 27 | private Paint mPaint; 28 | private boolean isDrawing = false; 29 | private String name = ""; 30 | private Context context; 31 | private long mTime = 0; 32 | private int swapAPosition = -1; 33 | private int swapBPosition = -1; 34 | private int tracePosition = -1; 35 | private int targetPosition = -1; 36 | private int completePosition = -1; 37 | private int barColor = Color.WHITE; 38 | private int targetColor = Color.GREEN; 39 | private int swapAColor = Color.RED; 40 | private int swapBColor = Color.MAGENTA; 41 | private int traceColor = Color.BLUE; 42 | private int quadColor = Color.GREEN; 43 | private int completeColor = Color.GREEN; 44 | private int textInfoColor = Color.RED; 45 | private Handler handler = new Handler(); 46 | public float xA = 0; 47 | public float xB = 0; 48 | private float yA = 0; 49 | private float yB = 0; 50 | private int delta = 0; 51 | 52 | public SortView(Context context) { 53 | super(context); 54 | setup(context, null, -1); 55 | } 56 | 57 | public SortView(Context context, AttributeSet attrs) { 58 | super(context, attrs); 59 | setup(context, attrs, -1); 60 | } 61 | 62 | public SortView(Context context, AttributeSet attrs, int defStyleAttr) { 63 | super(context, attrs, defStyleAttr); 64 | 65 | setup(context, attrs, defStyleAttr); 66 | 67 | } 68 | 69 | 70 | public int getCompletePosition() { 71 | return completePosition; 72 | } 73 | 74 | public void setCompletePosition(int completePosition) { 75 | this.completePosition = completePosition; 76 | } 77 | 78 | /** 79 | * find max value in array 80 | * 81 | * @param arr - input array 82 | * @return - max value 83 | */ 84 | private int getMax(int[] arr) { 85 | int N = arr.length; 86 | int max = arr[0]; 87 | for (int i = 1; i < N; i++) { 88 | if (max < arr[i]) max = arr[i]; 89 | } 90 | return max; 91 | } 92 | 93 | public void setup(Context context, AttributeSet attrs, int defStyleAttr) { 94 | this.context = context; 95 | 96 | TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SortViewAttrs); 97 | 98 | barColor = a.getInteger(R.styleable.SortViewAttrs_bar_color, barColor); 99 | targetColor = a.getInteger(R.styleable.SortViewAttrs_target_color, targetColor); 100 | traceColor = a.getInteger(R.styleable.SortViewAttrs_trace_color, traceColor); 101 | quadColor = a.getInteger(R.styleable.SortViewAttrs_quad_color, quadColor); 102 | completeColor = a.getInteger(R.styleable.SortViewAttrs_complete_color, completeColor); 103 | textInfoColor = a.getInteger(R.styleable.SortViewAttrs_text_info_color, textInfoColor); 104 | swapAColor = a.getInteger(R.styleable.SortViewAttrs_swap_a_color, swapAColor); 105 | swapBColor = a.getInteger(R.styleable.SortViewAttrs_swap_b_color, swapBColor); 106 | a.recycle(); 107 | 108 | mPaint = new Paint(); 109 | mPaint.setStyle(Paint.Style.STROKE); 110 | mPaint.setColor(barColor); 111 | mPaint.setAntiAlias(true); 112 | setTextSize(20f); 113 | array = null; 114 | } 115 | 116 | /** 117 | * calculate and set text size for mPaint 118 | */ 119 | private void setTextSize(float GESTURE_THRESHOLD_DIP) { 120 | // The gesture threshold expressed in dip 121 | // Convert the dips to pixels 122 | final float scale = getContext().getResources().getDisplayMetrics().density; 123 | int mGestureThreshold = (int) (GESTURE_THRESHOLD_DIP * scale + 0.5f); 124 | 125 | mPaint.setTextSize(mGestureThreshold); 126 | } 127 | 128 | /** 129 | * draw data from array @array 130 | * 131 | * @param canvas - canvas 132 | */ 133 | @Override 134 | protected void onDraw(Canvas canvas) { 135 | super.onDraw(canvas); 136 | //if data is available 137 | if (array != null && array.length > 0) { 138 | drawArray(canvas); 139 | } else { 140 | drawNoData(canvas); 141 | } 142 | drawInfo(canvas); 143 | } 144 | 145 | /** 146 | * draw text name and mTime in top-left of view 147 | */ 148 | private void drawInfo(Canvas canvas) { 149 | mPaint.setStyle(Paint.Style.FILL); 150 | mPaint.setStrokeWidth(1.0f); 151 | mPaint.setColor(textInfoColor); 152 | setTextSize(10f); 153 | 154 | Rect rect = new Rect(); 155 | mPaint.getTextBounds("A", 0, 1, rect); 156 | 157 | int x = rect.width(); 158 | int y = rect.height() + rect.height() / 2; 159 | 160 | canvas.drawText(name, x, y, mPaint); 161 | 162 | y += (rect.height() + rect.height() / 2); 163 | canvas.drawText("Complexity: " + mTime, x, y, mPaint); 164 | } 165 | 166 | /** 167 | * draw array data 168 | * 169 | * @param canvas 170 | */ 171 | private void drawArray(Canvas canvas) { 172 | int width = getWidth(); //get width of view 173 | int height = getHeight(); //get height of view 174 | //number entry of array 175 | int N = array.length; 176 | 177 | //calculate width of bar 178 | float barWidth = width / (N + 1); 179 | mPaint.setStrokeWidth(barWidth * 0.8f); 180 | 181 | int max = getMax(array); 182 | 183 | //calculate dip per bar entry 184 | float per = height / (max + 1); 185 | 186 | //start x, start y, start y is height because axis of screen 187 | // top-left (0;0) -> right-bottom (width;height) 188 | float x = 0; 189 | float y = height; 190 | 191 | //start index 192 | int index = 0; 193 | 194 | //foreach 195 | for (int a : array) { 196 | x += barWidth;//coordinate of next bar 197 | if (index <= completePosition) { 198 | //set color for bar entry 199 | mPaint.setColor(completeColor); 200 | canvas.drawLine(x, y, x, y - (a * per), mPaint);//draw bar 201 | } else { 202 | if (index == swapAPosition) { //swap0 203 | // Log.d(TAG, "drawArray: " + swapAPosition); 204 | mPaint.setColor(swapAColor); 205 | //draw highlight bar 206 | canvas.drawLine(xA, yA, xA, yA + (a * per), mPaint); 207 | 208 | } else if (index == swapBPosition) { //swap1 209 | // Log.d(TAG, "drawArray: " + swapBPosition); 210 | mPaint.setColor(swapBColor); 211 | //draw highlight bar 212 | canvas.drawLine(xB, yB, xB, yB + (a * per), mPaint); 213 | 214 | } else if (index == tracePosition) { //trace 215 | mPaint.setColor(traceColor); 216 | canvas.drawLine(x, y, x, y - (a * per), mPaint);//draw highlight bar 217 | } else { 218 | //set color for bar entry 219 | mPaint.setColor(barColor); 220 | canvas.drawLine(x, y, x, y - (a * per), mPaint);//draw bar 221 | } 222 | if (index == targetPosition) { //target 223 | 224 | //set color for bar entry 225 | mPaint.setColor(targetColor); 226 | canvas.drawLine(x, y, x, y - (a * per), mPaint);//draw highlight bar 227 | } 228 | } 229 | index++; 230 | } 231 | if (swapAPosition != swapBPosition) { 232 | mPaint.setStyle(Paint.Style.STROKE); 233 | mPaint.setStrokeWidth(2.0f); 234 | mPaint.setColor(quadColor); 235 | Path path = new Path(); 236 | path.moveTo(xA, yA); 237 | 238 | path.quadTo(xA + Math.abs(xB - xA) * 2 / 3, y - max * per, xB, yB); 239 | canvas.drawPath(path, mPaint); 240 | } 241 | } 242 | 243 | private void drawNoData(Canvas canvas) { 244 | mPaint.setStyle(Paint.Style.FILL); 245 | mPaint.setStrokeWidth(1.0f); 246 | mPaint.setColor(textInfoColor); 247 | canvas.drawText(NO_DATA, getWidth() / 2, getHeight() / 2, mPaint); 248 | } 249 | 250 | public void setTracePosition(int index) { 251 | this.tracePosition = index; 252 | invalidate(); 253 | } 254 | 255 | public void setArray(int[] arr) { 256 | this.array = arr; 257 | } 258 | 259 | @UiThread 260 | public void setSwapPosition(int i1, int i2) { 261 | setSwapPosition(i1, i2, true); 262 | } 263 | 264 | @UiThread 265 | public void setSwapPosition(int i1, int i2, boolean redraw) { 266 | if (i1 < 0 || i2 < 0) { 267 | swapAPosition = i1; 268 | swapBPosition = i2; 269 | if (redraw) invalidate(); 270 | return; 271 | } 272 | if (i1 < i2) { 273 | swapAPosition = i1; 274 | swapBPosition = i2; 275 | } else { 276 | swapAPosition = i2; 277 | swapBPosition = i1; 278 | } 279 | 280 | int width = getWidth(); //get width of view 281 | int height = getHeight(); //get height of view 282 | int N = array.length; 283 | float barWidth = width / (N + 1); 284 | int max = getMax(array); 285 | //calculate pixel per bar entry 286 | float per = height / (max + 1); 287 | 288 | xA = barWidth * (swapAPosition + 1); 289 | yA = height - (array[swapAPosition] * per); 290 | 291 | xB = barWidth * (swapBPosition + 1); 292 | yB = height - (array[swapBPosition] * per); 293 | delta = (int) Math.abs(xB - xA); 294 | if (redraw) invalidate(); 295 | } 296 | 297 | 298 | public int getSizeArray() { 299 | return array.length; 300 | } 301 | 302 | public String getName() { 303 | return name; 304 | } 305 | 306 | public void setName(String name) { 307 | this.name = name; 308 | } 309 | 310 | public void setName(int id) { 311 | this.name = context.getString(id); 312 | } 313 | 314 | @UiThread 315 | public void setTargetPosition(int targetPosition) { 316 | this.targetPosition = targetPosition; 317 | invalidate(); 318 | } 319 | 320 | public void setTime(long time) { 321 | this.mTime = time; 322 | } 323 | 324 | public void addTimeUnit(long time) { 325 | this.mTime += time; 326 | } 327 | 328 | /** 329 | * change value of xA, xB 330 | */ 331 | @UiThread 332 | public void incPositionSwap(float v) { 333 | xA += v; 334 | xB -= v; 335 | invalidate(); 336 | } 337 | 338 | public int getDelta() { 339 | return delta; 340 | } 341 | } 342 | -------------------------------------------------------------------------------- /app/src/main/java/com/duy/algorithm/notify/RateManager.java: -------------------------------------------------------------------------------- 1 | package com.duy.algorithm.notify; 2 | 3 | import android.app.Activity; 4 | import android.content.ActivityNotFoundException; 5 | import android.content.Context; 6 | import android.content.Intent; 7 | import android.net.Uri; 8 | 9 | import com.duy.algorithm.R; 10 | import com.kobakei.ratethisapp.RateThisApp; 11 | 12 | /** 13 | * Created by DUy on 13-Jan-17. 14 | */ 15 | 16 | public class RateManager { 17 | 18 | public static void init(Context context) { 19 | RateThisApp.Config config = new RateThisApp.Config(3, 15); 20 | config.setTitle(R.string.my_own_title); 21 | config.setMessage(R.string.my_own_message); 22 | config.setYesButtonText(R.string.my_own_rate); 23 | config.setNoButtonText(R.string.my_own_thanks); 24 | config.setCancelButtonText(R.string.my_own_cancel); 25 | RateThisApp.init(config); 26 | } 27 | 28 | /** 29 | * create intent go to market play store 30 | */ 31 | public static void rateApp(Activity activity) { 32 | Uri uri = Uri.parse("market://details?id=com.duy.com.duy.calculator.free"); 33 | Intent goToMarket = new Intent(Intent.ACTION_VIEW, uri); 34 | // To count with Play market backstack, After pressing back button, 35 | // to taken back to our application, we need to add following flags to intent. 36 | goToMarket.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY | 37 | Intent.FLAG_ACTIVITY_MULTIPLE_TASK); 38 | try { 39 | activity.startActivity(goToMarket); 40 | } catch (ActivityNotFoundException e) { 41 | activity.startActivity(new Intent(Intent.ACTION_VIEW, 42 | Uri.parse("http://play.google.com/store/apps/details?id=com.duy.com.duy.calculator.free"))); 43 | } 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /app/src/main/java/com/duy/algorithm/userinterface/ThemeEngine.java: -------------------------------------------------------------------------------- 1 | package com.duy.algorithm.userinterface; 2 | 3 | import android.content.Context; 4 | import android.content.res.Resources; 5 | 6 | import com.duy.algorithm.R; 7 | 8 | 9 | /** 10 | * Created by Duy on 3/7/2016 11 | */ 12 | public class ThemeEngine { 13 | public static final String NULL = ""; 14 | public static final int THEME_NOT_FOUND = -1; 15 | private final int mLightTheme; 16 | private final int mDarkTheme; 17 | private Resources mResources; 18 | 19 | public ThemeEngine(Context applicationContext) { 20 | this.mResources = applicationContext.getResources(); 21 | 22 | mLightTheme = R.style.AppTheme_Light_NoActionBar; 23 | mDarkTheme = R.style.AppTheme_Dark_NoActionBar; 24 | 25 | } 26 | 27 | /** 28 | * get theme from mResult 29 | * 30 | * @param name 31 | * @return 32 | */ 33 | public int getTheme(String name) { 34 | name = name.trim(); 35 | if (name.equals(NULL)) { 36 | return THEME_NOT_FOUND; 37 | } 38 | if (name.equals(mResources.getString(R.string.theme_light))) { 39 | return mLightTheme; 40 | } else if (name.equals(mResources.getString(R.string.theme_dark))) { 41 | return mDarkTheme; 42 | } 43 | return mLightTheme; 44 | } 45 | } 46 | 47 | -------------------------------------------------------------------------------- /app/src/main/java/com/duy/algorithm/utils/ArrayUtils.java: -------------------------------------------------------------------------------- 1 | package com.duy.algorithm.utils; 2 | 3 | 4 | import java.util.Random; 5 | 6 | public class ArrayUtils { 7 | 8 | /** 9 | * create array with random value 10 | * 11 | * @param a - array 12 | * @param bits - range random 13 | */ 14 | public static void createIntArray(int[] a, int bits) { 15 | int len = a.length; 16 | Random random = new Random(); 17 | 18 | for (int i = 0; i < len; i++) { 19 | a[i] = random.nextInt(bits) + 1; 20 | } 21 | 22 | } 23 | 24 | /** 25 | * create array with random value 26 | * 27 | * @param length - length of array and range random 28 | */ 29 | public static int[] createIntArray(int length) { 30 | int[] a = new int[length]; 31 | Random random = new Random(); 32 | 33 | for (int i = 0; i < length; i++) { 34 | a[i] = random.nextInt(length) + 1; 35 | } 36 | return a; 37 | } 38 | 39 | public static void swap(int[] a, int i, int j) { 40 | int e = a[i]; 41 | a[i] = a[j]; 42 | a[j] = e; 43 | } 44 | 45 | public static String arrayToString(int[] array) { 46 | String res = ""; 47 | for (int i = 0; i < array.length; i++) { 48 | res += array[i]; 49 | if (i != array.length - 1) 50 | res += ","; 51 | } 52 | return res; 53 | } 54 | 55 | public static int[] arrayStringToInt(String[] strArray) { 56 | int array[] = new int[strArray.length]; 57 | for (int i = 0; i < strArray.length; i++) { 58 | try { 59 | array[i] = Integer.parseInt(strArray[i].replace(" ", "")); 60 | } catch (Exception e) { 61 | e.printStackTrace(); 62 | array[0] = Integer.parseInt(strArray[i]); 63 | return array; 64 | } 65 | } 66 | return array; 67 | } 68 | 69 | public static int findMax(int[] array) { 70 | int max = -1; 71 | try { 72 | max = array[0]; 73 | for (int a : array) { 74 | if (max < a) max = a; 75 | } 76 | } catch (Exception e) { 77 | e.printStackTrace(); 78 | } 79 | return max; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_check_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tranleduy2000/sortalgorithm/ebabae4c97d552d5a228866342b3daf0d61a8b7d/app/src/main/res/drawable-hdpi/ic_check_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_color_lens_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tranleduy2000/sortalgorithm/ebabae4c97d552d5a228866342b3daf0d61a8b7d/app/src/main/res/drawable-hdpi/ic_color_lens_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_compare_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tranleduy2000/sortalgorithm/ebabae4c97d552d5a228866342b3daf0d61a8b7d/app/src/main/res/drawable-hdpi/ic_compare_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_info_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tranleduy2000/sortalgorithm/ebabae4c97d552d5a228866342b3daf0d61a8b7d/app/src/main/res/drawable-hdpi/ic_info_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_language_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tranleduy2000/sortalgorithm/ebabae4c97d552d5a228866342b3daf0d61a8b7d/app/src/main/res/drawable-hdpi/ic_language_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_list_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tranleduy2000/sortalgorithm/ebabae4c97d552d5a228866342b3daf0d61a8b7d/app/src/main/res/drawable-hdpi/ic_list_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_pause_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tranleduy2000/sortalgorithm/ebabae4c97d552d5a228866342b3daf0d61a8b7d/app/src/main/res/drawable-hdpi/ic_pause_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_play_arrow_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tranleduy2000/sortalgorithm/ebabae4c97d552d5a228866342b3daf0d61a8b7d/app/src/main/res/drawable-hdpi/ic_play_arrow_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_settings_backup_restore_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tranleduy2000/sortalgorithm/ebabae4c97d552d5a228866342b3daf0d61a8b7d/app/src/main/res/drawable-hdpi/ic_settings_backup_restore_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_settings_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tranleduy2000/sortalgorithm/ebabae4c97d552d5a228866342b3daf0d61a8b7d/app/src/main/res/drawable-hdpi/ic_settings_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_check_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tranleduy2000/sortalgorithm/ebabae4c97d552d5a228866342b3daf0d61a8b7d/app/src/main/res/drawable-mdpi/ic_check_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_color_lens_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tranleduy2000/sortalgorithm/ebabae4c97d552d5a228866342b3daf0d61a8b7d/app/src/main/res/drawable-mdpi/ic_color_lens_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_compare_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tranleduy2000/sortalgorithm/ebabae4c97d552d5a228866342b3daf0d61a8b7d/app/src/main/res/drawable-mdpi/ic_compare_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_info_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tranleduy2000/sortalgorithm/ebabae4c97d552d5a228866342b3daf0d61a8b7d/app/src/main/res/drawable-mdpi/ic_info_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_language_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tranleduy2000/sortalgorithm/ebabae4c97d552d5a228866342b3daf0d61a8b7d/app/src/main/res/drawable-mdpi/ic_language_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_list_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tranleduy2000/sortalgorithm/ebabae4c97d552d5a228866342b3daf0d61a8b7d/app/src/main/res/drawable-mdpi/ic_list_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_pause_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tranleduy2000/sortalgorithm/ebabae4c97d552d5a228866342b3daf0d61a8b7d/app/src/main/res/drawable-mdpi/ic_pause_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_play_arrow_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tranleduy2000/sortalgorithm/ebabae4c97d552d5a228866342b3daf0d61a8b7d/app/src/main/res/drawable-mdpi/ic_play_arrow_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_settings_backup_restore_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tranleduy2000/sortalgorithm/ebabae4c97d552d5a228866342b3daf0d61a8b7d/app/src/main/res/drawable-mdpi/ic_settings_backup_restore_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_settings_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tranleduy2000/sortalgorithm/ebabae4c97d552d5a228866342b3daf0d61a8b7d/app/src/main/res/drawable-mdpi/ic_settings_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_check_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tranleduy2000/sortalgorithm/ebabae4c97d552d5a228866342b3daf0d61a8b7d/app/src/main/res/drawable-xhdpi/ic_check_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_color_lens_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tranleduy2000/sortalgorithm/ebabae4c97d552d5a228866342b3daf0d61a8b7d/app/src/main/res/drawable-xhdpi/ic_color_lens_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_compare_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tranleduy2000/sortalgorithm/ebabae4c97d552d5a228866342b3daf0d61a8b7d/app/src/main/res/drawable-xhdpi/ic_compare_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_info_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tranleduy2000/sortalgorithm/ebabae4c97d552d5a228866342b3daf0d61a8b7d/app/src/main/res/drawable-xhdpi/ic_info_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_language_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tranleduy2000/sortalgorithm/ebabae4c97d552d5a228866342b3daf0d61a8b7d/app/src/main/res/drawable-xhdpi/ic_language_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_list_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tranleduy2000/sortalgorithm/ebabae4c97d552d5a228866342b3daf0d61a8b7d/app/src/main/res/drawable-xhdpi/ic_list_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_pause_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tranleduy2000/sortalgorithm/ebabae4c97d552d5a228866342b3daf0d61a8b7d/app/src/main/res/drawable-xhdpi/ic_pause_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_play_arrow_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tranleduy2000/sortalgorithm/ebabae4c97d552d5a228866342b3daf0d61a8b7d/app/src/main/res/drawable-xhdpi/ic_play_arrow_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_settings_backup_restore_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tranleduy2000/sortalgorithm/ebabae4c97d552d5a228866342b3daf0d61a8b7d/app/src/main/res/drawable-xhdpi/ic_settings_backup_restore_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_settings_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tranleduy2000/sortalgorithm/ebabae4c97d552d5a228866342b3daf0d61a8b7d/app/src/main/res/drawable-xhdpi/ic_settings_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_check_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tranleduy2000/sortalgorithm/ebabae4c97d552d5a228866342b3daf0d61a8b7d/app/src/main/res/drawable-xxhdpi/ic_check_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_color_lens_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tranleduy2000/sortalgorithm/ebabae4c97d552d5a228866342b3daf0d61a8b7d/app/src/main/res/drawable-xxhdpi/ic_color_lens_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_compare_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tranleduy2000/sortalgorithm/ebabae4c97d552d5a228866342b3daf0d61a8b7d/app/src/main/res/drawable-xxhdpi/ic_compare_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_info_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tranleduy2000/sortalgorithm/ebabae4c97d552d5a228866342b3daf0d61a8b7d/app/src/main/res/drawable-xxhdpi/ic_info_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_language_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tranleduy2000/sortalgorithm/ebabae4c97d552d5a228866342b3daf0d61a8b7d/app/src/main/res/drawable-xxhdpi/ic_language_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_list_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tranleduy2000/sortalgorithm/ebabae4c97d552d5a228866342b3daf0d61a8b7d/app/src/main/res/drawable-xxhdpi/ic_list_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_pause_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tranleduy2000/sortalgorithm/ebabae4c97d552d5a228866342b3daf0d61a8b7d/app/src/main/res/drawable-xxhdpi/ic_pause_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_play_arrow_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tranleduy2000/sortalgorithm/ebabae4c97d552d5a228866342b3daf0d61a8b7d/app/src/main/res/drawable-xxhdpi/ic_play_arrow_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_settings_backup_restore_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tranleduy2000/sortalgorithm/ebabae4c97d552d5a228866342b3daf0d61a8b7d/app/src/main/res/drawable-xxhdpi/ic_settings_backup_restore_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_settings_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tranleduy2000/sortalgorithm/ebabae4c97d552d5a228866342b3daf0d61a8b7d/app/src/main/res/drawable-xxhdpi/ic_settings_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_check_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tranleduy2000/sortalgorithm/ebabae4c97d552d5a228866342b3daf0d61a8b7d/app/src/main/res/drawable-xxxhdpi/ic_check_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_color_lens_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tranleduy2000/sortalgorithm/ebabae4c97d552d5a228866342b3daf0d61a8b7d/app/src/main/res/drawable-xxxhdpi/ic_color_lens_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_compare_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tranleduy2000/sortalgorithm/ebabae4c97d552d5a228866342b3daf0d61a8b7d/app/src/main/res/drawable-xxxhdpi/ic_compare_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_info_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tranleduy2000/sortalgorithm/ebabae4c97d552d5a228866342b3daf0d61a8b7d/app/src/main/res/drawable-xxxhdpi/ic_info_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_language_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tranleduy2000/sortalgorithm/ebabae4c97d552d5a228866342b3daf0d61a8b7d/app/src/main/res/drawable-xxxhdpi/ic_language_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_list_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tranleduy2000/sortalgorithm/ebabae4c97d552d5a228866342b3daf0d61a8b7d/app/src/main/res/drawable-xxxhdpi/ic_list_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_pause_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tranleduy2000/sortalgorithm/ebabae4c97d552d5a228866342b3daf0d61a8b7d/app/src/main/res/drawable-xxxhdpi/ic_pause_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_play_arrow_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tranleduy2000/sortalgorithm/ebabae4c97d552d5a228866342b3daf0d61a8b7d/app/src/main/res/drawable-xxxhdpi/ic_play_arrow_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_settings_backup_restore_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tranleduy2000/sortalgorithm/ebabae4c97d552d5a228866342b3daf0d61a8b7d/app/src/main/res/drawable-xxxhdpi/ic_settings_backup_restore_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_settings_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tranleduy2000/sortalgorithm/ebabae4c97d552d5a228866342b3daf0d61a8b7d/app/src/main/res/drawable-xxxhdpi/ic_settings_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_app_about.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 10 | 11 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 13 | 14 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /app/src/main/res/layout/content_app_about.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 13 | 14 | 22 | 23 | 29 | 30 | 36 | 37 | 43 | 44 | 49 | 50 | 55 | 56 | 61 | 62 | 71 | 72 | 73 | 74 | 75 | 76 | 85 | 86 | 92 | 93 | 94 | 103 | 104 | 105 | 113 | 114 | 115 | 116 | 117 | -------------------------------------------------------------------------------- /app/src/main/res/layout/content_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 11 | 12 | 16 | 17 | 18 | 29 | 30 | 34 | 35 | 42 | 43 | 47 | 48 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 73 | 74 | 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /app/src/main/res/layout/control_panel.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 11 | 12 | 20 | 21 | 22 | 26 | 27 | 31 | 32 | 36 | 37 | 38 | 44 | 45 | 49 | 50 | 56 | 57 | 64 | 65 | 66 | 67 | 72 | 73 | 80 | 81 | 86 | 87 | 93 | 94 | 99 | 100 | 101 | 102 | 103 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_control.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 11 | 12 | 16 | 17 | 21 | 22 | 23 | 29 | 30 | 34 | 35 | 41 | 42 | 49 | 50 | 51 | 56 | 57 | 64 | 65 | 70 | 71 | 77 | 78 | 83 | 84 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_log.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 15 | 16 | 20 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_multi_sort.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 14 | 15 | 20 | 21 | 26 | 27 | 32 | 33 | 38 | 39 | 44 | 45 | 50 | 51 | 56 | 57 | 62 | 63 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_sort.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 18 | 19 | 24 | 25 | 31 | 32 | 33 | 37 | 38 | 46 | 47 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /app/src/main/res/layout/log_item.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/layout/nav_header.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 12 | 13 | 19 | 20 |