diff --git a/.idea/compiler.xml b/.idea/compiler.xml
index 1f2af51..96cc43e 100644
--- a/.idea/compiler.xml
+++ b/.idea/compiler.xml
@@ -11,6 +11,7 @@
+
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
deleted file mode 100644
index 97626ba..0000000
--- a/.idea/encodings.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/gradle.xml b/.idea/gradle.xml
index 7ac24c7..fe72da5 100644
--- a/.idea/gradle.xml
+++ b/.idea/gradle.xml
@@ -3,8 +3,9 @@
-
+
-
-
-
-
- Android API 10 Platform
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
index 94a25f7..35eb1dd 100644
--- a/.idea/vcs.xml
+++ b/.idea/vcs.xml
@@ -1,6 +1,6 @@
-
+
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index 604b5f6..12ce42a 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -43,4 +43,7 @@ dependencies {
}
+ testCompile 'junit:junit:4.12'
+ testCompile 'org.mockito:mockito-core:1.10.19'
+
}
diff --git a/app/src/main/assets/desc.json b/app/src/main/assets/desc.json
index 72e152b..1e936f0 100644
--- a/app/src/main/assets/desc.json
+++ b/app/src/main/assets/desc.json
@@ -94,6 +94,16 @@
"SortingVisualizer"
]
},
+ "merge_sort": {
+ "Merge Sort": "Merge Sort is a Divide and Conquer algorithm. It divides input array in two halves, calls itself for the two halves and then merges the two sorted halves",
+ "Complexity": {
+ "Time": "worst O(n log(n)), best O(n log(n)), average O(n log(n))",
+ "Space": "worst O(n) auxiliary"
+ },
+ "References": [
+ "Wikipedia
"
+ ]
+ },
"linked_list": {
"Singly linked list": "A Linked List is a linear collection of data elements, called nodes, each pointing to the next node by means of a pointer. It is a data structure consisting of a group of nodes which together represent a sequence. Under the simplest form, each node is composed of data and a reference (in other words, a link) to the next node in the sequence. ",
"Complexity": {
diff --git a/app/src/main/java/com/naman14/algovisualizer/AlgorithmCode.java b/app/src/main/java/com/naman14/algovisualizer/AlgorithmCode.java
index a810f86..f74f931 100644
--- a/app/src/main/java/com/naman14/algovisualizer/AlgorithmCode.java
+++ b/app/src/main/java/com/naman14/algovisualizer/AlgorithmCode.java
@@ -65,6 +65,42 @@ public class AlgorithmCode {
" addLog(\"Array has been sorted\");\n" +
" completed();";
+ public static final String CODE_MERGE_SORT = "" +
+ "public void mergeSort(int start, int end){\n" +
+ " if (start >= end){\n" +
+ " return;\n" +
+ " }\n" +
+ " int middle = (start + end)/2;\n" +
+ " mergeSort(start,middle);\n" +
+ " mergeSort(middle+1,end);\n" +
+ " merge(start,middle,middle+1,end);\n" +
+ "}\n" +
+ "public void merge(int start1, int end1, int start2, int end2){\n" +
+ " List sortedList = new ArrayList();\n" +
+ " List indexes = new ArrayList();\n" +
+ " int s0 = start1;\n" +
+ " while(start1 <= end1){\n" +
+ " if (start2 > end2){\n" +
+ " sortedList.add(array[start1]);\n" +
+ " start1+=1;\n" +
+ " continue;\n" +
+ " }\n" +
+ " if (array[start1] <= array[start2]){\n" +
+ " sortedList.add(array[start1]);\n" +
+ " start1+=1;\n" +
+ " }\n" +
+ " else{\n" +
+ " sortedList.add(array[start2]);\n" +
+ " start2+=1;\n" +
+ " }\n" +
+ " }\n" +
+ " int i = 0;\n" +
+ " for (int number:sortedList) {\n" +
+ " array[s0+i]=number;\n" +
+ " i+=1;\n" +
+ " }\n" +
+ "}";
+
public static final String CODE_BST_SEARCH = " int id = DataUtils.getRandomKeyFromBST();\n" +
" addLog(\"Searching for \" + String.valueOf(id));\n" +
" BinarySearchTree.Node current = b.getRoot();\n" +
diff --git a/app/src/main/java/com/naman14/algovisualizer/CodeFragment.java b/app/src/main/java/com/naman14/algovisualizer/CodeFragment.java
index bc3eb40..f443f07 100644
--- a/app/src/main/java/com/naman14/algovisualizer/CodeFragment.java
+++ b/app/src/main/java/com/naman14/algovisualizer/CodeFragment.java
@@ -67,6 +67,9 @@ public void setCode(String key) {
case Algorithm.SELECTION_SORT:
addCodeItem(AlgorithmCode.CODE_SELECTION_SORT,"Selection sort");
break;
+ case Algorithm.MERGE_SORT:
+ addCodeItem(AlgorithmCode.CODE_MERGE_SORT, "Merge sort");
+ break;
case Algorithm.BST_SEARCH:
addCodeItem(AlgorithmCode.CODE_BST_SEARCH, "BST Search");
break;
diff --git a/app/src/main/java/com/naman14/algovisualizer/MainActivity.java b/app/src/main/java/com/naman14/algovisualizer/MainActivity.java
index 391868c..1dc72b5 100644
--- a/app/src/main/java/com/naman14/algovisualizer/MainActivity.java
+++ b/app/src/main/java/com/naman14/algovisualizer/MainActivity.java
@@ -93,6 +93,10 @@ public boolean onChildClick(ExpandableListView expandableListView, View view, in
break;
case 2:
algoFragment.setupFragment(Algorithm.SELECTION_SORT);
+ break;
+ case 3:
+ algoFragment.setupFragment(Algorithm.MERGE_SORT);
+ break;
}
break;
case 2:
@@ -208,6 +212,7 @@ private void prepareListData() {
heading2.add("Bubble Sort");
heading2.add("Insertion Sort");
heading2.add("Selection Sort");
+ heading2.add("Merge Sort");
List heading3 = new ArrayList();
heading3.add("BST Search");
heading3.add("BST Insert");
diff --git a/app/src/main/java/com/naman14/algovisualizer/VisualAlgoFragment.java b/app/src/main/java/com/naman14/algovisualizer/VisualAlgoFragment.java
index d6756d0..dd1243d 100644
--- a/app/src/main/java/com/naman14/algovisualizer/VisualAlgoFragment.java
+++ b/app/src/main/java/com/naman14/algovisualizer/VisualAlgoFragment.java
@@ -41,6 +41,7 @@
import com.naman14.algovisualizer.algorithm.search.LinearSearch;
import com.naman14.algovisualizer.algorithm.sorting.BubbleSort;
import com.naman14.algovisualizer.algorithm.sorting.InsertionSort;
+import com.naman14.algovisualizer.algorithm.sorting.MergeSort;
import com.naman14.algovisualizer.algorithm.sorting.SelectionSort;
import com.naman14.algovisualizer.algorithm.tree.bst.BSTAlgorithm;
import com.naman14.algovisualizer.visualizer.AlgorithmVisualizer;
@@ -190,6 +191,12 @@ public void setupFragment(String algorithmKey) {
algorithm = new SelectionSort((SortingVisualizer) visualizer, getActivity(), logFragment);
((SelectionSort) algorithm).setData(DataUtils.createRandomArray(15));
break;
+ case Algorithm.MERGE_SORT:
+ visualizer = new SortingVisualizer(getActivity());
+ appBarLayout.addView(visualizer);
+ algorithm = new MergeSort((SortingVisualizer)visualizer, getActivity(), logFragment);
+ ((MergeSort)algorithm).setData(DataUtils.createRandomArray(15));
+ break;
case Algorithm.BST_SEARCH:
visualizer = new BSTVisualizer(getActivity());
appBarLayout.addView(visualizer);
diff --git a/app/src/main/java/com/naman14/algovisualizer/algorithm/Algorithm.java b/app/src/main/java/com/naman14/algovisualizer/algorithm/Algorithm.java
index 349452a..080db75 100644
--- a/app/src/main/java/com/naman14/algovisualizer/algorithm/Algorithm.java
+++ b/app/src/main/java/com/naman14/algovisualizer/algorithm/Algorithm.java
@@ -42,6 +42,7 @@ public class Algorithm extends HandlerThread {
public static final String DFS = "dfs";
public static final String DIJKSTRA = "dijkstra";
public static final String BELLMAN_FORD = "bellman_ford";
+ public static final String MERGE_SORT = "merge_sort";
public LogFragment logFragment;
diff --git a/app/src/main/java/com/naman14/algovisualizer/algorithm/sorting/MergeSort.java b/app/src/main/java/com/naman14/algovisualizer/algorithm/sorting/MergeSort.java
new file mode 100644
index 0000000..328807a
--- /dev/null
+++ b/app/src/main/java/com/naman14/algovisualizer/algorithm/sorting/MergeSort.java
@@ -0,0 +1,99 @@
+package com.naman14.algovisualizer.algorithm.sorting;
+
+import android.app.Activity;
+
+import com.naman14.algovisualizer.LogFragment;
+import com.naman14.algovisualizer.algorithm.Algorithm;
+import com.naman14.algovisualizer.algorithm.DataHandler;
+import com.naman14.algovisualizer.visualizer.SortingVisualizer;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Created by sergio on 02/01/17.
+ */
+
+public class MergeSort extends SortAlgorithm implements DataHandler {
+
+ private int[] array;
+
+ public MergeSort(SortingVisualizer visualizer, Activity activity, LogFragment logFragment) {
+ this.visualizer = visualizer;
+ this.activity = activity;
+ this.logFragment = logFragment;
+ }
+
+ private void sort(){
+ logArray("Original array - " ,array);
+ mergeSort(0,array.length-1);
+ completed();
+ }
+
+ public void mergeSort(int start, int end){
+ addLog("Sorting array between " + start + " and " + end);
+ if (start >= end){
+ return;
+ }
+ int middle = (start + end)/2;
+ highlightInterval(start,middle);
+ sleep();
+ mergeSort(start,middle);
+ highlightInterval(middle+1,end);
+ sleep();
+ mergeSort(middle+1,end);
+ highlightInterval(start,end);
+ sleep();
+ merge(start,middle,middle+1,end);
+ }
+
+ public void merge(int start1, int end1, int start2, int end2){
+ addLog("merging sub-array " + start1 + " to " + end1 + " and subarray " + start2 + " to " +
+ end2);
+ List sortedList = new ArrayList();
+ int s0 = start1;
+ while(start1 <= end1){
+ if (start2 > end2){
+ sortedList.add(array[start1]);
+ start1+=1;
+ continue;
+ }
+ if (array[start1] <= array[start2]){
+ sortedList.add(array[start1]);
+ start1+=1;
+ }
+ else{
+ sortedList.add(array[start2]);
+ start2+=1;
+ }
+ }
+ int i = 0;
+ for (int number:sortedList) {
+ array[s0+i]=number;
+ i+=1;
+ }
+ sleep();
+ }
+
+ @Override
+ public void run() {
+ super.run();
+ }
+
+ @Override
+ public void onDataRecieved(Object data) {
+ super.onDataRecieved(data);
+ this.array = (int[])data;
+
+ }
+
+ @Override
+ public void onMessageReceived(String message) {
+ super.onMessageReceived(message);
+ if(message.equals(Algorithm.COMMAND_START_ALGORITHM)){
+ startExecution();
+ sort();
+ }
+
+ }
+}
diff --git a/app/src/main/java/com/naman14/algovisualizer/algorithm/sorting/SortAlgorithm.java b/app/src/main/java/com/naman14/algovisualizer/algorithm/sorting/SortAlgorithm.java
index 3b4b3cb..b804e7c 100644
--- a/app/src/main/java/com/naman14/algovisualizer/algorithm/sorting/SortAlgorithm.java
+++ b/app/src/main/java/com/naman14/algovisualizer/algorithm/sorting/SortAlgorithm.java
@@ -52,6 +52,24 @@ public void run() {
});
}
+ public void highlightInterval(final int start, final int end){
+ activity.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ visualizer.highlightInterval(start,end);
+ }
+ });
+ }
+
+ public void resetInterval(){
+ activity.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ visualizer.highlightInterval(-1,-1);
+ }
+ });
+ }
+
@Override
public void onDataRecieved(Object data) {
diff --git a/app/src/main/java/com/naman14/algovisualizer/visualizer/SortingVisualizer.java b/app/src/main/java/com/naman14/algovisualizer/visualizer/SortingVisualizer.java
index 709c948..4bebf38 100644
--- a/app/src/main/java/com/naman14/algovisualizer/visualizer/SortingVisualizer.java
+++ b/app/src/main/java/com/naman14/algovisualizer/visualizer/SortingVisualizer.java
@@ -32,6 +32,8 @@ public class SortingVisualizer extends AlgorithmVisualizer {
int highlightPositionOne = -1, highlightPositionTwo = -1;
int highlightPosition = -1;
int lineStrokeWidth = getDimensionInPixel(10);
+ int startInterval, endInterval = -1;
+
public SortingVisualizer(Context context) {
super(context);
@@ -72,14 +74,23 @@ protected void onDraw(Canvas canvas) {
for (int i = 0; i < array.length; i++) {
if (i == highlightPositionOne || i == highlightPositionTwo) {
- canvas.drawLine(xPos, getHeight() - (float) ((array[i] / 10.0) * getHeight()), xPos, getHeight(), highlightPaintSwap);
+ canvas.drawLine(xPos, getHeight() - (float) ((array[i] / 10.0) * getHeight()),
+ xPos, getHeight(), highlightPaintSwap);
} else if (i == highlightPosition)
- canvas.drawLine(xPos, getHeight() - (float) ((array[i] / 10.0) * getHeight()), xPos, getHeight(), highlightPaintTrace);
+ canvas.drawLine(xPos, getHeight() - (float) ((array[i] / 10.0) * getHeight()),
+ xPos, getHeight(), highlightPaintTrace);
+ else if (startInterval >= 0 && endInterval >= startInterval &&
+ i >= startInterval && i <= endInterval) {
+ canvas.drawLine(xPos, getHeight() - (float) ((array[i] / 10.0) * getHeight()),
+ xPos, getHeight(), highlightPaintTrace);
+ }
else {
- canvas.drawLine(xPos, getHeight() - (float) ((array[i] / 10.0) * getHeight()), xPos, getHeight(), paint);
+ canvas.drawLine(xPos, getHeight() - (float) ((array[i] / 10.0) * getHeight()),
+ xPos, getHeight(), paint);
}
- canvas.drawText(String.valueOf(array[i]), xPos - lineStrokeWidth / 3, getHeight() - (float) ((array[i] / 10.0) * getHeight()) - 30, textPaint);
+ canvas.drawText(String.valueOf(array[i]), xPos - lineStrokeWidth / 3,
+ getHeight() - (float) ((array[i] / 10.0) * getHeight()) - 30, textPaint);
xPos += margin + 30;
}
@@ -111,11 +122,23 @@ public void highlightTrace(int position) {
invalidate();
}
+ public void highlightInterval(int start, int end){
+ this.startInterval = start;
+ this.endInterval = end;
+ invalidate();
+ }
+
+ public void resetHighlightInterval(){
+ highlightInterval(-1,-1);
+ }
+
@Override
public void onCompleted() {
this.highlightPosition = -1;
this.highlightPositionTwo = -1;
this.highlightPositionOne = -1;
+ this.startInterval = -1;
+ this.endInterval = -1;
invalidate();
}
}
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index eb96b43..e75c5cd 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -2,4 +2,6 @@
AlgorithmVisualizer
Settings
Report any bugs here
+ key
+ key
diff --git a/app/src/test/java/com/naman14/algovisualizer/MergeSortTest.java b/app/src/test/java/com/naman14/algovisualizer/MergeSortTest.java
new file mode 100644
index 0000000..7b6dd51
--- /dev/null
+++ b/app/src/test/java/com/naman14/algovisualizer/MergeSortTest.java
@@ -0,0 +1,87 @@
+package com.naman14.algovisualizer;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.res.AssetManager;
+import android.content.res.Resources;
+import android.test.mock.MockContext;
+
+import com.naman14.algovisualizer.algorithm.sorting.MergeSort;
+import com.naman14.algovisualizer.visualizer.SortingVisualizer;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+
+import static junit.framework.Assert.assertEquals;
+import static org.mockito.Mockito.when;
+
+/**
+ * Created by sergio on 02/01/17.
+ */
+@RunWith(MockitoJUnitRunner.class)
+public class MergeSortTest {
+
+ @Mock
+ private SortingVisualizer mSortVisualizer;
+ @Mock
+ private Activity mActivity;
+ @Mock
+ private LogFragment mLogFragment;
+
+ private MergeSort mergeSort;
+
+ public MergeSortTest(){
+
+ }
+
+ @Before
+ public void before(){
+ mergeSort = new MergeSort(mSortVisualizer, mActivity,mLogFragment);
+ }
+
+ @Test
+ public void mergeSort() throws Exception {
+ int [] array = new int[] {4,1,2,4,6,8,7,10,9};
+ int [] sortedArray = new int [] {1,2,4,4,6,7,8,9,10};
+
+ mergeSort.onDataRecieved(array);
+ mergeSort.mergeSort(0,array.length-1);
+
+ for (int i = 0; i < array.length; i++) {
+ assertEquals(array[i],sortedArray[i]);
+ }
+ }
+
+ @Test
+ public void mergeSort_empty_array() throws Exception{
+ int [] array = new int[]{};
+ mergeSort.onDataRecieved(array);
+ mergeSort.mergeSort(0,array.length-1);
+ assertEquals(array.length,0);
+ }
+
+ @Test
+ public void mergeSort_one_element_array() throws Exception{
+ int [] array = new int[]{1};
+ mergeSort.onDataRecieved(array);
+ mergeSort.mergeSort(0,array.length-1);
+ assertEquals(array.length,1);
+ assertEquals(array[0],1);
+ }
+
+ @Test
+ public void merge() throws Exception {
+
+ int [] array = new int[] {1,5,6,7,1,2,3,10};
+ int [] mergedArray = new int[] {1,1,2,3,5,6,7,10};
+ mergeSort.onDataRecieved(array);
+ mergeSort.merge(1,3,4,6);
+
+ for (int i = 0; i < array.length; i++) {
+ assertEquals(array[i],mergedArray[i]);
+ }
+ }
+}
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index e5fbd9f..efa7225 100644
--- a/build.gradle
+++ b/build.gradle
@@ -6,7 +6,7 @@ buildscript {
maven { url 'https://maven.fabric.io/public' }
}
dependencies {
- classpath 'com.android.tools.build:gradle:2.1.0'
+ classpath 'com.android.tools.build:gradle:2.2.3'
classpath 'io.fabric.tools:gradle:1.+'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index c25cec5..625e6f2 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Wed Oct 21 11:34:03 PDT 2015
+#Mon Jan 02 13:25:43 GMT 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip