Browse Source

新增排序算法:冒泡排序、选择排序

ChenGanBin 3 years ago
parent
commit
dfd0de49a9

+ 37 - 0
src/main/java/com/cyl/algorithrms/sort/Bubble.java

@@ -0,0 +1,37 @@
+package com.cyl.algorithrms.sort;
+
+/**
+ * 冒泡排序
+ * 时间复杂度:O(n^2)
+ */
+public class Bubble {
+    /**
+     * 冒泡排序
+     * 第一个循环:控制遍历次数,也代表已排序的元素数量
+     * 第二个循环:对范围内的数据进行排序
+     *     每次都是从第一个元素开始排序 j=0
+     *     两两相邻元素进行比较,因此比较范围为[j, j+1]
+     *     排序下标范围:[0, 数组长度-1-已排序元素数量(i)],数组长度-1 是把长度改成0基表示,更易理解
+     *     显示条件:j < 数组长度-1-已排序元素数量(i), 即 j+1 = 数组长度-1-已排序元素数量(i)
+     * @param a 待排序数组
+     * @param ascending true-升序,false-降序
+     * @return
+     */
+    public static void sort(Comparable[] a, boolean ascending) {
+        //获取数组长度
+        int length = a.length;
+        //排序方向:1 升序;-1 降序
+        int compVal = ascending ? 1 : -1;
+        for (int i=0; i<length; i++){
+            for (int j=0; j< length-i-1; j++){
+                // a[j] > a[j+1] 即 升序 (true, 1)
+                // a[j] < a[j+1] 即 降序 (false, -1)
+                if(a[j].compareTo(a[j+1]) == compVal) {
+                    Comparable tmp = a[j];
+                    a[j] = a[j+1];
+                    a[j+1] = tmp;
+                }
+            }
+        }
+    }
+}

+ 27 - 44
src/main/java/com/cyl/algorithrms/sort/Selection.java

@@ -2,55 +2,38 @@ package com.cyl.algorithrms.sort;
 
 /**
  * 选择排序
+ * 时间复杂度:O(n^2)
+ * 空间复杂度:O(1)
+ *
+ * 与冒泡排序相比,基本上一致,依然是两两比较,但是减少了交换次数(不是立刻交换,而是遍历一次后再交换)
  */
 public class Selection {
 
-    public static void sort(Comparable[] a) {
-        //将a[]按升序排列
-        int N = a.length;
-        for (int i = 0; i < N; i++) {
-            int min = i;
-            for (int j = i + 1; j < N; j++) {
-                if(less(a[j], a[min])) {
-                    min = j;
+    public static void sort(Comparable[] a, boolean ascending) {
+        //获取数组长度
+        int len = a.length;
+        //排序方向:1 升序;-1 降序
+        int compVal = ascending ? 1 : -1;
+        //第一个循环:控制遍历次数
+        for (int i = 0; i < len; i++) {
+            //用于记录当前的待排序元素
+            int idx = i;
+            //第二个循环:控制待排序的范围 (待遍历的范围)
+            // 待排序的元素下标 i、[i+1, len - 1]
+            // idx=i 即当前循环开始时的待排序元素
+            // j=i+1 即下一个要比较的元素
+            // len-1 即0基础表示时,数组的最后一个元素,j < len 与 j <= len-1 等价
+            for (int j = i + 1; j < len; j++) {
+                // a[j] > a[j+1] 即 升序 (true, 1)
+                // a[j] < a[j+1] 即 降序 (false, -1)
+                if(a[idx].compareTo(a[j]) == compVal) {
+                    idx = j;
                 }
-                exch(a, i, min);
             }
+            // 找到符合目标的元素后进行交换
+            Comparable tmp = a[i];
+            a[i] = a[idx];
+            a[idx] = tmp;
         }
     }
-
-    private static boolean less(Comparable v, Comparable w) {
-        return v.compareTo(w) < 0;
-    }
-
-    private static void exch(Comparable[] a, int i, int j) {
-        Comparable t = a[i];
-        a[i] = a[j];
-        a[j] = t;
-    }
-
-    private static void show(Comparable[] a) {
-        //    在单行中打印数组
-        for (int i = 0; i < a.length; i++) {
-            System.out.print(a[i] + " ");
-        }
-        System.out.println();
-    }
-
-    public static boolean isSorted(Comparable[] a) {
-        //    测试数组元素是否有序
-        for (int i = 1; i < a.length; i++) {
-            if(less(a[i], a[i-1])) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    public static void main(String[] args) {
-        String[] a = "SORTEXAMPLE".split("");
-        sort(a);
-        assert isSorted(a);
-        show(a);
-    }
 }

+ 0 - 12
src/test/java/AppTest.java

@@ -1,12 +0,0 @@
-/*
- * This Java source file was generated by the Gradle 'init' task.
- */
-import org.junit.Test;
-import static org.junit.Assert.*;
-
-public class AppTest {
-    @Test public void testAppHasAGreeting() {
-        App classUnderTest = new App();
-        assertNotNull("app should have a greeting", classUnderTest.getGreeting());
-    }
-}

+ 32 - 0
src/test/java/com/cyl/algorithrms/sort/BubbleTest.java

@@ -0,0 +1,32 @@
+package com.cyl.algorithrms.sort;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.Arrays;
+
+import static org.junit.Assert.*;
+
+public class BubbleTest {
+
+    private Comparable[] origArr = null;
+
+    @Before
+    public void prepare() {
+        origArr = new Comparable[]{1,3,4,6,7,8,9,2,5,0};
+    }
+
+    @Test
+    public void testSortAsc() {
+        Comparable[] ascArr = new Comparable[]{0,1,2,3,4,5,6,7,8,9};
+        Bubble.sort(origArr, true);
+        assertArrayEquals(String.format("测试升序,排序结果:%s", Arrays.toString(origArr)), ascArr, origArr);
+    }
+
+    @Test
+    public void testSortDesc() {
+        Comparable[] descArr = new Comparable[]{9,8,7,6,5,4,3,2,1,0};
+        Bubble.sort(origArr, false);
+        assertArrayEquals(String.format("测试降序,排序结果:%s", Arrays.toString(origArr)), descArr, origArr);
+    }
+}

+ 34 - 0
src/test/java/com/cyl/algorithrms/sort/SelectionTest.java

@@ -0,0 +1,34 @@
+package com.cyl.algorithrms.sort;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.Arrays;
+
+import static org.junit.Assert.*;
+
+public class SelectionTest {
+
+    protected Comparable[] origArr = null;
+
+    protected Comparable[] ascArr = new Comparable[]{0,1,2,3,4,5,6,7,8,9};
+
+    protected Comparable[] descArr = new Comparable[]{9,8,7,6,5,4,3,2,1,0};
+
+    @Before
+    public void prepare() {
+        origArr = new Comparable[]{1,3,4,6,7,8,9,2,5,0};
+    }
+
+    @Test
+    public void testSortAsc() {
+        Selection.sort(origArr, true);
+        assertArrayEquals(String.format("测试降序,排序结果:%s", Arrays.toString(origArr)), ascArr, origArr);
+    }
+
+    @Test
+    public void testSortDesc() {
+        Selection.sort(origArr, false);
+        assertArrayEquals(String.format("测试降序,排序结果:%s", Arrays.toString(origArr)), descArr, origArr);
+    }
+}