From 11d23bf86a59611137cee6fba3578fc6d6093faf Mon Sep 17 00:00:00 2001 From: byhieg Date: Tue, 14 Mar 2017 10:45:52 +0800 Subject: [PATCH 01/34] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E8=AE=BE=E8=AE=A1?= =?UTF-8?q?=E6=A8=A1=E5=BC=8F=E7=9A=84=E6=95=99=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../singleton/SimpleSingleton.java | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 src/main/java/cn/byhieg/designpatterntutorial/singleton/SimpleSingleton.java diff --git a/src/main/java/cn/byhieg/designpatterntutorial/singleton/SimpleSingleton.java b/src/main/java/cn/byhieg/designpatterntutorial/singleton/SimpleSingleton.java new file mode 100644 index 0000000..78cd486 --- /dev/null +++ b/src/main/java/cn/byhieg/designpatterntutorial/singleton/SimpleSingleton.java @@ -0,0 +1,22 @@ +package cn.byhieg.designpatterntutorial.singleton; + +/** + * 该类线程不安全,是延迟加载的懒汉模式 + * Created by shiqifeng on 2017/3/14. + * Mail byhieg@gmail.com + */ +public class SimpleSingleton { + + private static SimpleSingleton simpleSingleton; + + private SimpleSingleton(){ + + } + + public static SimpleSingleton getInstance(){ + if (simpleSingleton == null) { + simpleSingleton = new SimpleSingleton(); + } + return simpleSingleton; + } +} From b11ae9167995a2740367f9738058b115173ad7fb Mon Sep 17 00:00:00 2001 From: byhieg Date: Tue, 14 Mar 2017 11:26:39 +0800 Subject: [PATCH 02/34] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E7=BA=BF=E7=A8=8B?= =?UTF-8?q?=E5=AE=89=E5=85=A8=E7=9A=84=E6=87=92=E6=B1=89=E5=86=99=E6=B3=95?= =?UTF-8?q?=E7=9A=84=E5=8D=95=E4=BE=8B=E6=A8=A1=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../singleton/DCLSingleton.java | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 src/main/java/cn/byhieg/designpatterntutorial/singleton/DCLSingleton.java diff --git a/src/main/java/cn/byhieg/designpatterntutorial/singleton/DCLSingleton.java b/src/main/java/cn/byhieg/designpatterntutorial/singleton/DCLSingleton.java new file mode 100644 index 0000000..d39d86e --- /dev/null +++ b/src/main/java/cn/byhieg/designpatterntutorial/singleton/DCLSingleton.java @@ -0,0 +1,26 @@ +package cn.byhieg.designpatterntutorial.singleton; + +/** + * Created by shiqifeng on 2017/3/14. + * Mail byhieg@gmail.com + */ +public class DCLSingleton { + + private static volatile DCLSingleton singleton; + + private DCLSingleton(){ + + } + + public static DCLSingleton getSingleton(){ + if (singleton == null) { + synchronized (DCLSingleton.class) { + if (singleton == null) { + singleton = new DCLSingleton(); + } + } + } + return singleton; + } + +} From 4aa73fc5ba62c0e2482160006a67e237ffda3d53 Mon Sep 17 00:00:00 2001 From: byhieg Date: Wed, 15 Mar 2017 16:19:52 +0800 Subject: [PATCH 03/34] =?UTF-8?q?=E5=AE=8C=E6=88=90=E4=B8=8B=E8=BD=BD?= =?UTF-8?q?=EF=BC=8C=E4=BD=86=E6=98=AF=E5=9B=9E=E8=B0=83=E7=9A=84=E8=A7=A6?= =?UTF-8?q?=E5=8F=91=E6=9C=89=E4=BA=9B=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../singleton/DCLSingleton.java | 2 ++ .../singleton/EnumSingleton.java | 14 +++++++++++++ .../singleton/HungrySingleton.java | 17 ++++++++++++++++ .../singleton/SimpleSingleton.java | 6 +++++- .../singleton/StaticSingleton.java | 20 +++++++++++++++++++ 5 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 src/main/java/cn/byhieg/designpatterntutorial/singleton/EnumSingleton.java create mode 100644 src/main/java/cn/byhieg/designpatterntutorial/singleton/HungrySingleton.java create mode 100644 src/main/java/cn/byhieg/designpatterntutorial/singleton/StaticSingleton.java diff --git a/src/main/java/cn/byhieg/designpatterntutorial/singleton/DCLSingleton.java b/src/main/java/cn/byhieg/designpatterntutorial/singleton/DCLSingleton.java index d39d86e..ba45d43 100644 --- a/src/main/java/cn/byhieg/designpatterntutorial/singleton/DCLSingleton.java +++ b/src/main/java/cn/byhieg/designpatterntutorial/singleton/DCLSingleton.java @@ -23,4 +23,6 @@ public static DCLSingleton getSingleton(){ return singleton; } + + } diff --git a/src/main/java/cn/byhieg/designpatterntutorial/singleton/EnumSingleton.java b/src/main/java/cn/byhieg/designpatterntutorial/singleton/EnumSingleton.java new file mode 100644 index 0000000..86c24cf --- /dev/null +++ b/src/main/java/cn/byhieg/designpatterntutorial/singleton/EnumSingleton.java @@ -0,0 +1,14 @@ +package cn.byhieg.designpatterntutorial.singleton; + +/** + * Created by shiqifeng on 2017/3/14. + * Mail byhieg@gmail.com + */ +public enum EnumSingleton { + SINGLETON; + + + public void doSometings(){ + + } +} diff --git a/src/main/java/cn/byhieg/designpatterntutorial/singleton/HungrySingleton.java b/src/main/java/cn/byhieg/designpatterntutorial/singleton/HungrySingleton.java new file mode 100644 index 0000000..d3ac705 --- /dev/null +++ b/src/main/java/cn/byhieg/designpatterntutorial/singleton/HungrySingleton.java @@ -0,0 +1,17 @@ +package cn.byhieg.designpatterntutorial.singleton; + +/** + * Created by shiqifeng on 2017/3/14. + * Mail byhieg@gmail.com + */ +public class HungrySingleton { + private static final HungrySingleton singleton = new HungrySingleton(); + + private HungrySingleton(){ + + } + +// public static HungrySingleton getSingleton(){ +// return singleton; +// } +} diff --git a/src/main/java/cn/byhieg/designpatterntutorial/singleton/SimpleSingleton.java b/src/main/java/cn/byhieg/designpatterntutorial/singleton/SimpleSingleton.java index 78cd486..fedad66 100644 --- a/src/main/java/cn/byhieg/designpatterntutorial/singleton/SimpleSingleton.java +++ b/src/main/java/cn/byhieg/designpatterntutorial/singleton/SimpleSingleton.java @@ -1,11 +1,13 @@ package cn.byhieg.designpatterntutorial.singleton; +import java.io.Serializable; + /** * 该类线程不安全,是延迟加载的懒汉模式 * Created by shiqifeng on 2017/3/14. * Mail byhieg@gmail.com */ -public class SimpleSingleton { +public class SimpleSingleton implements Serializable { private static SimpleSingleton simpleSingleton; @@ -19,4 +21,6 @@ public static SimpleSingleton getInstance(){ } return simpleSingleton; } + + } diff --git a/src/main/java/cn/byhieg/designpatterntutorial/singleton/StaticSingleton.java b/src/main/java/cn/byhieg/designpatterntutorial/singleton/StaticSingleton.java new file mode 100644 index 0000000..8a2ee20 --- /dev/null +++ b/src/main/java/cn/byhieg/designpatterntutorial/singleton/StaticSingleton.java @@ -0,0 +1,20 @@ +package cn.byhieg.designpatterntutorial.singleton; + +/** + * Created by shiqifeng on 2017/3/14. + * Mail byhieg@gmail.com + */ +public class StaticSingleton { + + private StaticSingleton(){ + } + + + public static final StaticSingleton getInstance(){ + return Holder.singleton; + } + + private static class Holder{ + private static final StaticSingleton singleton = new StaticSingleton(); + } +} From d907e7aef91e45688e7c5872e4f8ad88e98a9861 Mon Sep 17 00:00:00 2001 From: byhieg Date: Fri, 17 Mar 2017 11:10:03 +0800 Subject: [PATCH 04/34] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BB=A3=E7=90=86?= =?UTF-8?q?=E6=A8=A1=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../maptutorial/TreeMapExample.java | 1 - .../proxy/staticproxy/Client.java | 13 +++++++++++++ .../proxy/staticproxy/ProxySubject.java | 19 +++++++++++++++++++ .../proxy/staticproxy/RealSubject.java | 14 ++++++++++++++ .../proxy/staticproxy/Subject.java | 10 ++++++++++ 5 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 src/main/java/cn/byhieg/designpatterntutorial/proxy/staticproxy/Client.java create mode 100644 src/main/java/cn/byhieg/designpatterntutorial/proxy/staticproxy/ProxySubject.java create mode 100644 src/main/java/cn/byhieg/designpatterntutorial/proxy/staticproxy/RealSubject.java create mode 100644 src/main/java/cn/byhieg/designpatterntutorial/proxy/staticproxy/Subject.java diff --git a/src/main/java/cn/byhieg/collectiontutorial/maptutorial/TreeMapExample.java b/src/main/java/cn/byhieg/collectiontutorial/maptutorial/TreeMapExample.java index b791cbc..136999d 100644 --- a/src/main/java/cn/byhieg/collectiontutorial/maptutorial/TreeMapExample.java +++ b/src/main/java/cn/byhieg/collectiontutorial/maptutorial/TreeMapExample.java @@ -1,6 +1,5 @@ package cn.byhieg.collectiontutorial.maptutorial; -import apple.laf.JRSUIUtils; import java.util.Iterator; import java.util.Map; diff --git a/src/main/java/cn/byhieg/designpatterntutorial/proxy/staticproxy/Client.java b/src/main/java/cn/byhieg/designpatterntutorial/proxy/staticproxy/Client.java new file mode 100644 index 0000000..7e38f06 --- /dev/null +++ b/src/main/java/cn/byhieg/designpatterntutorial/proxy/staticproxy/Client.java @@ -0,0 +1,13 @@ +package cn.byhieg.designpatterntutorial.proxy.staticproxy; + +/** + * Created by shiqifeng on 2017/3/17. + * Mail byhieg@gmail.com + */ +public class Client { + + public static void main(String[] args) { + ProxySubject subject = new ProxySubject(new RealSubject()); + subject.visit(); + } +} diff --git a/src/main/java/cn/byhieg/designpatterntutorial/proxy/staticproxy/ProxySubject.java b/src/main/java/cn/byhieg/designpatterntutorial/proxy/staticproxy/ProxySubject.java new file mode 100644 index 0000000..9a6ed10 --- /dev/null +++ b/src/main/java/cn/byhieg/designpatterntutorial/proxy/staticproxy/ProxySubject.java @@ -0,0 +1,19 @@ +package cn.byhieg.designpatterntutorial.proxy.staticproxy; + +/** + * Created by shiqifeng on 2017/3/17. + * Mail byhieg@gmail.com + */ +public class ProxySubject implements Subject{ + + private Subject subject; + + public ProxySubject(Subject subject) { + this.subject = subject; + } + + @Override + public void visit() { + subject.visit(); + } +} diff --git a/src/main/java/cn/byhieg/designpatterntutorial/proxy/staticproxy/RealSubject.java b/src/main/java/cn/byhieg/designpatterntutorial/proxy/staticproxy/RealSubject.java new file mode 100644 index 0000000..9669e0b --- /dev/null +++ b/src/main/java/cn/byhieg/designpatterntutorial/proxy/staticproxy/RealSubject.java @@ -0,0 +1,14 @@ +package cn.byhieg.designpatterntutorial.proxy.staticproxy; + +/** + * Created by shiqifeng on 2017/3/17. + * Mail byhieg@gmail.com + */ +public class RealSubject implements Subject { + + private String name = "byhieg"; + @Override + public void visit() { + System.out.println(name); + } +} diff --git a/src/main/java/cn/byhieg/designpatterntutorial/proxy/staticproxy/Subject.java b/src/main/java/cn/byhieg/designpatterntutorial/proxy/staticproxy/Subject.java new file mode 100644 index 0000000..1e93880 --- /dev/null +++ b/src/main/java/cn/byhieg/designpatterntutorial/proxy/staticproxy/Subject.java @@ -0,0 +1,10 @@ +package cn.byhieg.designpatterntutorial.proxy.staticproxy; + +/** + * Created by shiqifeng on 2017/3/17. + * Mail byhieg@gmail.com + */ +public interface Subject { + + void visit(); +} From a34b33c46eb2e08316109fbeb9c0660d11959b04 Mon Sep 17 00:00:00 2001 From: byhieg Date: Fri, 17 Mar 2017 11:33:19 +0800 Subject: [PATCH 05/34] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=8A=A8=E6=80=81?= =?UTF-8?q?=E4=BB=A3=E7=90=86=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../proxy/dynamicproxy/DynamicProxy.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 src/main/java/cn/byhieg/designpatterntutorial/proxy/dynamicproxy/DynamicProxy.java diff --git a/src/main/java/cn/byhieg/designpatterntutorial/proxy/dynamicproxy/DynamicProxy.java b/src/main/java/cn/byhieg/designpatterntutorial/proxy/dynamicproxy/DynamicProxy.java new file mode 100644 index 0000000..abe4fe1 --- /dev/null +++ b/src/main/java/cn/byhieg/designpatterntutorial/proxy/dynamicproxy/DynamicProxy.java @@ -0,0 +1,18 @@ +package cn.byhieg.designpatterntutorial.proxy.dynamicproxy; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; + +/** + * Created by shiqifeng on 2017/3/17. + * Mail byhieg@gmail.com + */ +public class DynamicProxy implements InvocationHandler { + private Object object; + + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + Object result = method.invoke(object, args); + return result; + } +} From 5af7b236085deaab8316e8f6f802109e0a05377a Mon Sep 17 00:00:00 2001 From: byhieg Date: Tue, 28 Mar 2017 16:21:36 +0800 Subject: [PATCH 06/34] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=8E=92=E5=BA=8F?= =?UTF-8?q?=E7=AE=97=E6=B3=95=EF=BC=8C=E9=80=89=E6=8B=A9=EF=BC=8C=E6=8F=92?= =?UTF-8?q?=E5=85=A5=EF=BC=8C=E5=86=92=E6=B3=A1=EF=BC=8C=E5=BF=AB=E6=8E=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/byhieg/algorithmtutorial/Sort.java | 176 ++++++++++++++++++ .../proxy/dynamicproxy/Client.java | 19 ++ .../proxy/dynamicproxy/DynamicProxy.java | 5 + .../proxy/dynamicproxy/RealSubject.java | 15 ++ .../proxy/dynamicproxy/Subject.java | 10 + .../algorithmtutorialtest/SortTest.java | 44 +++++ 6 files changed, 269 insertions(+) create mode 100644 src/main/java/cn/byhieg/algorithmtutorial/Sort.java create mode 100644 src/main/java/cn/byhieg/designpatterntutorial/proxy/dynamicproxy/Client.java create mode 100644 src/main/java/cn/byhieg/designpatterntutorial/proxy/dynamicproxy/RealSubject.java create mode 100644 src/main/java/cn/byhieg/designpatterntutorial/proxy/dynamicproxy/Subject.java create mode 100644 src/test/java/cn/byhieg/algorithmtutorialtest/SortTest.java diff --git a/src/main/java/cn/byhieg/algorithmtutorial/Sort.java b/src/main/java/cn/byhieg/algorithmtutorial/Sort.java new file mode 100644 index 0000000..57c8b5f --- /dev/null +++ b/src/main/java/cn/byhieg/algorithmtutorial/Sort.java @@ -0,0 +1,176 @@ +package cn.byhieg.algorithmtutorial; + +/** + * Created by shiqifeng on 2017/3/28. + * Mail byhieg@gmail.com + */ +public class Sort { + + /** + * 选择排序,每一轮排序,选择数组中数字最小的那一个放到指定的位置上。 + * 时间复杂度o(n^2),无论数组顺序如何都要选择一个最小的值,因为数组的是否有序,不影响时间复杂度 + * 空间复杂度o(1) + * @param nums + */ + public void chooseSort(int[] nums) { + int length = nums.length; + for (int i = 0; i < length; i++) { + int min = i;//申请额外的空间o(1) + for (int j = i + 1; j < length; j++) { + if (nums[min] > nums[j]) { + min = j; + } + } + //将最小的下标代表的数与i位置的进行交换 + int tmp = nums[i]; + nums[i] = nums[min]; + nums[min] = tmp; + } + } + + /** + * 直接插入排序,每一轮排序,都是在i坐标之前,包括i坐标的序列是有序的,但是并不是最终的排序位置。 + * 时间复杂度o(n^2),对于第二重循环,只会在非有序的环境下才会执行每个元素后移,因此针对有序的数组,时间复杂度最好的情况是o(N)。 + * 空间复杂度o(1) + * @param nums + */ + public void insertDirectlySort(int[] nums) { + int length = nums.length; + for (int i = 1; i < length; i++) { + for (int j = i ; j > 0; j --) { + if (nums[j] < nums[j - 1]) { + int tmp = nums[j - 1]; + nums[j - 1] = nums[j]; + nums[j] = tmp; + } + } + } + } + + /** + * 折半插入排序,针对直接排序而言,每一个要插入的元素都是插入在有序的数组中,因此,只需要查找到插入的位置即可,查找的方式利用二分查找 + * 时间复杂度和直接插入是一样的,只是快在了查找的过程中,还是o(N^2),最好的环境下是o(N) + * 空间复杂度还是o(1) + * @param nums + */ + public void insertBinarySort(int[] nums) { + int length = nums.length; + for (int i = 1; i < length;i++) { + int tmp = nums[i]; + int low = 0; + int high = i - 1; + while (low <= high) { + int mid = (low + high) / 2; + if (tmp < nums[mid]) { + high = mid - 1; + }else{ + low = mid + 1; + } + } + + for (int j = i; j >= low + 1;j--) { + nums[j] = nums[j - 1]; + } + nums[low] = tmp; + } + } + + /** + * 冒泡排序,每i轮排序,就是不断交换两个元素,直到将最大的元素放到n - i的位置上 + * 这种实现是按照算法定义的,但是效率是最低的 + * 时间复杂度o(n^2) + * 空间复杂度o(1) + * @param nums + */ + public void bubbleSort1(int[] nums) { + int length = nums.length; + for (int i = 1 ; i < length;i++) { + for (int j = 0 ; j < length - i;j++) { + if (nums[j] > nums[j + 1]) { + int tmp = nums[j]; + nums[j] = nums[j + 1]; + nums[j+1] = tmp; + } + } + } + } + + /** + * 冒泡排序,高效率实现,因为只需要用一个flag变量来记录本次的排序,是否修改 + * 如果没有修改,说明已经有序 + * @param nums + */ + public void bubbleSort2(int[] nums) { + int length = nums.length; + boolean flag = true; + while (flag) { + flag = false; + for (int j = 0 ; j < length - 1;j++) { + if (nums[j] > nums[j + 1]) { + int tmp = nums[j]; + nums[j] = nums[j + 1]; + nums[j + 1] = tmp; + flag = true; + } + } + length -- ; + } + } + + /** + * 快速排序,选定一个切分元素,每一轮排序后,都保证切分元素之前的元素都小于切分元素,切分元素之后的元素都大于切分元素 + * + * @param nums + */ + public void quickSort(int[] nums) { + int low = 0; + int high = nums.length - 1; + sort(nums, low, high); + } + + /** + * 快速排序的递归实现 + * @param nums + * @param low + * @param high + */ + public void sort(int[] nums, int low, int high) { + if (low >= high) return; + int j = partition(nums, low, high); + sort(nums, low, j - 1); + sort(nums, j + 1, high); + } + + /** + * 快速排序的辅助方法,来对排序的数组,进行切分, + * @param nums + * @param low + * @param high + * @return + */ + public int partition(int[] nums, int low, int high) { + int i = low; + int j = high; + int x = nums[i]; + while (i < j) { + //从右向左找到nums[j]小于x的元素 + while (i < j && nums[j] > x) j-- ; + if (i < j) { + nums[i] = nums[j]; + i++; + } + + //从左向右找到nums[i]大于x的元素 + while (i < j && nums[i] < x) i++; + if (i < j) { + nums[j] = nums[i]; + j--; + } + } + nums[i] = x; + return i; + } + + + +} diff --git a/src/main/java/cn/byhieg/designpatterntutorial/proxy/dynamicproxy/Client.java b/src/main/java/cn/byhieg/designpatterntutorial/proxy/dynamicproxy/Client.java new file mode 100644 index 0000000..6d6a78d --- /dev/null +++ b/src/main/java/cn/byhieg/designpatterntutorial/proxy/dynamicproxy/Client.java @@ -0,0 +1,19 @@ +package cn.byhieg.designpatterntutorial.proxy.dynamicproxy; + + +import java.lang.reflect.Proxy; + +/** + * Created by shiqifeng on 2017/3/17. + * Mail byhieg@gmail.com + */ +public class Client { + + public static void main(String[] args) { + Subject realSubject = new RealSubject(); + DynamicProxy proxy = new DynamicProxy(realSubject); + ClassLoader classLoader = realSubject.getClass().getClassLoader(); + Subject subject = (Subject) Proxy.newProxyInstance(classLoader, new Class[]{Subject.class}, proxy); + subject.visit(); + } +} diff --git a/src/main/java/cn/byhieg/designpatterntutorial/proxy/dynamicproxy/DynamicProxy.java b/src/main/java/cn/byhieg/designpatterntutorial/proxy/dynamicproxy/DynamicProxy.java index abe4fe1..5589d9c 100644 --- a/src/main/java/cn/byhieg/designpatterntutorial/proxy/dynamicproxy/DynamicProxy.java +++ b/src/main/java/cn/byhieg/designpatterntutorial/proxy/dynamicproxy/DynamicProxy.java @@ -10,6 +10,11 @@ public class DynamicProxy implements InvocationHandler { private Object object; + + public DynamicProxy(Object object) { + this.object = object; + } + @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = method.invoke(object, args); diff --git a/src/main/java/cn/byhieg/designpatterntutorial/proxy/dynamicproxy/RealSubject.java b/src/main/java/cn/byhieg/designpatterntutorial/proxy/dynamicproxy/RealSubject.java new file mode 100644 index 0000000..ab391f7 --- /dev/null +++ b/src/main/java/cn/byhieg/designpatterntutorial/proxy/dynamicproxy/RealSubject.java @@ -0,0 +1,15 @@ +package cn.byhieg.designpatterntutorial.proxy.dynamicproxy; + + +/** + * Created by shiqifeng on 2017/3/17. + * Mail byhieg@gmail.com + */ +public class RealSubject implements Subject { + + private String name = "byhieg"; + @Override + public void visit() { + System.out.println(name); + } +} diff --git a/src/main/java/cn/byhieg/designpatterntutorial/proxy/dynamicproxy/Subject.java b/src/main/java/cn/byhieg/designpatterntutorial/proxy/dynamicproxy/Subject.java new file mode 100644 index 0000000..f662e32 --- /dev/null +++ b/src/main/java/cn/byhieg/designpatterntutorial/proxy/dynamicproxy/Subject.java @@ -0,0 +1,10 @@ +package cn.byhieg.designpatterntutorial.proxy.dynamicproxy; + +/** + * Created by shiqifeng on 2017/3/17. + * Mail byhieg@gmail.com + */ +public interface Subject { + + void visit(); +} diff --git a/src/test/java/cn/byhieg/algorithmtutorialtest/SortTest.java b/src/test/java/cn/byhieg/algorithmtutorialtest/SortTest.java new file mode 100644 index 0000000..6bf1bc1 --- /dev/null +++ b/src/test/java/cn/byhieg/algorithmtutorialtest/SortTest.java @@ -0,0 +1,44 @@ +package cn.byhieg.algorithmtutorialtest; + +import cn.byhieg.algorithmtutorial.Sort; +import junit.framework.TestCase; + +/** + * Created by shiqifeng on 2017/3/28. + * Mail byhieg@gmail.com + */ +public class SortTest extends TestCase { + int [] nums; + public void setUp() throws Exception { + super.setUp(); + nums = new int[]{10, 20, 2, 3, 1, 100, 45, 22, 51, 21}; + } + + public void tearDown() throws Exception { + for (int i = 0 ; i < nums.length;i++){ + System.out.print(nums[i] + " "); + } + } + +// public void testChooseSort() throws Exception { +// new Sort().chooseSort(nums); +// } + + +// public void testInsertDirectlySort() throws Exception { +// new Sort().insertDirectlySort(nums); +// } + +// public void testInsertBinarySort() throws Exception { +// new Sort().insertBinarySort(nums); +// } + +// public void testBubbleSort() throws Exception { +// new Sort().bubbleSort2(nums); +// } + + public void testQuickSort() throws Exception { + new Sort().quickSort(nums); + } + +} \ No newline at end of file From 7bc7130804ce5617e215274ad5fe846afa6dbd54 Mon Sep 17 00:00:00 2001 From: byhieg Date: Tue, 28 Mar 2017 20:00:01 +0800 Subject: [PATCH 07/34] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=A0=86=E6=8E=92?= =?UTF-8?q?=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/byhieg/algorithmtutorial/Sort.java | 112 +++++++++++++++--- .../algorithmtutorialtest/SortTest.java | 28 +++-- 2 files changed, 111 insertions(+), 29 deletions(-) diff --git a/src/main/java/cn/byhieg/algorithmtutorial/Sort.java b/src/main/java/cn/byhieg/algorithmtutorial/Sort.java index 57c8b5f..d4427a9 100644 --- a/src/main/java/cn/byhieg/algorithmtutorial/Sort.java +++ b/src/main/java/cn/byhieg/algorithmtutorial/Sort.java @@ -10,6 +10,7 @@ public class Sort { * 选择排序,每一轮排序,选择数组中数字最小的那一个放到指定的位置上。 * 时间复杂度o(n^2),无论数组顺序如何都要选择一个最小的值,因为数组的是否有序,不影响时间复杂度 * 空间复杂度o(1) + * * @param nums */ public void chooseSort(int[] nums) { @@ -32,18 +33,19 @@ public void chooseSort(int[] nums) { * 直接插入排序,每一轮排序,都是在i坐标之前,包括i坐标的序列是有序的,但是并不是最终的排序位置。 * 时间复杂度o(n^2),对于第二重循环,只会在非有序的环境下才会执行每个元素后移,因此针对有序的数组,时间复杂度最好的情况是o(N)。 * 空间复杂度o(1) + * * @param nums */ public void insertDirectlySort(int[] nums) { int length = nums.length; for (int i = 1; i < length; i++) { - for (int j = i ; j > 0; j --) { - if (nums[j] < nums[j - 1]) { - int tmp = nums[j - 1]; - nums[j - 1] = nums[j]; - nums[j] = tmp; - } - } + for (int j = i; j > 0; j--) { + if (nums[j] < nums[j - 1]) { + int tmp = nums[j - 1]; + nums[j - 1] = nums[j]; + nums[j] = tmp; + } + } } } @@ -51,11 +53,12 @@ public void insertDirectlySort(int[] nums) { * 折半插入排序,针对直接排序而言,每一个要插入的元素都是插入在有序的数组中,因此,只需要查找到插入的位置即可,查找的方式利用二分查找 * 时间复杂度和直接插入是一样的,只是快在了查找的过程中,还是o(N^2),最好的环境下是o(N) * 空间复杂度还是o(1) + * * @param nums */ public void insertBinarySort(int[] nums) { int length = nums.length; - for (int i = 1; i < length;i++) { + for (int i = 1; i < length; i++) { int tmp = nums[i]; int low = 0; int high = i - 1; @@ -63,12 +66,12 @@ public void insertBinarySort(int[] nums) { int mid = (low + high) / 2; if (tmp < nums[mid]) { high = mid - 1; - }else{ + } else { low = mid + 1; } } - for (int j = i; j >= low + 1;j--) { + for (int j = i; j >= low + 1; j--) { nums[j] = nums[j - 1]; } nums[low] = tmp; @@ -80,16 +83,17 @@ public void insertBinarySort(int[] nums) { * 这种实现是按照算法定义的,但是效率是最低的 * 时间复杂度o(n^2) * 空间复杂度o(1) + * * @param nums */ public void bubbleSort1(int[] nums) { int length = nums.length; - for (int i = 1 ; i < length;i++) { - for (int j = 0 ; j < length - i;j++) { + for (int i = 1; i < length; i++) { + for (int j = 0; j < length - i; j++) { if (nums[j] > nums[j + 1]) { int tmp = nums[j]; nums[j] = nums[j + 1]; - nums[j+1] = tmp; + nums[j + 1] = tmp; } } } @@ -98,6 +102,7 @@ public void bubbleSort1(int[] nums) { /** * 冒泡排序,高效率实现,因为只需要用一个flag变量来记录本次的排序,是否修改 * 如果没有修改,说明已经有序 + * * @param nums */ public void bubbleSort2(int[] nums) { @@ -105,7 +110,7 @@ public void bubbleSort2(int[] nums) { boolean flag = true; while (flag) { flag = false; - for (int j = 0 ; j < length - 1;j++) { + for (int j = 0; j < length - 1; j++) { if (nums[j] > nums[j + 1]) { int tmp = nums[j]; nums[j] = nums[j + 1]; @@ -113,12 +118,14 @@ public void bubbleSort2(int[] nums) { flag = true; } } - length -- ; + length--; } } /** * 快速排序,选定一个切分元素,每一轮排序后,都保证切分元素之前的元素都小于切分元素,切分元素之后的元素都大于切分元素 + * 时间复杂度o(NlgN) + * 空间复杂度o(lgN) * * @param nums */ @@ -130,6 +137,7 @@ public void quickSort(int[] nums) { /** * 快速排序的递归实现 + * * @param nums * @param low * @param high @@ -143,6 +151,7 @@ public void sort(int[] nums, int low, int high) { /** * 快速排序的辅助方法,来对排序的数组,进行切分, + * * @param nums * @param low * @param high @@ -154,7 +163,7 @@ public int partition(int[] nums, int low, int high) { int x = nums[i]; while (i < j) { //从右向左找到nums[j]小于x的元素 - while (i < j && nums[j] > x) j-- ; + while (i < j && nums[j] > x) j--; if (i < j) { nums[i] = nums[j]; i++; @@ -171,6 +180,75 @@ public int partition(int[] nums, int low, int high) { return i; } - + + /** + * 堆排序,建立一个小顶堆,小顶堆满足父节点比两个子节点的值要小 + * 堆的性质满足:1. 只能在堆顶删除元素 + * 2. 只能在堆的最后一位存元素。 + * 3. 堆的存储利用数组,满足i节点是父节点,则子节点是2 * i+ 1,2 * i + 2 + * 4. 堆的两种建方法,第一种是从上到下,@see sink(),第二种是从下到上 @see swim + * 5. 堆排序是指在弄好的堆中,输出第一个元素,然后将最后一个元素与第一个元素互换,换后调用sink,找到自己的位置后,在重复这个步骤,就输出一个有序的堆 + * 6. 如果要生序就需要大顶堆,要降序就需要小顶堆。 + * 时间复杂度:o(NlgN) + * 空间复杂度: o(1) + * 这是小顶堆的排序,所以nums数组最后是降序的 + * @param nums + */ + public void heapSort(int[] nums) { + int length = nums.length; + for (int i = 0; i < length; i++) { + swim(nums, i); + } + while (length > 0) { + int temp = nums[0]; + nums[0] = nums[length - 1]; + nums[length - 1] = temp; + length--; + sink(nums, 0, length); + } + } + + /** + * 将i放入对堆中,i的父节点是(i - 1)/ 2,父节点的值是小于他的两个子节点的 + * i节点放入后,要向上移动,如果父节点比i节点的值大,则i节点要继续上移。 + * + * @param nums + * @param i + */ + private void swim(int nums[], int i) { + while (i > 0) { + int father = (i - 1) / 2; + if (nums[father] > nums[i]) { + int temp = nums[father]; + nums[father] = nums[i]; + nums[i] = temp; + } + i = father; + } + } + + + /** + * 从i节点由上到下开始调整,i节点的子节点为2*i + 1, 2 * i + 2 + * i节点要向下移动,直到满足i节点小于两个子节点 + * + * @param nums nums[] 数组 + * @param i i节点 + */ + public void sink(int nums[], int i,int n) { + int son = 2 * i + 1; + while (son <= n - 1) { + if (son < n - 1 && nums[son] > nums[son + 1]) son++; + if (nums[i] > nums[son]) { + int temp = nums[i]; + nums[i] = nums[son]; + nums[son] = temp; + i = son; + } else { + break; + } + } + } + } diff --git a/src/test/java/cn/byhieg/algorithmtutorialtest/SortTest.java b/src/test/java/cn/byhieg/algorithmtutorialtest/SortTest.java index 6bf1bc1..65b128e 100644 --- a/src/test/java/cn/byhieg/algorithmtutorialtest/SortTest.java +++ b/src/test/java/cn/byhieg/algorithmtutorialtest/SortTest.java @@ -20,25 +20,29 @@ public void tearDown() throws Exception { } } -// public void testChooseSort() throws Exception { -// new Sort().chooseSort(nums); -// } + public void testChooseSort() throws Exception { + new Sort().chooseSort(nums); + } -// public void testInsertDirectlySort() throws Exception { -// new Sort().insertDirectlySort(nums); -// } + public void testInsertDirectlySort() throws Exception { + new Sort().insertDirectlySort(nums); + } -// public void testInsertBinarySort() throws Exception { -// new Sort().insertBinarySort(nums); -// } + public void testInsertBinarySort() throws Exception { + new Sort().insertBinarySort(nums); + } -// public void testBubbleSort() throws Exception { -// new Sort().bubbleSort2(nums); -// } + public void testBubbleSort() throws Exception { + new Sort().bubbleSort2(nums); + } public void testQuickSort() throws Exception { new Sort().quickSort(nums); } + public void testHeapSort() throws Exception { + new Sort().heapSort(nums); + } + } \ No newline at end of file From 36aea2e2d8e4bd0cd2a97e1b27ea65f13b1b6ac0 Mon Sep 17 00:00:00 2001 From: byhieg Date: Tue, 28 Mar 2017 21:02:40 +0800 Subject: [PATCH 08/34] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BA=86=E5=AF=B9?= =?UTF-8?q?=E6=8E=92=E5=BA=8F=E7=AE=97=E6=B3=95=E7=A8=B3=E5=AE=9A=E6=80=A7?= =?UTF-8?q?=E5=88=A4=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/cn/byhieg/algorithmtutorial/Sort.java | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/main/java/cn/byhieg/algorithmtutorial/Sort.java b/src/main/java/cn/byhieg/algorithmtutorial/Sort.java index d4427a9..74cc832 100644 --- a/src/main/java/cn/byhieg/algorithmtutorial/Sort.java +++ b/src/main/java/cn/byhieg/algorithmtutorial/Sort.java @@ -10,7 +10,7 @@ public class Sort { * 选择排序,每一轮排序,选择数组中数字最小的那一个放到指定的位置上。 * 时间复杂度o(n^2),无论数组顺序如何都要选择一个最小的值,因为数组的是否有序,不影响时间复杂度 * 空间复杂度o(1) - * + * 不稳定排序 * @param nums */ public void chooseSort(int[] nums) { @@ -33,13 +33,14 @@ public void chooseSort(int[] nums) { * 直接插入排序,每一轮排序,都是在i坐标之前,包括i坐标的序列是有序的,但是并不是最终的排序位置。 * 时间复杂度o(n^2),对于第二重循环,只会在非有序的环境下才会执行每个元素后移,因此针对有序的数组,时间复杂度最好的情况是o(N)。 * 空间复杂度o(1) - * + * 稳定排序 * @param nums */ public void insertDirectlySort(int[] nums) { int length = nums.length; for (int i = 1; i < length; i++) { for (int j = i; j > 0; j--) { + //这一步导致该算法是稳定排序 if (nums[j] < nums[j - 1]) { int tmp = nums[j - 1]; nums[j - 1] = nums[j]; @@ -83,13 +84,14 @@ public void insertBinarySort(int[] nums) { * 这种实现是按照算法定义的,但是效率是最低的 * 时间复杂度o(n^2) * 空间复杂度o(1) - * + * 稳定排序 * @param nums */ public void bubbleSort1(int[] nums) { int length = nums.length; for (int i = 1; i < length; i++) { for (int j = 0; j < length - i; j++) { + //这一步导致该算法是稳定排序 if (nums[j] > nums[j + 1]) { int tmp = nums[j]; nums[j] = nums[j + 1]; @@ -126,7 +128,7 @@ public void bubbleSort2(int[] nums) { * 快速排序,选定一个切分元素,每一轮排序后,都保证切分元素之前的元素都小于切分元素,切分元素之后的元素都大于切分元素 * 时间复杂度o(NlgN) * 空间复杂度o(lgN) - * + * 不稳定排序 * @param nums */ public void quickSort(int[] nums) { @@ -192,12 +194,16 @@ public int partition(int[] nums, int low, int high) { * 时间复杂度:o(NlgN) * 空间复杂度: o(1) * 这是小顶堆的排序,所以nums数组最后是降序的 + * 不稳定,不稳定的原因在建堆的时候,就可能把相同元素的位置换了,比如两个相同元素在不同的子树上 * @param nums */ public void heapSort(int[] nums) { int length = nums.length; - for (int i = 0; i < length; i++) { - swim(nums, i); +// for (int i = 0; i < length; i++) { +// swim(nums, i); +// } + for (int i = length / 2 ; i >= 0;i--) { + sink(nums,i,length); } while (length > 0) { int temp = nums[0]; From b26e8b4d338bdfcdf9c39ee1f10d761bea9b2053 Mon Sep 17 00:00:00 2001 From: byhieg Date: Wed, 29 Mar 2017 23:15:10 +0800 Subject: [PATCH 09/34] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BA=8C=E6=9F=A5?= =?UTF-8?q?=E6=9F=A5=E6=89=BE=E7=9A=84=E4=B8=89=E7=A7=8D=E6=83=85=E5=86=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/byhieg/algorithmtutorial/Find.java | 83 +++++++++++++++++++ .../maptutorial/HashMapExample.java | 4 +- .../algorithmtutorialtest/FindTest.java | 34 ++++++++ 3 files changed, 118 insertions(+), 3 deletions(-) create mode 100644 src/main/java/cn/byhieg/algorithmtutorial/Find.java create mode 100644 src/test/java/cn/byhieg/algorithmtutorialtest/FindTest.java diff --git a/src/main/java/cn/byhieg/algorithmtutorial/Find.java b/src/main/java/cn/byhieg/algorithmtutorial/Find.java new file mode 100644 index 0000000..ff548c6 --- /dev/null +++ b/src/main/java/cn/byhieg/algorithmtutorial/Find.java @@ -0,0 +1,83 @@ +package cn.byhieg.algorithmtutorial; + +/** + * Created by shiqifeng on 2017/3/29. + * Mail byhieg@gmail.com + */ +public class Find { + + + /** + * 二查查找算法,要求准确找到目标值,没有找到则是-1. + * 此方法保证在相同元素都满足条件时,取到的是最大的下标 + * 时间复杂度 o(lgN) + * @param nums int型数组,要求有序 + * @return 找到,返回下标,没找到,返回-1 + */ + public int binarySerachFind(int[] nums,int des) { + int length = nums.length; + int low = 0; + int high = length - 1; + while (low < high) { + int mid = low + (high - low) / 2; + if (nums[mid] == des) { + return mid; + } else if (nums[mid] < des) { + low = mid + 1; + } else{ + high = mid - 1; + } + } + return -1; + } + + /** + * 给定一个单调不降的数组,查找大于des条件的最小的数 + * @param nums + * @param des + * @return + */ + public int binarySearchMinFind(int[] nums, int des) { + int length = nums.length; + int low = 0; + int high = length - 1; + int mid ; + while (low < high) { + mid = (low + high) / 2; + if (nums[mid] <= des){ + low = mid + 1; + }else{ + high = mid; + } + } + if (nums[high] > des) return high; + return -1; + } + + /** + * 给定一个单调不降的数组,查找小于des条件的最大的数 + * @param nums + * @param des + * @return + */ + public int binarySearchMaxFind(int[] nums, int des) { + int length = nums.length; + int low = 0; + int high = length - 1; + int mid; + int result = -1; + while (low < high) { + mid = low + (high - low + 1) / 2; + if (nums[mid] < des){ + low = mid; + }else{ + high = mid - 1; + } + } + if (nums[low] < des) return low; + return -1; + } + + + +} diff --git a/src/main/java/cn/byhieg/collectiontutorial/maptutorial/HashMapExample.java b/src/main/java/cn/byhieg/collectiontutorial/maptutorial/HashMapExample.java index e3a51ac..9e55ef1 100644 --- a/src/main/java/cn/byhieg/collectiontutorial/maptutorial/HashMapExample.java +++ b/src/main/java/cn/byhieg/collectiontutorial/maptutorial/HashMapExample.java @@ -1,8 +1,6 @@ package cn.byhieg.collectiontutorial.maptutorial; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; +import java.util.*; /** * Created by shiqifeng on 2017/2/24. diff --git a/src/test/java/cn/byhieg/algorithmtutorialtest/FindTest.java b/src/test/java/cn/byhieg/algorithmtutorialtest/FindTest.java new file mode 100644 index 0000000..beef69c --- /dev/null +++ b/src/test/java/cn/byhieg/algorithmtutorialtest/FindTest.java @@ -0,0 +1,34 @@ +package cn.byhieg.algorithmtutorialtest; + +import cn.byhieg.algorithmtutorial.Find; +import junit.framework.TestCase; + +/** + * Created by shiqifeng on 2017/3/29. + * Mail byhieg@gmail.com + */ +public class FindTest extends TestCase { + int[] nums; + int result; + public void setUp() throws Exception { + super.setUp(); + nums = new int[]{1}; + } + + public void tearDown() throws Exception { + System.out.println(result); + } + +// public void testBinarySerachFind() throws Exception { +// result = new Find().binarySerachFind(nums,6); +// } +//// +// public void testBinarySearchMinFind() throws Exception { +// result = new Find().binarySearchMinFind(nums,1); +// } + + public void testBinarySearchMaxFind() throws Exception { + result = new Find().binarySearchMaxFind(nums, 2); + } + +} \ No newline at end of file From 769ffdd6c855975b01568054fdf7aa6d12d192c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=9F=B3=E7=90=A6=E5=B3=B0?= Date: Thu, 30 Mar 2017 21:34:16 +0800 Subject: [PATCH 10/34] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BA=8C=E5=8F=89?= =?UTF-8?q?=E6=90=9C=E7=B4=A2=E6=A0=91=EF=BC=8C=E4=BB=A5=E5=8F=8A=E6=A0=91?= =?UTF-8?q?=E7=9A=84=E5=85=88=E5=BA=8F=EF=BC=8C=E4=B8=AD=E5=BA=8F=EF=BC=8C?= =?UTF-8?q?=E5=90=8E=E5=BA=8F=E9=80=92=E5=BD=92=E5=92=8C=E9=9D=9E=E9=80=92?= =?UTF-8?q?=E5=BD=92=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../algorithmtutorial/BinarySearchTree.java | 258 ++++++++++++++++++ .../BinarySearchTreeTest.java | 53 ++++ 2 files changed, 311 insertions(+) create mode 100644 src/main/java/cn/byhieg/algorithmtutorial/BinarySearchTree.java create mode 100644 src/test/java/cn/byhieg/collectiontutorialtest/BinarySearchTreeTest.java diff --git a/src/main/java/cn/byhieg/algorithmtutorial/BinarySearchTree.java b/src/main/java/cn/byhieg/algorithmtutorial/BinarySearchTree.java new file mode 100644 index 0000000..ccb787d --- /dev/null +++ b/src/main/java/cn/byhieg/algorithmtutorial/BinarySearchTree.java @@ -0,0 +1,258 @@ +package cn.byhieg.algorithmtutorial; + +/** + * Created by byhieg on 17/3/30. + * Mail to byhieg@gmail.com + */ + +import java.util.Stack; + +/** + * 该类是二叉搜索树 + * 该树在实现的时候,不考虑数组中有重复的数字。 + * 节点的左子节点的值都小于这个节点的值,节点的右子节点的值都大于等于这个节点的值 + */ +public class BinarySearchTree { + + private Node root; + + + public BinarySearchTree(){ + + } + + + public BinarySearchTree(int[] nums) { + Node[] nodes = new Node[nums.length]; + for (int i = 0 ; i < nums.length;i++) { + nodes[i] = new Node(nums[i]); + insert(nodes[i]); + } + } + + /** + * 查找指定的元素 + * @param des + * @return + */ + public Node find(int des){ + if (root == null) { + System.out.println("树是空的"); + throw new RuntimeException(); + } + Node current = root; + while (current.data != des) { + if (current.data < des) { + current = current.right; + }else{ + current = current.left; + } + if (current == null) return null; + } + return current; + } + + /** + * 对BST执行插入操作,采用非递归的形式 + * 保证插入后,左节点的值小于根节点的值,根节点的值小于右节点的值 + * @param node + * @return + */ + public boolean insert(Node node){ + if (root == null) { + root = node; + return true; + } + + if (find(node.data) != null) { + System.out.println("不允许插入相同data的数"); + throw new RuntimeException(); + } + + Node current = root; + while (current != null) { + if (current.data < node.data) { + if (current.right == null) { + current.right = node; + return true; + } + current = current.right; + }else{ + if (current.left == null) { + current.left = node; + return true; + } + current = current.left; + } + } + return false; + + } + + /** + * 树的前序遍历,递归实现 + */ + public void preOrder(Node node) { + System.out.print(node.data + "-->"); + if (node.left != null) { + preOrder(node.left); + } + if (node.right != null) { + preOrder(node.right); + } + } + + /** + * 树的中序遍历,递归实现 + * 针对BST,该结果会从小到大输出树 + * @param node + */ + public void inOrder(Node node){ + if (node.left != null) { + inOrder(node.left); + } + System.out.print(node.data + "-->"); + if (node.right != null) { + inOrder(node.right); + } + } + + /** + * 树的后续遍历,递归实现 + */ + public void postOrder(Node node){ + if (node.left != null) { + postOrder(node.left); + } + if (node.right != null) { + postOrder(node.right); + } + System.out.print(node.data + "-->"); + } + + + /** + * 树的先续遍历,非递归实现 + * 1. 建立一个栈,现将头结点压入栈中。 + * 2. 现将每出栈一个节点,打印他的值,然后都要先加入他的右节点,在加入他的左节点。因为栈的后进先出的特性,才能让左边先出。 + * 3. 不断重复2,直到栈空 + * + */ + public void preOrder2(Node node) { + if (node != null) { + Stack stack = new Stack<>(); + stack.push(node); + while (!stack.isEmpty()) { + Node tmp = stack.pop(); + System.out.print(tmp.data + "-->"); + if (tmp.right != null) { + stack.push(tmp.right); + } + if (tmp.left != null) { + stack.push(tmp.left); + } + } + } + } + + /** + * 树的中序遍历,非递归实现 + * 1. 设定cur,初始化cur = root节点,不断遍历里cur.left,并将其压入栈中,直到null。 + * 2. 出栈一个节点,打印他的值,然后cur = node.right,并不断重复第二步 + * 3. 当栈为空,并且cur为空时,停止 + */ + public void inorder2(Node node){ + if (node != null) { + Stack stack = new Stack<>(); + Node cur = node; + while (!stack.isEmpty() || cur != null) { + if (cur == null) { + cur = stack.pop(); + System.out.print(cur.data + "-->"); + cur = cur.right; + }else{ + stack.push(cur); + cur = cur.left; + } + } + } + } + + /** + * 树的后续遍历,非递归实现 + * 1. 树的先续遍历中,是栈存放顺序是根,右节点,左节点。 + * 2. 我们可以将其反过来,用栈存放是根,左节点,右节点。然后出栈的时候,将出栈的结果存放到另一个栈里。 + * 3. 第二栈里的顺序从上到下就是左节点,右节点,根的顺序。 + * @param node + */ + + public void postOrder2(Node node) { + if (node != null) { + Stack stack = new Stack<>(); + Stack result = new Stack<>(); + Node cur = node; + stack.push(cur); + while (!stack.isEmpty()){ + Node tmp = stack.pop(); + result.push(tmp); + if (tmp.left != null) { + stack.push(tmp.left); + } + if (tmp.right != null) { + stack.push(tmp.right); + } + } + + while (!result.isEmpty()) { + System.out.print(result.pop().data + "-->"); + } + } + } + + + /** + * 得到树中最小的节点 + * @return + */ + public Node getMinNode(){ + if (root == null) { + throw new RuntimeException("树为空"); + } + Node current = root; + while (current.left != null) { + current = current.left; + } + return current; + + } + + /** + * 得到树中最大的节点 + * @return + */ + public Node getMaxNode(){ + if (root == null) { + throw new RuntimeException("树为空"); + } + Node current = root; + while (current.right != null) { + current = current.right; + } + + return current; + } + + public static class Node{ + public int data; + public Node left; + public Node right; + + public Node(int data){ + this.data = data; + } + } + + public Node getRoot() { + return root; + } +} diff --git a/src/test/java/cn/byhieg/collectiontutorialtest/BinarySearchTreeTest.java b/src/test/java/cn/byhieg/collectiontutorialtest/BinarySearchTreeTest.java new file mode 100644 index 0000000..775d0cf --- /dev/null +++ b/src/test/java/cn/byhieg/collectiontutorialtest/BinarySearchTreeTest.java @@ -0,0 +1,53 @@ +package cn.byhieg.collectiontutorialtest; + +import cn.byhieg.algorithmtutorial.BinarySearchTree; +import com.sun.tools.internal.ws.wsdl.document.soap.SOAPUse; +import junit.framework.TestCase; +import org.junit.Assert; + +/** + * Created by byhieg on 17/3/30. + * Mail to byhieg@gmail.com + */ +public class BinarySearchTreeTest extends TestCase { + int [] nums; + BinarySearchTree tree; + public void setUp() throws Exception { + super.setUp(); + nums = new int[]{10,6,2,8,7,3,4,1}; + tree = new BinarySearchTree(nums); + } + + public void tearDown() throws Exception { + } + + + public void testInsert() throws Exception { + } + + public void testInOrder() throws Exception { + System.out.println("中序遍历"); + tree.inorder2(tree.getRoot()); + System.out.println(); + } + + public void testPreOrder() throws Exception { + System.out.println("先续遍历"); + tree.preOrder2(tree.getRoot()); + System.out.println(); + } + + public void testPostOrder() throws Exception { + System.out.println("后续遍历"); + tree.postOrder2(tree.getRoot()); + System.out.println(); + } + + public void testGetMaxData() throws Exception { +// Assert.assertEquals(12,tree.getMaxNode().data); + } + + public void testGetMinData() throws Exception { +// Assert.assertEquals(1,tree.getMinNode().data); + } +} \ No newline at end of file From 2f4dc6ba888c39e270716c12da454dab62a7ec73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=9F=B3=E7=90=A6=E5=B3=B0?= Date: Thu, 30 Mar 2017 22:37:54 +0800 Subject: [PATCH 11/34] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=A0=B9=E6=8D=AE?= =?UTF-8?q?=E5=89=8D=E5=BA=8F=E9=81=8D=E5=8E=86=E5=92=8C=E4=B8=AD=E5=BA=8F?= =?UTF-8?q?=E9=81=8D=E5=8E=86=E7=9A=84=E6=83=85=E5=86=B5=EF=BC=8C=E8=BF=98?= =?UTF-8?q?=E5=8E=9F=E4=BA=8C=E5=8F=89=E6=A0=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../algorithmtutorial/BinarySearchTree.java | 76 +++++++++++++++---- .../cn/byhieg/algorithmtutorial/Find.java | 6 +- .../BinarySearchTreeTest.java | 17 +++-- 3 files changed, 75 insertions(+), 24 deletions(-) diff --git a/src/main/java/cn/byhieg/algorithmtutorial/BinarySearchTree.java b/src/main/java/cn/byhieg/algorithmtutorial/BinarySearchTree.java index ccb787d..165d5d9 100644 --- a/src/main/java/cn/byhieg/algorithmtutorial/BinarySearchTree.java +++ b/src/main/java/cn/byhieg/algorithmtutorial/BinarySearchTree.java @@ -17,14 +17,14 @@ public class BinarySearchTree { private Node root; - public BinarySearchTree(){ + public BinarySearchTree() { } public BinarySearchTree(int[] nums) { Node[] nodes = new Node[nums.length]; - for (int i = 0 ; i < nums.length;i++) { + for (int i = 0; i < nums.length; i++) { nodes[i] = new Node(nums[i]); insert(nodes[i]); } @@ -32,10 +32,11 @@ public BinarySearchTree(int[] nums) { /** * 查找指定的元素 + * * @param des * @return */ - public Node find(int des){ + public Node find(int des) { if (root == null) { System.out.println("树是空的"); throw new RuntimeException(); @@ -44,7 +45,7 @@ public Node find(int des){ while (current.data != des) { if (current.data < des) { current = current.right; - }else{ + } else { current = current.left; } if (current == null) return null; @@ -55,10 +56,11 @@ public Node find(int des){ /** * 对BST执行插入操作,采用非递归的形式 * 保证插入后,左节点的值小于根节点的值,根节点的值小于右节点的值 + * * @param node * @return */ - public boolean insert(Node node){ + public boolean insert(Node node) { if (root == null) { root = node; return true; @@ -77,7 +79,7 @@ public boolean insert(Node node){ return true; } current = current.right; - }else{ + } else { if (current.left == null) { current.left = node; return true; @@ -105,9 +107,10 @@ public void preOrder(Node node) { /** * 树的中序遍历,递归实现 * 针对BST,该结果会从小到大输出树 + * * @param node */ - public void inOrder(Node node){ + public void inOrder(Node node) { if (node.left != null) { inOrder(node.left); } @@ -120,7 +123,7 @@ public void inOrder(Node node){ /** * 树的后续遍历,递归实现 */ - public void postOrder(Node node){ + public void postOrder(Node node) { if (node.left != null) { postOrder(node.left); } @@ -136,7 +139,6 @@ public void postOrder(Node node){ * 1. 建立一个栈,现将头结点压入栈中。 * 2. 现将每出栈一个节点,打印他的值,然后都要先加入他的右节点,在加入他的左节点。因为栈的后进先出的特性,才能让左边先出。 * 3. 不断重复2,直到栈空 - * */ public void preOrder2(Node node) { if (node != null) { @@ -161,7 +163,7 @@ public void preOrder2(Node node) { * 2. 出栈一个节点,打印他的值,然后cur = node.right,并不断重复第二步 * 3. 当栈为空,并且cur为空时,停止 */ - public void inorder2(Node node){ + public void inorder2(Node node) { if (node != null) { Stack stack = new Stack<>(); Node cur = node; @@ -170,7 +172,7 @@ public void inorder2(Node node){ cur = stack.pop(); System.out.print(cur.data + "-->"); cur = cur.right; - }else{ + } else { stack.push(cur); cur = cur.left; } @@ -183,6 +185,7 @@ public void inorder2(Node node){ * 1. 树的先续遍历中,是栈存放顺序是根,右节点,左节点。 * 2. 我们可以将其反过来,用栈存放是根,左节点,右节点。然后出栈的时候,将出栈的结果存放到另一个栈里。 * 3. 第二栈里的顺序从上到下就是左节点,右节点,根的顺序。 + * * @param node */ @@ -192,7 +195,7 @@ public void postOrder2(Node node) { Stack result = new Stack<>(); Node cur = node; stack.push(cur); - while (!stack.isEmpty()){ + while (!stack.isEmpty()) { Node tmp = stack.pop(); result.push(tmp); if (tmp.left != null) { @@ -212,9 +215,10 @@ public void postOrder2(Node node) { /** * 得到树中最小的节点 + * * @return */ - public Node getMinNode(){ + public Node getMinNode() { if (root == null) { throw new RuntimeException("树为空"); } @@ -228,9 +232,10 @@ public Node getMinNode(){ /** * 得到树中最大的节点 + * * @return */ - public Node getMaxNode(){ + public Node getMaxNode() { if (root == null) { throw new RuntimeException("树为空"); } @@ -242,12 +247,51 @@ public Node getMaxNode(){ return current; } - public static class Node{ + + public void getTree(int[] preOrders, int[] inOrders,boolean isLeft) { + int root = preOrders[0]; + if (isLeft) { + System.out.println("左" + root); + }else{ + System.out.println("右" + root); + } + + int index = new Find().binarySearchFind(inOrders, root); + int[] left = new int[index]; + int[] preLeft = new int[index]; + if (left.length != 0) { + for (int i = 0; i < index; i++) { + left[i] = inOrders[i]; + preLeft[i] = preOrders[i + 1]; + } + } + int size = inOrders.length - index - 1; + int[] right = new int[inOrders.length - index - 1]; + int[] preRight = new int[size]; + if (right.length != 0) { + for (int i = 0; i < size; i++) { + right[i] = inOrders[i + index + 1]; + preRight[i] = preOrders[preLeft.length + i + 1]; + } + } + + if (preLeft.length != 0) { + getTree(preLeft, left,true); + } + + if (preRight.length != 0) { + getTree(preRight, right,false); + } + System.out.println(); + + } + + public static class Node { public int data; public Node left; public Node right; - public Node(int data){ + public Node(int data) { this.data = data; } } diff --git a/src/main/java/cn/byhieg/algorithmtutorial/Find.java b/src/main/java/cn/byhieg/algorithmtutorial/Find.java index ff548c6..f476fb3 100644 --- a/src/main/java/cn/byhieg/algorithmtutorial/Find.java +++ b/src/main/java/cn/byhieg/algorithmtutorial/Find.java @@ -14,12 +14,12 @@ public class Find { * @param nums int型数组,要求有序 * @return 找到,返回下标,没找到,返回-1 */ - public int binarySerachFind(int[] nums,int des) { + public int binarySearchFind(int[] nums,int des) { int length = nums.length; int low = 0; int high = length - 1; - while (low < high) { - int mid = low + (high - low) / 2; + while (low <= high) { + int mid = (low + high) / 2; if (nums[mid] == des) { return mid; } else if (nums[mid] < des) { diff --git a/src/test/java/cn/byhieg/collectiontutorialtest/BinarySearchTreeTest.java b/src/test/java/cn/byhieg/collectiontutorialtest/BinarySearchTreeTest.java index 775d0cf..85ce3e8 100644 --- a/src/test/java/cn/byhieg/collectiontutorialtest/BinarySearchTreeTest.java +++ b/src/test/java/cn/byhieg/collectiontutorialtest/BinarySearchTreeTest.java @@ -1,7 +1,6 @@ package cn.byhieg.collectiontutorialtest; import cn.byhieg.algorithmtutorial.BinarySearchTree; -import com.sun.tools.internal.ws.wsdl.document.soap.SOAPUse; import junit.framework.TestCase; import org.junit.Assert; @@ -10,11 +9,12 @@ * Mail to byhieg@gmail.com */ public class BinarySearchTreeTest extends TestCase { - int [] nums; + int[] nums; BinarySearchTree tree; + public void setUp() throws Exception { super.setUp(); - nums = new int[]{10,6,2,8,7,3,4,1}; + nums = new int[]{10, 6, 2, 8, 7, 3, 4, 1}; tree = new BinarySearchTree(nums); } @@ -43,11 +43,18 @@ public void testPostOrder() throws Exception { System.out.println(); } + public void testGetTree() throws Exception { + System.out.println("树"); + int[] pre = new int[]{10, 6, 2, 1, 3, 4, 8, 7}; + int[] in = new int[]{1, 2, 3, 4, 6, 7, 8, 10}; + tree.getTree(pre, in,true); + } + public void testGetMaxData() throws Exception { -// Assert.assertEquals(12,tree.getMaxNode().data); + Assert.assertEquals(10,tree.getMaxNode().data); } public void testGetMinData() throws Exception { -// Assert.assertEquals(1,tree.getMinNode().data); + Assert.assertEquals(1,tree.getMinNode().data); } } \ No newline at end of file From 2d5db31cfb3c9558fecb310271d3f35c235feabc Mon Sep 17 00:00:00 2001 From: byhieg Date: Wed, 5 Apr 2017 18:32:16 +0800 Subject: [PATCH 12/34] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BB=8E=E5=89=8D?= =?UTF-8?q?=E5=BA=8F=E9=81=8D=E5=8E=86=E5=92=8C=E4=B8=AD=E5=BA=8F=E9=81=8D?= =?UTF-8?q?=E5=8E=86=E5=BE=97=E5=88=B0=E6=A0=91=E7=9A=84=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../algorithmtutorial/BinarySearchTree.java | 59 +++++++++++++++---- .../cn/byhieg/algorithmtutorial/Sort.java | 3 +- .../algorithmtutorialtest/SortTest.java | 42 ++++++------- .../BinarySearchTreeTest.java | 26 ++++---- 4 files changed, 85 insertions(+), 45 deletions(-) diff --git a/src/main/java/cn/byhieg/algorithmtutorial/BinarySearchTree.java b/src/main/java/cn/byhieg/algorithmtutorial/BinarySearchTree.java index 165d5d9..f2fc3c1 100644 --- a/src/main/java/cn/byhieg/algorithmtutorial/BinarySearchTree.java +++ b/src/main/java/cn/byhieg/algorithmtutorial/BinarySearchTree.java @@ -5,6 +5,8 @@ * Mail to byhieg@gmail.com */ +import java.util.LinkedList; +import java.util.Queue; import java.util.Stack; /** @@ -212,6 +214,26 @@ public void postOrder2(Node node) { } } + /** + * 树的层次遍历,类似于图的BFS + * @param root + */ + public void levelRead(Node root) { + if (root == null) return; + Queue queue = new LinkedList<>(); + queue.offer(root); + while (!queue.isEmpty()) { + Node current = queue.poll(); + System.out.print(current.data + "-->"); + if (current.left != null) { + queue.offer(current.left); + } + if (current.right != null) { + queue.offer(current.right); + } + } + } + /** * 得到树中最小的节点 @@ -248,15 +270,15 @@ public Node getMaxNode() { } - public void getTree(int[] preOrders, int[] inOrders,boolean isLeft) { + public void getTree(int[] preOrders, int[] inOrders,Node r) { int root = preOrders[0]; - if (isLeft) { - System.out.println("左" + root); - }else{ - System.out.println("右" + root); - } - - int index = new Find().binarySearchFind(inOrders, root); +// if (isLeft) { +// System.out.println("左" + root); +// }else{ +// System.out.println("右" + root); +// } + r.data = root; + int index = findIndex(inOrders, root); int[] left = new int[index]; int[] preLeft = new int[index]; if (left.length != 0) { @@ -264,7 +286,11 @@ public void getTree(int[] preOrders, int[] inOrders,boolean isLeft) { left[i] = inOrders[i]; preLeft[i] = preOrders[i + 1]; } + Node node = new Node(preLeft[0]); + r.left = node; } + + int size = inOrders.length - index - 1; int[] right = new int[inOrders.length - index - 1]; int[] preRight = new int[size]; @@ -273,17 +299,17 @@ public void getTree(int[] preOrders, int[] inOrders,boolean isLeft) { right[i] = inOrders[i + index + 1]; preRight[i] = preOrders[preLeft.length + i + 1]; } + Node node = new Node(preRight[0]); + r.right = node; } if (preLeft.length != 0) { - getTree(preLeft, left,true); + getTree(preLeft, left,r.left); } if (preRight.length != 0) { - getTree(preRight, right,false); + getTree(preRight, right,r.right); } - System.out.println(); - } public static class Node { @@ -299,4 +325,13 @@ public Node(int data) { public Node getRoot() { return root; } + + private int findIndex(int[] nums, int target) { + for (int i = 0 ; i < nums.length;i++) { + if (nums[i] == target) { + return i; + } + } + return -1; + } } diff --git a/src/main/java/cn/byhieg/algorithmtutorial/Sort.java b/src/main/java/cn/byhieg/algorithmtutorial/Sort.java index 74cc832..4571f7a 100644 --- a/src/main/java/cn/byhieg/algorithmtutorial/Sort.java +++ b/src/main/java/cn/byhieg/algorithmtutorial/Sort.java @@ -250,7 +250,8 @@ public void sink(int nums[], int i,int n) { nums[i] = nums[son]; nums[son] = temp; i = son; - } else { + son = 2 * i + 1; + }else{ break; } } diff --git a/src/test/java/cn/byhieg/algorithmtutorialtest/SortTest.java b/src/test/java/cn/byhieg/algorithmtutorialtest/SortTest.java index 65b128e..08c1d90 100644 --- a/src/test/java/cn/byhieg/algorithmtutorialtest/SortTest.java +++ b/src/test/java/cn/byhieg/algorithmtutorialtest/SortTest.java @@ -19,27 +19,27 @@ public void tearDown() throws Exception { System.out.print(nums[i] + " "); } } - - public void testChooseSort() throws Exception { - new Sort().chooseSort(nums); - } - - - public void testInsertDirectlySort() throws Exception { - new Sort().insertDirectlySort(nums); - } - - public void testInsertBinarySort() throws Exception { - new Sort().insertBinarySort(nums); - } - - public void testBubbleSort() throws Exception { - new Sort().bubbleSort2(nums); - } - - public void testQuickSort() throws Exception { - new Sort().quickSort(nums); - } +// +// public void testChooseSort() throws Exception { +// new Sort().chooseSort(nums); +// } +// +// +// public void testInsertDirectlySort() throws Exception { +// new Sort().insertDirectlySort(nums); +// } +// +// public void testInsertBinarySort() throws Exception { +// new Sort().insertBinarySort(nums); +// } +// +// public void testBubbleSort() throws Exception { +// new Sort().bubbleSort2(nums); +// } +// +// public void testQuickSort() throws Exception { +// new Sort().quickSort(nums); +// } public void testHeapSort() throws Exception { new Sort().heapSort(nums); diff --git a/src/test/java/cn/byhieg/collectiontutorialtest/BinarySearchTreeTest.java b/src/test/java/cn/byhieg/collectiontutorialtest/BinarySearchTreeTest.java index 85ce3e8..c56ce25 100644 --- a/src/test/java/cn/byhieg/collectiontutorialtest/BinarySearchTreeTest.java +++ b/src/test/java/cn/byhieg/collectiontutorialtest/BinarySearchTreeTest.java @@ -14,11 +14,13 @@ public class BinarySearchTreeTest extends TestCase { public void setUp() throws Exception { super.setUp(); - nums = new int[]{10, 6, 2, 8, 7, 3, 4, 1}; + nums = new int[]{1,2,3,4,5}; tree = new BinarySearchTree(nums); } public void tearDown() throws Exception { + BinarySearchTree.Node node = new BinarySearchTree.Node(10); + tree.levelRead(node); } @@ -45,16 +47,18 @@ public void testPostOrder() throws Exception { public void testGetTree() throws Exception { System.out.println("树"); - int[] pre = new int[]{10, 6, 2, 1, 3, 4, 8, 7}; - int[] in = new int[]{1, 2, 3, 4, 6, 7, 8, 10}; - tree.getTree(pre, in,true); + int[] pre = new int[]{1,2,4,5,3}; + int[] in = new int[]{4,2,5,1,3}; + BinarySearchTree.Node node = new BinarySearchTree.Node(1); + tree.getTree(pre, in,node); + tree.levelRead(node); } - public void testGetMaxData() throws Exception { - Assert.assertEquals(10,tree.getMaxNode().data); - } - - public void testGetMinData() throws Exception { - Assert.assertEquals(1,tree.getMinNode().data); - } +// public void testGetMaxData() throws Exception { +// Assert.assertEquals(10,tree.getMaxNode().data); +// } +// +// public void testGetMinData() throws Exception { +// Assert.assertEquals(1,tree.getMinNode().data); +// } } \ No newline at end of file From 722da5daa8627e8215174f11f7bf8a3a7ed9f2ed Mon Sep 17 00:00:00 2001 From: byhieg Date: Wed, 5 Apr 2017 20:38:06 +0800 Subject: [PATCH 13/34] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=97=A0=E5=90=91?= =?UTF-8?q?=E5=9B=BE=E7=9A=84=E9=93=BE=E6=8E=A5=E7=9F=A9=E9=98=B5=E5=AD=98?= =?UTF-8?q?=E5=82=A8=E4=BB=A5=E5=8F=8ADFS=EF=BC=8CBFS=EF=BC=8Cdijkstra?= =?UTF-8?q?=E7=AE=97=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../algorithmtutorial/BinarySearchTree.java | 22 ++- .../byhieg/algorithmtutorial/GraphMatrix.java | 152 ++++++++++++++++++ .../algorithmtutorialtest/FindTest.java | 16 +- .../GraphMatrixTest.java | 56 +++++++ 4 files changed, 233 insertions(+), 13 deletions(-) create mode 100644 src/main/java/cn/byhieg/algorithmtutorial/GraphMatrix.java create mode 100644 src/test/java/cn/byhieg/algorithmtutorialtest/GraphMatrixTest.java diff --git a/src/main/java/cn/byhieg/algorithmtutorial/BinarySearchTree.java b/src/main/java/cn/byhieg/algorithmtutorial/BinarySearchTree.java index f2fc3c1..3aaffd5 100644 --- a/src/main/java/cn/byhieg/algorithmtutorial/BinarySearchTree.java +++ b/src/main/java/cn/byhieg/algorithmtutorial/BinarySearchTree.java @@ -156,6 +156,8 @@ public void preOrder2(Node node) { stack.push(tmp.left); } } + System.out.println("结束"); + } } @@ -179,6 +181,8 @@ public void inorder2(Node node) { cur = cur.left; } } + System.out.println("结束"); + } } @@ -211,6 +215,8 @@ public void postOrder2(Node node) { while (!result.isEmpty()) { System.out.print(result.pop().data + "-->"); } + System.out.println("结束"); + } } @@ -232,9 +238,13 @@ public void levelRead(Node root) { queue.offer(current.right); } } + System.out.println("结束"); + } + + /** * 得到树中最小的节点 * @@ -270,14 +280,16 @@ public Node getMaxNode() { } + /** + * 从先序遍历和中序遍历中构造出树 + * @param preOrders + * @param inOrders + * @param r + */ public void getTree(int[] preOrders, int[] inOrders,Node r) { int root = preOrders[0]; -// if (isLeft) { -// System.out.println("左" + root); -// }else{ -// System.out.println("右" + root); -// } r.data = root; + int index = findIndex(inOrders, root); int[] left = new int[index]; int[] preLeft = new int[index]; diff --git a/src/main/java/cn/byhieg/algorithmtutorial/GraphMatrix.java b/src/main/java/cn/byhieg/algorithmtutorial/GraphMatrix.java new file mode 100644 index 0000000..16c7afa --- /dev/null +++ b/src/main/java/cn/byhieg/algorithmtutorial/GraphMatrix.java @@ -0,0 +1,152 @@ +package cn.byhieg.algorithmtutorial; + +import java.util.LinkedList; +import java.util.Queue; + +/** + * Created by shiqifeng on 2017/4/5. + * Mail byhieg@gmail.com + */ +public class GraphMatrix { + + Weight[][] graph; + boolean[] isVisited; + + private static final int UNREACH = Integer.MAX_VALUE - 1000; + + public GraphMatrix(Weight[][] graph) { + this.graph = graph; + } + + /** + * 图的BFS,算法流程 + * 1. 首先将begin节点入队 + * 2. 然后判断队列是否为空,不为空,则出队一个元素,输出。 + * 3. 将出队的元素的所有相邻的元素且没有访问的都放进队列中,重复第二步 + * + * 广度优先遍历,从V0出发,访问V0的各个未曾访问的邻接点W1,W2,…,Wk;然后,依次从W1,W2,…,Wk出发访问各自未被访问的邻接点; + * @param begin + */ + public void BFS(Integer begin) { + isVisited = new boolean[graph.length]; + for (int i = 0 ; i < isVisited.length;i++) { + isVisited[i] = false; + } + + Queue queue = new LinkedList<>(); + queue.offer(begin); + isVisited[begin] = true; + + while (!queue.isEmpty()) { + int current = queue.poll(); + System.out.print(current + "-->"); + for (int i = 0 ; i < graph[current].length;i++) { + if (i == begin) { + continue; + } + if (graph[current][i].weight != UNREACH && !isVisited[i]) { + queue.offer(i); + isVisited[i] = true; + } + } + } + System.out.println("结束"); + } + + + /** + * 图的DFS算法,算法流程 + * 1. 从begin节点出发,输出begin节点。 + * 2. 循环遍历所有与begin节点相邻并且没有被访问的节点 + * 3. 找到一个节点,就以他为begin,递归调用DFS + * @param begin + */ + public void DFS(Integer begin) { + isVisited = new boolean[graph.length]; + for (int i = 0 ; i < isVisited.length;i++) { + isVisited[i] = false; + } + doDFS(begin); + System.out.println("结束"); + } + + /** + * 假设给定图G的初态是所有顶点均未曾访问过。 + * 在G中任选一顶点v为初始出发点(源点),则深度优先遍历可定义如下: + * 首先访问出发点v,并将其标记为已访问过;然后依次从v出发搜索v的每个邻接点w。 + * 若w未曾访问过,则以w为新的出发点继续进行深度优先遍历,直至图中所有和源点v有路径相通的顶点(亦称为从源点可达的顶点)均已被访问为止。 + * 若此时图中仍有未访问的顶点,则另选一个尚未访问的顶点作为新的源点重复上述过程,直至图中所有顶点均已被访问为止。 + * @param begin + */ + private void doDFS(Integer begin) { + isVisited[begin] = true; + System.out.print(begin + "-->"); + for (int i = 0 ; i < graph[begin].length;i++) { + if (graph[begin][i].weight != UNREACH && !isVisited[i]) { + doDFS(i); + } + } + } + + public void dijkstra(int start) { + //接受一个有向图的权重矩阵,和一个起点编号start(从0编号,顶点存在数组中) + //返回一个int[] 数组,表示从start到它的最短路径长度 + int n = graph.length; //顶点个数 + int[] shortPath = new int[n]; //存放从start到其他各点的最短路径 + String[] path = new String[n]; //存放从start到其他各点的最短路径的字符串表示 + for (int i = 0; i < n; i++) + path[i] = new String(start + "-->" + i); + int[] visited = new int[n]; //标记当前该顶点的最短路径是否已经求出,1表示已求出 + + //初始化,第一个顶点求出 + shortPath[start] = 0; + visited[start] = 1; + + for (int count = 1; count <= n - 1; count++) //要加入n-1个顶点 + { + + int k = -1; //选出一个距离初始顶点start最近的未标记顶点 + int dmin = Integer.MAX_VALUE; + for (int i = 0; i < n; i++) { + if (visited[i] == 0 && graph[start][i].weight < dmin) { + dmin = graph[start][i].weight; + + k = i; + } + + } + //将新选出的顶点标记为已求出最短路径,且到start的最短路径就是dmin + shortPath[k] = dmin; + + visited[k] = 1; + + //以k为中间点,修正从start到未访问各点的距离 + for (int i = 0; i < n; i++) { // System.out.println("k="+k); + if (visited[i] == 0 && graph[start][k].weight + graph[k][i].weight < graph[start][i].weight) { + graph[start][i].weight = graph[start][k].weight + graph[k][i].weight; + path[i] = path[k] + "-->" + i; + } + } + } + + for (int i = 0; i < n; i++) { + System.out.println("从" + start + "出发到" + i + "的最短路径为:" + path[i] + " 距离为" + shortPath[i]); + } + } + + + + + + + public static class Weight{ + int weight; + public Weight(){ + this(UNREACH); + } + + public Weight(int weight) { + this.weight = weight; + } + } +} diff --git a/src/test/java/cn/byhieg/algorithmtutorialtest/FindTest.java b/src/test/java/cn/byhieg/algorithmtutorialtest/FindTest.java index beef69c..53914a9 100644 --- a/src/test/java/cn/byhieg/algorithmtutorialtest/FindTest.java +++ b/src/test/java/cn/byhieg/algorithmtutorialtest/FindTest.java @@ -12,23 +12,23 @@ public class FindTest extends TestCase { int result; public void setUp() throws Exception { super.setUp(); - nums = new int[]{1}; + nums = new int[]{}; } public void tearDown() throws Exception { System.out.println(result); } -// public void testBinarySerachFind() throws Exception { -// result = new Find().binarySerachFind(nums,6); -// } -//// + public void testBinarySerachFind() throws Exception { + result = new Find().binarySearchFind(nums,2); + } + // public void testBinarySearchMinFind() throws Exception { // result = new Find().binarySearchMinFind(nums,1); // } - public void testBinarySearchMaxFind() throws Exception { - result = new Find().binarySearchMaxFind(nums, 2); - } +// public void testBinarySearchMaxFind() throws Exception { +// result = new Find().binarySearchMaxFind(nums, 2); +// } } \ No newline at end of file diff --git a/src/test/java/cn/byhieg/algorithmtutorialtest/GraphMatrixTest.java b/src/test/java/cn/byhieg/algorithmtutorialtest/GraphMatrixTest.java new file mode 100644 index 0000000..ea0f6d3 --- /dev/null +++ b/src/test/java/cn/byhieg/algorithmtutorialtest/GraphMatrixTest.java @@ -0,0 +1,56 @@ +package cn.byhieg.algorithmtutorialtest; + +import cn.byhieg.algorithmtutorial.GraphMatrix; +import junit.framework.TestCase; + +/** + * Created by shiqifeng on 2017/4/5. + * Mail byhieg@gmail.com + */ +public class GraphMatrixTest extends TestCase { + + GraphMatrix graphMatrix; + GraphMatrix.Weight[][] weights; + public void setUp() throws Exception { + super.setUp(); + weights = new GraphMatrix.Weight[5][5]; + for (int i = 0 ; i < weights.length;i++) + for (int j = 0 ; j < weights[i].length;j++){ + weights[i][j] = new GraphMatrix.Weight(); + weights[j][i] = new GraphMatrix.Weight(); + } + + weights[0][1] = new GraphMatrix.Weight(100); + weights[1][2] = new GraphMatrix.Weight(10); + weights[2][3] = new GraphMatrix.Weight(20); + weights[3][1] = new GraphMatrix.Weight(25); + weights[2][4] = new GraphMatrix.Weight(20); + + weights[1][0] = new GraphMatrix.Weight(100); + weights[2][1] = new GraphMatrix.Weight(10); + weights[3][2] = new GraphMatrix.Weight(20); + weights[1][3] = new GraphMatrix.Weight(25); + weights[4][2] = new GraphMatrix.Weight(20); + + + graphMatrix = new GraphMatrix(weights); + } + + public void tearDown() throws Exception { + + } + + public void testBFS() throws Exception { + graphMatrix.BFS(4); + + } + + public void testDFS() throws Exception { + graphMatrix.DFS(0); + } + + public void testDijkstra() throws Exception { + graphMatrix.dijkstra(0); + } + +} \ No newline at end of file From 0c45e5b56da4007522029f3bf4f6b71c87ee2050 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=9F=B3=E7=90=A6=E5=B3=B0?= Date: Thu, 6 Apr 2017 11:27:47 +0800 Subject: [PATCH 14/34] =?UTF-8?q?=E4=BF=AE=E6=94=B9README=E5=9B=BE?= =?UTF-8?q?=E7=89=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../JavaTutorial\347\233\256\345\275\225.jpg" | Bin 176782 -> 353150 bytes .../algorithmtutorial/BinarySearchTree.java | 15 +++++++++++++++ .../cn/byhieg/algorithmtutorial/Sort.java | 2 +- 3 files changed, 16 insertions(+), 1 deletion(-) diff --git "a/images/JavaTutorial\347\233\256\345\275\225.jpg" "b/images/JavaTutorial\347\233\256\345\275\225.jpg" index e6c8c449c4b3bcaa7849c1ab03bdb7fab734de37..a4603a6e1fee9a5143d9d3147e1e181688b9c5e7 100644 GIT binary patch literal 353150 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