diff --git a/.gitignore b/.gitignore
index 2a5296f902..f1e9957cfa 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,21 +1,287 @@
-*.class
-# Mobile Tools for Java (J2ME)
-.mtj.tmp/
-
-# Package Files #
-*.jar
-*.war
-*.ear
-
-# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
-hs_err_pid*
-
-#ide config
-.metadata
-.recommenders
-.idea/
-*.iml
-rebel.*
-.rebel.*
-
-target
+#################
+## Eclipse
+#################
+
+*.pydevproject
+.project
+.metadata
+bin/
+tmp/
+*.tmp
+*.bak
+*.swp
+*~.nib
+local.properties
+.classpath
+.settings/
+.loadpath
+
+# External tool builders
+.externalToolBuilders/
+
+# Locally stored "Eclipse launch configurations"
+*.launch
+
+# CDT-specific
+.cproject
+
+# PDT-specific
+.buildpath
+
+
+#################
+## Visual Studio
+#################
+
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+
+# User-specific files
+*.suo
+*.user
+*.sln.docstates
+
+# Build results
+
+[Dd]ebug/
+[Rr]elease/
+x64/
+build/
+[Bb]in/
+[Oo]bj/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+*_i.c
+*_p.c
+*.ilk
+*.meta
+*.obj
+*.pch
+*.pdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*.log
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.log
+*.scc
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opensdf
+*.sdf
+*.cachefile
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+
+# TeamCity is a build add-in
+_TeamCity*
+
+# DotCover is a Code Coverage Tool
+*.dotCover
+
+# NCrunch
+*.ncrunch*
+.*crunch*.local.xml
+
+# Installshield output folder
+[Ee]xpress/
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish/
+
+# Publish Web Output
+*.Publish.xml
+*.pubxml
+*.publishproj
+
+# NuGet Packages Directory
+## TODO: If you have NuGet Package Restore enabled, uncomment the next line
+#packages/
+
+# Windows Azure Build Output
+csx
+*.build.csdef
+
+# Windows Store app package directory
+AppPackages/
+
+# Others
+sql/
+*.Cache
+ClientBin/
+[Ss]tyle[Cc]op.*
+~$*
+*~
+*.dbmdl
+*.[Pp]ublish.xml
+*.pfx
+*.publishsettings
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file to a newer
+# Visual Studio version. Backup files are not needed, because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+
+# SQL Server files
+App_Data/*.mdf
+App_Data/*.ldf
+
+#############
+## Windows detritus
+#############
+
+# Windows image file caches
+Thumbs.db
+ehthumbs.db
+
+# Folder config file
+Desktop.ini
+
+# Recycle Bin used on file shares
+$RECYCLE.BIN/
+
+# Mac crap
+.DS_Store
+
+
+#############
+## Python
+#############
+
+*.py[cod]
+
+# Packages
+*.egg
+*.egg-info
+dist/
+build/
+eggs/
+parts/
+var/
+sdist/
+develop-eggs/
+.installed.cfg
+
+# Installer logs
+pip-log.txt
+
+# Unit test / coverage reports
+.coverage
+.tox
+
+#Translations
+*.mo
+
+#Mr Developer
+.mr.developer.cfg
+
+# Mobile Tools for Java (J2ME)
+.mtj.tmp/
+
+# Package Files #
+*.jar
+*.war
+*.ear
+
+# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
+hs_err_pid*
+
+#ide config
+.metadata
+.recommenders
+
+*.iml
+.idea
+*.iml
+rebel.xml
+rebel-remote.xml
+
+.classpath
+.project
+.setting
+.metadata
+
+target
+#*.class
+
+log
+*.log
+tmp
+*.tmp
+
+.metadata
+RemoteSystemsTempFiles
+
+build/
+.idea/
+.gradle/
+*.class
+# Mobile Tools for Java (J2ME)
+.mtj.tmp/
+
+# Package Files #
+*.jar
+*.war
+*.ear
+
+# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
+hs_err_pid*
+
+#ide config
+.metadata
+.recommenders
+.idea/
+*.iml
+rebel.*
+.rebel.*
+
+target
+*.DS_Store
+liuxin/.DS_Store
+liuxin/src/.DS_Store
+
+
+
+
+
+
diff --git a/README.md b/README.md
new file mode 100644
index 0000000000..a7d23c04cf
--- /dev/null
+++ b/README.md
@@ -0,0 +1,3 @@
+## 2017编程提高社群
+
+2017编程提高社群代码仓库所在地
\ No newline at end of file
diff --git a/group01/group01.md b/group01/group01.md
deleted file mode 100644
index 8b13789179..0000000000
--- a/group01/group01.md
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/group02/group02.md b/group02/group02.md
deleted file mode 100644
index 8b13789179..0000000000
--- a/group02/group02.md
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/group03/group03.md b/group03/group03.md
deleted file mode 100644
index 8b13789179..0000000000
--- a/group03/group03.md
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/group04/group04.md b/group04/group04.md
deleted file mode 100644
index 8b13789179..0000000000
--- a/group04/group04.md
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/group05/group05.md b/group05/group05.md
deleted file mode 100644
index 8b13789179..0000000000
--- a/group05/group05.md
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/group06/group06.md b/group06/group06.md
deleted file mode 100644
index 8b13789179..0000000000
--- a/group06/group06.md
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/group07/group07.md b/group07/group07.md
deleted file mode 100644
index 8b13789179..0000000000
--- a/group07/group07.md
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/group08/group08.md b/group08/group08.md
deleted file mode 100644
index 8b13789179..0000000000
--- a/group08/group08.md
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/group09/group09.md b/group09/group09.md
deleted file mode 100644
index 8b13789179..0000000000
--- a/group09/group09.md
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/group10/group10.md b/group10/group10.md
deleted file mode 100644
index 8b13789179..0000000000
--- a/group10/group10.md
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/group11/group11.md b/group11/group11.md
deleted file mode 100644
index 8b13789179..0000000000
--- a/group11/group11.md
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/group12/group12.md b/group12/group12.md
deleted file mode 100644
index 8b13789179..0000000000
--- a/group12/group12.md
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/group13/group13.md b/group13/group13.md
deleted file mode 100644
index 8b13789179..0000000000
--- a/group13/group13.md
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/group14/group14.md b/group14/group14.md
deleted file mode 100644
index 8b13789179..0000000000
--- a/group14/group14.md
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/group15/group15.md b/group15/group15.md
deleted file mode 100644
index 8b13789179..0000000000
--- a/group15/group15.md
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/group16/group16.md b/group16/group16.md
deleted file mode 100644
index 8b13789179..0000000000
--- a/group16/group16.md
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/group17/1204187480/code/homework/basic/src/main/java/com/coding/basic/LinkedList.java b/group17/1204187480/code/homework/basic/src/main/java/com/coding/basic/LinkedList.java
deleted file mode 100644
index e2c4e5e795..0000000000
--- a/group17/1204187480/code/homework/basic/src/main/java/com/coding/basic/LinkedList.java
+++ /dev/null
@@ -1,46 +0,0 @@
-package com.coding.basic;
-
-public class LinkedList implements List {
-
- private Node head;
-
- public void add(Object o){
-
- }
- public void add(int index , Object o){
-
- }
- public Object get(int index){
- return null;
- }
- public Object remove(int index){
- return null;
- }
-
- public int size(){
- return -1;
- }
-
- public void addFirst(Object o){
-
- }
- public void addLast(Object o){
-
- }
- public Object removeFirst(){
- return null;
- }
- public Object removeLast(){
- return null;
- }
- public Iterator iterator(){
- return null;
- }
-
-
- private static class Node{
- Object data;
- Node next;
-
- }
-}
diff --git a/group17/1204187480/code/homework/basic/src/main/java/com/coding/basic/Queue.java b/group17/1204187480/code/homework/basic/src/main/java/com/coding/basic/Queue.java
deleted file mode 100644
index 36e516e266..0000000000
--- a/group17/1204187480/code/homework/basic/src/main/java/com/coding/basic/Queue.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package com.coding.basic;
-
-public class Queue {
-
- public void enQueue(Object o){
- }
-
- public Object deQueue(){
- return null;
- }
-
- public boolean isEmpty(){
- return false;
- }
-
- public int size(){
- return -1;
- }
-}
diff --git a/group17/176653813/1766538130226Lesson/.classpath b/group17/176653813/1766538130226Lesson/.classpath
deleted file mode 100644
index 373dce4005..0000000000
--- a/group17/176653813/1766538130226Lesson/.classpath
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
-
-
-
diff --git a/group17/176653813/1766538130226Lesson/.gitignore b/group17/176653813/1766538130226Lesson/.gitignore
deleted file mode 100644
index ae3c172604..0000000000
--- a/group17/176653813/1766538130226Lesson/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-/bin/
diff --git a/group17/176653813/1766538130226Lesson/.project b/group17/176653813/1766538130226Lesson/.project
deleted file mode 100644
index 96a5027846..0000000000
--- a/group17/176653813/1766538130226Lesson/.project
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
- 1766538130226Lesson
-
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
-
- org.eclipse.jdt.core.javanature
-
-
diff --git a/group17/176653813/1766538130226Lesson/.settings/org.eclipse.jdt.core.prefs b/group17/176653813/1766538130226Lesson/.settings/org.eclipse.jdt.core.prefs
deleted file mode 100644
index 3a21537071..0000000000
--- a/group17/176653813/1766538130226Lesson/.settings/org.eclipse.jdt.core.prefs
+++ /dev/null
@@ -1,11 +0,0 @@
-eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
-org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
-org.eclipse.jdt.core.compiler.compliance=1.8
-org.eclipse.jdt.core.compiler.debug.lineNumber=generate
-org.eclipse.jdt.core.compiler.debug.localVariable=generate
-org.eclipse.jdt.core.compiler.debug.sourceFile=generate
-org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
-org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
-org.eclipse.jdt.core.compiler.source=1.8
diff --git a/group17/176653813/1766538130226Lesson/src/com/coding/basic/ArrayList.java b/group17/176653813/1766538130226Lesson/src/com/coding/basic/ArrayList.java
deleted file mode 100644
index 61df9ada90..0000000000
--- a/group17/176653813/1766538130226Lesson/src/com/coding/basic/ArrayList.java
+++ /dev/null
@@ -1,80 +0,0 @@
-package com.coding.basic;
-
-public class ArrayList implements List {
-
- private int size = 0;
- private Object[] obj = new Object[5];
-
- @Override
- public void add(Object o) {
- if(this.size < 0 )
- System.out.print("Error");
- this.extend(100);
- obj[this.size] = o;
- this.size ++;
- }
-
- @Override
- public void add(int index, Object o) {
-
- if(index < 0)
- System.out.println("Error");
- if(index < this.size){
- extend(100);
- for(int i = this.size;i < index; i--){
- obj[i+1] = obj[i];
- }
- obj[index] = o;
- }else if(index >= size){
- extend(100);
- obj[size] = o;
- }
- this.size++;
- }
-
- @Override
- public Object get(int index) {
- if(index < 0 || index > size){
- System.out.println("Error");
- return null;
- }
- return obj[index];
- }
-
- @Override
- public Object remove(int index) {
- if(index < 0 || index > size){
- System.out.println("Error");
- return null;
- }
- for(int i = index;i <= size;i++){
- obj[i] = obj[i+1];
- }
- size--;
- return obj[index];
- }
-
- @Override
- public int size() {
- return size;
- }
- public int length(){
- return obj.length;
- }
- public void extend(int newLength){
- if (this.size >= obj.length){
- //չ
- Object[] old = obj;
- obj = new Object[size+newLength];
- for(int i = 0;i < size; i++){
- obj[i] = old[i];
- }
- }
- return;
- }
- public void Iteror(){
- for(int i = 0 ;i < size ; i++){
- System.out.println(obj[i]);
- }
- }
-}
diff --git a/group17/176653813/1766538130226Lesson/src/com/coding/basic/LinkList.java b/group17/176653813/1766538130226Lesson/src/com/coding/basic/LinkList.java
deleted file mode 100644
index 2f4e0e3067..0000000000
--- a/group17/176653813/1766538130226Lesson/src/com/coding/basic/LinkList.java
+++ /dev/null
@@ -1,96 +0,0 @@
-package com.coding.basic;
-
-public class LinkList implements List{
-
- private Node head; //ͷ㲻
- private static class Node{
- Object data;
- Node next;
- }
-
- @Override
- public void add(Object o) {
- //һû뵽
- if(null == head){
- head = new Node();
- head.next = null;
- head.data = o;
- }else{
- //β뷨
- //Node t = new Node();
- Node t;
- Node ins = new Node();
- t = head;
- while(t.next != null){
- t = t.next;
- }
- t.next = ins;
- ins.next = null;
- ins.data = o;
- }
- }
-
- @Override
- public void add(int index, Object o) {
- if(index < 0 ){
- System.out.println("Error");
- }else if(index == 0 || index == 1){
- Node t = new Node();
- t.next = head.next;
- head.next = t;
- t.data = o;
- }else{
- Node t = new Node();//ǰڵ
- Node p = new Node();//ǰһڵ
- t = head.next;
- for(int i = 1;i < index;i++){
- p = t;
- t = t.next;
- }
- Node ins = new Node();
- p.next = ins;
- ins.next = t;
- ins.data = o;
- }
-
- }
-
- @Override
- public Object get(int index) {
- if(index < 0 || head == null){
- System.out.println("Error");
- return null;
- }else{
- Node t ;
- t = head;
- for(int i = 1;i < index;i++){
- t = t.next;
- }
- return t.data;
- }
- }
-
- @Override
- public Object remove(int index) {
-
- return null;
- }
-
- public void display(){
- if(head == null){
- System.out.println("No Data");
- }else{
- Node t ;
- t = head;
- while(t != null){
- System.out.println("******"+t.data);
- t = t.next;
- }
- }
-
- }
- @Override
- public int size() {
- return 0;
- }
-}
diff --git a/group17/176653813/1766538130226Lesson/src/com/coding/basic/Queue.java b/group17/176653813/1766538130226Lesson/src/com/coding/basic/Queue.java
deleted file mode 100644
index 032b636962..0000000000
--- a/group17/176653813/1766538130226Lesson/src/com/coding/basic/Queue.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package com.coding.basic;
-
-public class Queue {
-
- private LinkList elementData = new LinkList();
- private int front = 0;
- private int rear = 0;
-
-
- public void enQueue(Object o){
- elementData.add(o);
- rear++;
- }
- public Object deQueue(){
- if(!isEmpty()){
- Object obj = elementData.remove(front);
- front++;
- return obj;
- }else{
- System.out.println("Queue is empty");
- return null;
- }
- }
- public boolean isEmpty(){
- if(front > rear){
- return true;
- }
- return false;
- }
-
- public int size(){
- return rear-front+1;
- }
-}
-
diff --git a/group17/176653813/1766538130226Lesson/src/com/coding/basic/Stack.java b/group17/176653813/1766538130226Lesson/src/com/coding/basic/Stack.java
deleted file mode 100644
index b902dea844..0000000000
--- a/group17/176653813/1766538130226Lesson/src/com/coding/basic/Stack.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package com.coding.basic;
-
-public class Stack {
-
- //
- private ArrayList elementData = new ArrayList();
- private int top = 0;
-
- public void push(Object o){
- elementData.add(o);
- top++;
- }
-
- public Object pop(){
- if(!isEmpty()){
- System.out.println("stack is empoty");
- return null;
- }
- Object obj = elementData.remove(top);
- top--;
- return obj;
- }
-
- public Object peek(){
- return elementData.get(top);
- }
-
- public boolean isEmpty(){
- if(top != 0){
- return true;
- }
- return false;
- }
-
- public int size(){
- return top++;
- }
-
-
-
-}
diff --git a/group17/176653813/1766538130226Lesson/src/com/coding/basic/Test.java b/group17/176653813/1766538130226Lesson/src/com/coding/basic/Test.java
deleted file mode 100644
index 6f48b4b4fd..0000000000
--- a/group17/176653813/1766538130226Lesson/src/com/coding/basic/Test.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package com.coding.basic;
-
-import static org.junit.Assert.*;
-
-public class Test {
-
- @org.junit.Test
- public void test() {
-
-/* ArrayList al = new ArrayList();
- al.add(1);
- al.add(2);
- al.add(3);
- al.add(4);
- al.add(5);
- al.add(200);
- al.add(10,100);
- al.Iteror();
- //System.out.println(al.length());
- //System.out.println(al.size());
- System.out.println("==================");
- al.remove(0);
- al.Iteror();*/
-
- LinkList ls = new LinkList();
- ls.add(100);
- ls.add(300);
- ls.add(500);
- ls.add(1000);
- ls.add(3,2000);
- ls.display();
- System.out.println(ls.get(4));
- }
-
-}
-
diff --git a/group17/176653813/RemoteSystemsTempFiles/.project b/group17/176653813/RemoteSystemsTempFiles/.project
deleted file mode 100644
index 5447a64fa9..0000000000
--- a/group17/176653813/RemoteSystemsTempFiles/.project
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
- RemoteSystemsTempFiles
-
-
-
-
-
-
- org.eclipse.rse.ui.remoteSystemsTempNature
-
-
diff --git a/group17/group17.md b/group17/group17.md
deleted file mode 100644
index 8b13789179..0000000000
--- a/group17/group17.md
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/group18/group18.md b/group18/group18.md
deleted file mode 100644
index 8b13789179..0000000000
--- a/group18/group18.md
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/group19/group19.md b/group19/group19.md
deleted file mode 100644
index 8b13789179..0000000000
--- a/group19/group19.md
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/group20/group20.md b/group20/group20.md
deleted file mode 100644
index 8b13789179..0000000000
--- a/group20/group20.md
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/group21/group21.md b/group21/group21.md
deleted file mode 100644
index 8b13789179..0000000000
--- a/group21/group21.md
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/liuxin/.classpath b/liuxin/.classpath
deleted file mode 100644
index fceb4801b5..0000000000
--- a/liuxin/.classpath
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
diff --git a/liuxin/.gitignore b/liuxin/.gitignore
deleted file mode 100644
index ae3c172604..0000000000
--- a/liuxin/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-/bin/
diff --git a/liuxin/.project b/liuxin/.project
deleted file mode 100644
index fab8d7f04c..0000000000
--- a/liuxin/.project
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
- 2017Learning
-
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
-
- org.eclipse.jdt.core.javanature
-
-
diff --git a/liuxin/.settings/org.eclipse.jdt.core.prefs b/liuxin/.settings/org.eclipse.jdt.core.prefs
deleted file mode 100644
index 3a21537071..0000000000
--- a/liuxin/.settings/org.eclipse.jdt.core.prefs
+++ /dev/null
@@ -1,11 +0,0 @@
-eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
-org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
-org.eclipse.jdt.core.compiler.compliance=1.8
-org.eclipse.jdt.core.compiler.debug.lineNumber=generate
-org.eclipse.jdt.core.compiler.debug.localVariable=generate
-org.eclipse.jdt.core.compiler.debug.sourceFile=generate
-org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
-org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
-org.eclipse.jdt.core.compiler.source=1.8
diff --git a/liuxin/data-structure/answer/pom.xml b/liuxin/data-structure/answer/pom.xml
new file mode 100644
index 0000000000..ac6ba882df
--- /dev/null
+++ b/liuxin/data-structure/answer/pom.xml
@@ -0,0 +1,32 @@
+
+ 4.0.0
+
+ com.coderising
+ ds-answer
+ 0.0.1-SNAPSHOT
+ jar
+
+ ds-answer
+ http://maven.apache.org
+
+
+ UTF-8
+
+
+
+
+
+ junit
+ junit
+ 4.12
+
+
+
+
+
+ aliyunmaven
+ http://maven.aliyun.com/nexus/content/groups/public/
+
+
+
diff --git a/liuxin/data-structure/answer/src/main/java/com/coderising/download/DownloadThread.java b/liuxin/data-structure/answer/src/main/java/com/coderising/download/DownloadThread.java
new file mode 100644
index 0000000000..900a3ad358
--- /dev/null
+++ b/liuxin/data-structure/answer/src/main/java/com/coderising/download/DownloadThread.java
@@ -0,0 +1,20 @@
+package com.coderising.download;
+
+import com.coderising.download.api.Connection;
+
+public class DownloadThread extends Thread{
+
+ Connection conn;
+ int startPos;
+ int endPos;
+
+ public DownloadThread( Connection conn, int startPos, int endPos){
+
+ this.conn = conn;
+ this.startPos = startPos;
+ this.endPos = endPos;
+ }
+ public void run(){
+
+ }
+}
diff --git a/liuxin/data-structure/answer/src/main/java/com/coderising/download/FileDownloader.java b/liuxin/data-structure/answer/src/main/java/com/coderising/download/FileDownloader.java
new file mode 100644
index 0000000000..c3c8a3f27d
--- /dev/null
+++ b/liuxin/data-structure/answer/src/main/java/com/coderising/download/FileDownloader.java
@@ -0,0 +1,73 @@
+package com.coderising.download;
+
+import com.coderising.download.api.Connection;
+import com.coderising.download.api.ConnectionException;
+import com.coderising.download.api.ConnectionManager;
+import com.coderising.download.api.DownloadListener;
+
+
+public class FileDownloader {
+
+ String url;
+
+ DownloadListener listener;
+
+ ConnectionManager cm;
+
+
+ public FileDownloader(String _url) {
+ this.url = _url;
+
+ }
+
+ public void execute(){
+ // 在这里实现你的代码, 注意: 需要用多线程实现下载
+ // 这个类依赖于其他几个接口, 你需要写这几个接口的实现代码
+ // (1) ConnectionManager , 可以打开一个连接,通过Connection可以读取其中的一段(用startPos, endPos来指定)
+ // (2) DownloadListener, 由于是多线程下载, 调用这个类的客户端不知道什么时候结束,所以你需要实现当所有
+ // 线程都执行完以后, 调用listener的notifiedFinished方法, 这样客户端就能收到通知。
+ // 具体的实现思路:
+ // 1. 需要调用ConnectionManager的open方法打开连接, 然后通过Connection.getContentLength方法获得文件的长度
+ // 2. 至少启动3个线程下载, 注意每个线程需要先调用ConnectionManager的open方法
+ // 然后调用read方法, read方法中有读取文件的开始位置和结束位置的参数, 返回值是byte[]数组
+ // 3. 把byte数组写入到文件中
+ // 4. 所有的线程都下载完成以后, 需要调用listener的notifiedFinished方法
+
+ // 下面的代码是示例代码, 也就是说只有一个线程, 你需要改造成多线程的。
+ Connection conn = null;
+ try {
+
+ conn = cm.open(this.url);
+
+ int length = conn.getContentLength();
+
+ new DownloadThread(conn,0,length-1).start();
+
+ } catch (ConnectionException e) {
+ e.printStackTrace();
+ }finally{
+ if(conn != null){
+ conn.close();
+ }
+ }
+
+
+
+
+ }
+
+ public void setListener(DownloadListener listener) {
+ this.listener = listener;
+ }
+
+
+
+ public void setConnectionManager(ConnectionManager ucm){
+ this.cm = ucm;
+ }
+
+ public DownloadListener getListener(){
+ return this.listener;
+ }
+
+}
diff --git a/liuxin/data-structure/answer/src/main/java/com/coderising/download/FileDownloaderTest.java b/liuxin/data-structure/answer/src/main/java/com/coderising/download/FileDownloaderTest.java
new file mode 100644
index 0000000000..4ff7f46ae0
--- /dev/null
+++ b/liuxin/data-structure/answer/src/main/java/com/coderising/download/FileDownloaderTest.java
@@ -0,0 +1,59 @@
+package com.coderising.download;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.coderising.download.api.ConnectionManager;
+import com.coderising.download.api.DownloadListener;
+import com.coderising.download.impl.ConnectionManagerImpl;
+
+public class FileDownloaderTest {
+ boolean downloadFinished = false;
+ @Before
+ public void setUp() throws Exception {
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+ @Test
+ public void testDownload() {
+
+ String url = "http://localhost:8080/test.jpg";
+
+ FileDownloader downloader = new FileDownloader(url);
+
+
+ ConnectionManager cm = new ConnectionManagerImpl();
+ downloader.setConnectionManager(cm);
+
+ downloader.setListener(new DownloadListener() {
+ @Override
+ public void notifyFinished() {
+ downloadFinished = true;
+ }
+
+ });
+
+
+ downloader.execute();
+
+ // 等待多线程下载程序执行完毕
+ while (!downloadFinished) {
+ try {
+ System.out.println("还没有下载完成,休眠五秒");
+ //休眠5秒
+ Thread.sleep(5000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ System.out.println("下载完成!");
+
+
+
+ }
+
+}
diff --git a/liuxin/data-structure/answer/src/main/java/com/coderising/download/api/Connection.java b/liuxin/data-structure/answer/src/main/java/com/coderising/download/api/Connection.java
new file mode 100644
index 0000000000..0957eaf7f4
--- /dev/null
+++ b/liuxin/data-structure/answer/src/main/java/com/coderising/download/api/Connection.java
@@ -0,0 +1,23 @@
+package com.coderising.download.api;
+
+import java.io.IOException;
+
+public interface Connection {
+ /**
+ * 给定开始和结束位置, 读取数据, 返回值是字节数组
+ * @param startPos 开始位置, 从0开始
+ * @param endPos 结束位置
+ * @return
+ */
+ public byte[] read(int startPos,int endPos) throws IOException;
+ /**
+ * 得到数据内容的长度
+ * @return
+ */
+ public int getContentLength();
+
+ /**
+ * 关闭连接
+ */
+ public void close();
+}
diff --git a/liuxin/data-structure/answer/src/main/java/com/coderising/download/api/ConnectionException.java b/liuxin/data-structure/answer/src/main/java/com/coderising/download/api/ConnectionException.java
new file mode 100644
index 0000000000..1551a80b3d
--- /dev/null
+++ b/liuxin/data-structure/answer/src/main/java/com/coderising/download/api/ConnectionException.java
@@ -0,0 +1,5 @@
+package com.coderising.download.api;
+
+public class ConnectionException extends Exception {
+
+}
diff --git a/liuxin/data-structure/answer/src/main/java/com/coderising/download/api/ConnectionManager.java b/liuxin/data-structure/answer/src/main/java/com/coderising/download/api/ConnectionManager.java
new file mode 100644
index 0000000000..ce045393b1
--- /dev/null
+++ b/liuxin/data-structure/answer/src/main/java/com/coderising/download/api/ConnectionManager.java
@@ -0,0 +1,10 @@
+package com.coderising.download.api;
+
+public interface ConnectionManager {
+ /**
+ * 给定一个url , 打开一个连接
+ * @param url
+ * @return
+ */
+ public Connection open(String url) throws ConnectionException;
+}
diff --git a/liuxin/data-structure/answer/src/main/java/com/coderising/download/api/DownloadListener.java b/liuxin/data-structure/answer/src/main/java/com/coderising/download/api/DownloadListener.java
new file mode 100644
index 0000000000..bf9807b307
--- /dev/null
+++ b/liuxin/data-structure/answer/src/main/java/com/coderising/download/api/DownloadListener.java
@@ -0,0 +1,5 @@
+package com.coderising.download.api;
+
+public interface DownloadListener {
+ public void notifyFinished();
+}
diff --git a/liuxin/data-structure/answer/src/main/java/com/coderising/download/impl/ConnectionImpl.java b/liuxin/data-structure/answer/src/main/java/com/coderising/download/impl/ConnectionImpl.java
new file mode 100644
index 0000000000..36a9d2ce15
--- /dev/null
+++ b/liuxin/data-structure/answer/src/main/java/com/coderising/download/impl/ConnectionImpl.java
@@ -0,0 +1,27 @@
+package com.coderising.download.impl;
+
+import java.io.IOException;
+
+import com.coderising.download.api.Connection;
+
+public class ConnectionImpl implements Connection{
+
+ @Override
+ public byte[] read(int startPos, int endPos) throws IOException {
+
+ return null;
+ }
+
+ @Override
+ public int getContentLength() {
+
+ return 0;
+ }
+
+ @Override
+ public void close() {
+
+
+ }
+
+}
diff --git a/liuxin/data-structure/answer/src/main/java/com/coderising/download/impl/ConnectionManagerImpl.java b/liuxin/data-structure/answer/src/main/java/com/coderising/download/impl/ConnectionManagerImpl.java
new file mode 100644
index 0000000000..172371dd55
--- /dev/null
+++ b/liuxin/data-structure/answer/src/main/java/com/coderising/download/impl/ConnectionManagerImpl.java
@@ -0,0 +1,15 @@
+package com.coderising.download.impl;
+
+import com.coderising.download.api.Connection;
+import com.coderising.download.api.ConnectionException;
+import com.coderising.download.api.ConnectionManager;
+
+public class ConnectionManagerImpl implements ConnectionManager {
+
+ @Override
+ public Connection open(String url) throws ConnectionException {
+
+ return null;
+ }
+
+}
diff --git a/liuxin/data-structure/answer/src/main/java/com/coderising/litestruts/LoginAction.java b/liuxin/data-structure/answer/src/main/java/com/coderising/litestruts/LoginAction.java
new file mode 100644
index 0000000000..dcdbe226ed
--- /dev/null
+++ b/liuxin/data-structure/answer/src/main/java/com/coderising/litestruts/LoginAction.java
@@ -0,0 +1,39 @@
+package com.coderising.litestruts;
+
+/**
+ * 这是一个用来展示登录的业务类, 其中的用户名和密码都是硬编码的。
+ * @author liuxin
+ *
+ */
+public class LoginAction{
+ private String name ;
+ private String password;
+ private String message;
+
+ public String getName() {
+ return name;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public String execute(){
+ if("test".equals(name) && "1234".equals(password)){
+ this.message = "login successful";
+ return "success";
+ }
+ this.message = "login failed,please check your user/pwd";
+ return "fail";
+ }
+
+ public void setName(String name){
+ this.name = name;
+ }
+ public void setPassword(String password){
+ this.password = password;
+ }
+ public String getMessage(){
+ return this.message;
+ }
+}
diff --git a/liuxin/data-structure/answer/src/main/java/com/coderising/litestruts/Struts.java b/liuxin/data-structure/answer/src/main/java/com/coderising/litestruts/Struts.java
new file mode 100644
index 0000000000..85e2e22de3
--- /dev/null
+++ b/liuxin/data-structure/answer/src/main/java/com/coderising/litestruts/Struts.java
@@ -0,0 +1,34 @@
+package com.coderising.litestruts;
+
+import java.util.Map;
+
+
+
+public class Struts {
+
+ public static View runAction(String actionName, Map parameters) {
+
+ /*
+
+ 0. 读取配置文件struts.xml
+
+ 1. 根据actionName找到相对应的class , 例如LoginAction, 通过反射实例化(创建对象)
+ 据parameters中的数据,调用对象的setter方法, 例如parameters中的数据是
+ ("name"="test" , "password"="1234") ,
+ 那就应该调用 setName和setPassword方法
+
+ 2. 通过反射调用对象的exectue 方法, 并获得返回值,例如"success"
+
+ 3. 通过反射找到对象的所有getter方法(例如 getMessage),
+ 通过反射来调用, 把值和属性形成一个HashMap , 例如 {"message": "登录成功"} ,
+ 放到View对象的parameters
+
+ 4. 根据struts.xml中的 配置,以及execute的返回值, 确定哪一个jsp,
+ 放到View对象的jsp字段中。
+
+ */
+
+ return null;
+ }
+
+}
diff --git a/liuxin/data-structure/answer/src/main/java/com/coderising/litestruts/StrutsTest.java b/liuxin/data-structure/answer/src/main/java/com/coderising/litestruts/StrutsTest.java
new file mode 100644
index 0000000000..b8c81faf3c
--- /dev/null
+++ b/liuxin/data-structure/answer/src/main/java/com/coderising/litestruts/StrutsTest.java
@@ -0,0 +1,43 @@
+package com.coderising.litestruts;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+
+
+
+
+public class StrutsTest {
+
+ @Test
+ public void testLoginActionSuccess() {
+
+ String actionName = "login";
+
+ Map params = new HashMap();
+ params.put("name","test");
+ params.put("password","1234");
+
+
+ View view = Struts.runAction(actionName,params);
+
+ Assert.assertEquals("/jsp/homepage.jsp", view.getJsp());
+ Assert.assertEquals("login successful", view.getParameters().get("message"));
+ }
+
+ @Test
+ public void testLoginActionFailed() {
+ String actionName = "login";
+ Map params = new HashMap();
+ params.put("name","test");
+ params.put("password","123456"); //密码和预设的不一致
+
+ View view = Struts.runAction(actionName,params);
+
+ Assert.assertEquals("/jsp/showLogin.jsp", view.getJsp());
+ Assert.assertEquals("login failed,please check your user/pwd", view.getParameters().get("message"));
+ }
+}
diff --git a/liuxin/data-structure/answer/src/main/java/com/coderising/litestruts/View.java b/liuxin/data-structure/answer/src/main/java/com/coderising/litestruts/View.java
new file mode 100644
index 0000000000..07df2a5dab
--- /dev/null
+++ b/liuxin/data-structure/answer/src/main/java/com/coderising/litestruts/View.java
@@ -0,0 +1,23 @@
+package com.coderising.litestruts;
+
+import java.util.Map;
+
+public class View {
+ private String jsp;
+ private Map parameters;
+
+ public String getJsp() {
+ return jsp;
+ }
+ public View setJsp(String jsp) {
+ this.jsp = jsp;
+ return this;
+ }
+ public Map getParameters() {
+ return parameters;
+ }
+ public View setParameters(Map parameters) {
+ this.parameters = parameters;
+ return this;
+ }
+}
diff --git a/liuxin/data-structure/answer/src/main/java/com/coderising/litestruts/struts.xml b/liuxin/data-structure/answer/src/main/java/com/coderising/litestruts/struts.xml
new file mode 100644
index 0000000000..e5d9aebba8
--- /dev/null
+++ b/liuxin/data-structure/answer/src/main/java/com/coderising/litestruts/struts.xml
@@ -0,0 +1,11 @@
+
+
+
+ /jsp/homepage.jsp
+ /jsp/showLogin.jsp
+
+
+ /jsp/welcome.jsp
+ /jsp/error.jsp
+
+
\ No newline at end of file
diff --git a/group17/1204187480/code/homework/basic/src/main/java/com/coding/basic/Iterator.java b/liuxin/data-structure/answer/src/main/java/com/coding/basic/Iterator.java
similarity index 100%
rename from group17/1204187480/code/homework/basic/src/main/java/com/coding/basic/Iterator.java
rename to liuxin/data-structure/answer/src/main/java/com/coding/basic/Iterator.java
diff --git a/group17/1204187480/code/homework/basic/src/main/java/com/coding/basic/List.java b/liuxin/data-structure/answer/src/main/java/com/coding/basic/List.java
similarity index 100%
rename from group17/1204187480/code/homework/basic/src/main/java/com/coding/basic/List.java
rename to liuxin/data-structure/answer/src/main/java/com/coding/basic/List.java
diff --git a/liuxin/src/com/coding/basic/ArrayList.java b/liuxin/data-structure/answer/src/main/java/com/coding/basic/array/ArrayList.java
similarity index 80%
rename from liuxin/src/com/coding/basic/ArrayList.java
rename to liuxin/data-structure/answer/src/main/java/com/coding/basic/array/ArrayList.java
index 1f185736f9..4576c016af 100644
--- a/liuxin/src/com/coding/basic/ArrayList.java
+++ b/liuxin/data-structure/answer/src/main/java/com/coding/basic/array/ArrayList.java
@@ -1,4 +1,7 @@
-package com.coding.basic;
+package com.coding.basic.array;
+
+import com.coding.basic.Iterator;
+import com.coding.basic.List;
public class ArrayList implements List {
diff --git a/liuxin/data-structure/answer/src/main/java/com/coding/basic/array/ArrayUtil.java b/liuxin/data-structure/answer/src/main/java/com/coding/basic/array/ArrayUtil.java
new file mode 100644
index 0000000000..45740e6d57
--- /dev/null
+++ b/liuxin/data-structure/answer/src/main/java/com/coding/basic/array/ArrayUtil.java
@@ -0,0 +1,96 @@
+package com.coding.basic.array;
+
+public class ArrayUtil {
+
+ /**
+ * 给定一个整形数组a , 对该数组的值进行置换
+ 例如: a = [7, 9 , 30, 3] , 置换后为 [3, 30, 9,7]
+ 如果 a = [7, 9, 30, 3, 4] , 置换后为 [4,3, 30 , 9,7]
+ * @param origin
+ * @return
+ */
+ public void reverseArray(int[] origin){
+
+ }
+
+ /**
+ * 现在有如下的一个数组: int oldArr[]={1,3,4,5,0,0,6,6,0,5,4,7,6,7,0,5}
+ * 要求将以上数组中值为0的项去掉,将不为0的值存入一个新的数组,生成的新数组为:
+ * {1,3,4,5,6,6,5,4,7,6,7,5}
+ * @param oldArray
+ * @return
+ */
+
+ public int[] removeZero(int[] oldArray){
+ return null;
+ }
+
+ /**
+ * 给定两个已经排序好的整形数组, a1和a2 , 创建一个新的数组a3, 使得a3 包含a1和a2 的所有元素, 并且仍然是有序的
+ * 例如 a1 = [3, 5, 7,8] a2 = [4, 5, 6,7] 则 a3 为[3,4,5,6,7,8] , 注意: 已经消除了重复
+ * @param array1
+ * @param array2
+ * @return
+ */
+
+ public int[] merge(int[] array1, int[] array2){
+ return null;
+ }
+ /**
+ * 把一个已经存满数据的数组 oldArray的容量进行扩展, 扩展后的新数据大小为oldArray.length + size
+ * 注意,老数组的元素在新数组中需要保持
+ * 例如 oldArray = [2,3,6] , size = 3,则返回的新数组为
+ * [2,3,6,0,0,0]
+ * @param oldArray
+ * @param size
+ * @return
+ */
+ public int[] grow(int [] oldArray, int size){
+ return null;
+ }
+
+ /**
+ * 斐波那契数列为:1,1,2,3,5,8,13,21...... ,给定一个最大值, 返回小于该值的数列
+ * 例如, max = 15 , 则返回的数组应该为 [1,1,2,3,5,8,13]
+ * max = 1, 则返回空数组 []
+ * @param max
+ * @return
+ */
+ public int[] fibonacci(int max){
+ return null;
+ }
+
+ /**
+ * 返回小于给定最大值max的所有素数数组
+ * 例如max = 23, 返回的数组为[2,3,5,7,11,13,17,19]
+ * @param max
+ * @return
+ */
+ public int[] getPrimes(int max){
+ return null;
+ }
+
+ /**
+ * 所谓“完数”, 是指这个数恰好等于它的因子之和,例如6=1+2+3
+ * 给定一个最大值max, 返回一个数组, 数组中是小于max 的所有完数
+ * @param max
+ * @return
+ */
+ public int[] getPerfectNumbers(int max){
+ return null;
+ }
+
+ /**
+ * 用seperator 把数组 array给连接起来
+ * 例如array= [3,8,9], seperator = "-"
+ * 则返回值为"3-8-9"
+ * @param array
+ * @param s
+ * @return
+ */
+ public String join(int[] array, String seperator){
+ return null;
+ }
+
+
+}
diff --git a/liuxin/data-structure/answer/src/main/java/com/coding/basic/linklist/LRUPageFrame.java b/liuxin/data-structure/answer/src/main/java/com/coding/basic/linklist/LRUPageFrame.java
new file mode 100644
index 0000000000..24b9d8b155
--- /dev/null
+++ b/liuxin/data-structure/answer/src/main/java/com/coding/basic/linklist/LRUPageFrame.java
@@ -0,0 +1,164 @@
+package com.coding.basic.linklist;
+
+
+public class LRUPageFrame {
+
+ private static class Node {
+
+ Node prev;
+ Node next;
+ int pageNum;
+
+ Node() {
+ }
+ }
+
+ private int capacity;
+
+ private int currentSize;
+ private Node first;// 链表头
+ private Node last;// 链表尾
+
+
+ public LRUPageFrame(int capacity) {
+ this.currentSize = 0;
+ this.capacity = capacity;
+
+ }
+
+ /**
+ * 获取缓存中对象
+ *
+ * @param key
+ * @return
+ */
+ public void access(int pageNum) {
+
+ Node node = find(pageNum);
+ //在该队列中存在, 则提到队列头
+ if (node != null) {
+
+ moveExistingNodeToHead(node);
+
+ } else{
+
+ node = new Node();
+ node.pageNum = pageNum;
+
+ // 缓存容器是否已经超过大小.
+ if (currentSize >= capacity) {
+ removeLast();
+
+ }
+
+ addNewNodetoHead(node);
+
+
+
+
+ }
+ }
+
+ private void addNewNodetoHead(Node node) {
+
+ if(isEmpty()){
+
+ node.prev = null;
+ node.next = null;
+ first = node;
+ last = node;
+
+ } else{
+ node.prev = null;
+ node.next = first;
+ first.prev = node;
+ first = node;
+ }
+ this.currentSize ++;
+ }
+
+ private Node find(int data){
+
+ Node node = first;
+ while(node != null){
+ if(node.pageNum == data){
+ return node;
+ }
+ node = node.next;
+ }
+ return null;
+
+ }
+
+
+
+
+
+
+ /**
+ * 删除链表尾部节点 表示 删除最少使用的缓存对象
+ */
+ private void removeLast() {
+ Node prev = last.prev;
+ prev.next = null;
+ last.prev = null;
+ last = prev;
+ this.currentSize --;
+ }
+
+ /**
+ * 移动到链表头,表示这个节点是最新使用过的
+ *
+ * @param node
+ */
+ private void moveExistingNodeToHead(Node node) {
+
+ if (node == first) {
+
+ return;
+ }
+ else if(node == last){
+ //当前节点是链表尾, 需要放到链表头
+ Node prevNode = node.prev;
+ prevNode.next = null;
+ last.prev = null;
+ last = prevNode;
+
+ } else{
+ //node 在链表的中间, 把node 的前后节点连接起来
+ Node prevNode = node.prev;
+ prevNode.next = node.next;
+
+ Node nextNode = node.next;
+ nextNode.prev = prevNode;
+
+
+ }
+
+ node.prev = null;
+ node.next = first;
+ first.prev = node;
+ first = node;
+
+ }
+ private boolean isEmpty(){
+ return (first == null) && (last == null);
+ }
+
+ public String toString(){
+ StringBuilder buffer = new StringBuilder();
+ Node node = first;
+ while(node != null){
+ buffer.append(node.pageNum);
+
+ node = node.next;
+ if(node != null){
+ buffer.append(",");
+ }
+ }
+ return buffer.toString();
+ }
+
+
+
+}
diff --git a/liuxin/data-structure/answer/src/main/java/com/coding/basic/linklist/LRUPageFrameTest.java b/liuxin/data-structure/answer/src/main/java/com/coding/basic/linklist/LRUPageFrameTest.java
new file mode 100644
index 0000000000..7fd72fc2b4
--- /dev/null
+++ b/liuxin/data-structure/answer/src/main/java/com/coding/basic/linklist/LRUPageFrameTest.java
@@ -0,0 +1,34 @@
+package com.coding.basic.linklist;
+
+import org.junit.Assert;
+
+import org.junit.Test;
+
+
+public class LRUPageFrameTest {
+
+ @Test
+ public void testAccess() {
+ LRUPageFrame frame = new LRUPageFrame(3);
+ frame.access(7);
+ frame.access(0);
+ frame.access(1);
+ Assert.assertEquals("1,0,7", frame.toString());
+ frame.access(2);
+ Assert.assertEquals("2,1,0", frame.toString());
+ frame.access(0);
+ Assert.assertEquals("0,2,1", frame.toString());
+ frame.access(0);
+ Assert.assertEquals("0,2,1", frame.toString());
+ frame.access(3);
+ Assert.assertEquals("3,0,2", frame.toString());
+ frame.access(0);
+ Assert.assertEquals("0,3,2", frame.toString());
+ frame.access(4);
+ Assert.assertEquals("4,0,3", frame.toString());
+ frame.access(5);
+ Assert.assertEquals("5,4,0", frame.toString());
+
+ }
+
+}
diff --git a/liuxin/data-structure/answer/src/main/java/com/coding/basic/linklist/LinkedList.java b/liuxin/data-structure/answer/src/main/java/com/coding/basic/linklist/LinkedList.java
new file mode 100644
index 0000000000..f4c7556a2e
--- /dev/null
+++ b/liuxin/data-structure/answer/src/main/java/com/coding/basic/linklist/LinkedList.java
@@ -0,0 +1,125 @@
+package com.coding.basic.linklist;
+
+import com.coding.basic.Iterator;
+import com.coding.basic.List;
+
+public class LinkedList implements List {
+
+ private Node head;
+
+ public void add(Object o){
+
+ }
+ public void add(int index , Object o){
+
+ }
+ public Object get(int index){
+ return null;
+ }
+ public Object remove(int index){
+ return null;
+ }
+
+ public int size(){
+ return -1;
+ }
+
+ public void addFirst(Object o){
+
+ }
+ public void addLast(Object o){
+
+ }
+ public Object removeFirst(){
+ return null;
+ }
+ public Object removeLast(){
+ return null;
+ }
+ public Iterator iterator(){
+ return null;
+ }
+
+
+ private static class Node{
+ Object data;
+ Node next;
+
+ }
+
+ /**
+ * 把该链表逆置
+ * 例如链表为 3->7->10 , 逆置后变为 10->7->3
+ */
+ public void reverse(){
+
+ }
+
+ /**
+ * 删除一个单链表的前半部分
+ * 例如:list = 2->5->7->8 , 删除以后的值为 7->8
+ * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10
+
+ */
+ public void removeFirstHalf(){
+
+ }
+
+ /**
+ * 从第i个元素开始, 删除length 个元素 , 注意i从0开始
+ * @param i
+ * @param length
+ */
+ public void remove(int i, int length){
+
+ }
+ /**
+ * 假定当前链表和listB均包含已升序排列的整数
+ * 从当前链表中取出那些listB所指定的元素
+ * 例如当前链表 = 11->101->201->301->401->501->601->701
+ * listB = 1->3->4->6
+ * 返回的结果应该是[101,301,401,601]
+ * @param list
+ */
+ public int[] getElements(LinkedList list){
+ return null;
+ }
+
+ /**
+ * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。
+ * 从当前链表中中删除在listB中出现的元素
+
+ * @param list
+ */
+
+ public void subtract(LinkedList list){
+
+ }
+
+ /**
+ * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。
+ * 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同)
+ */
+ public void removeDuplicateValues(){
+
+ }
+
+ /**
+ * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。
+ * 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素)
+ * @param min
+ * @param max
+ */
+ public void removeRange(int min, int max){
+
+ }
+
+ /**
+ * 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同)
+ * 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列
+ * @param list
+ */
+ public LinkedList intersection( LinkedList list){
+ return null;
+ }
+}
diff --git a/liuxin/data-structure/answer/src/main/java/com/coding/basic/queue/CircleQueue.java b/liuxin/data-structure/answer/src/main/java/com/coding/basic/queue/CircleQueue.java
new file mode 100644
index 0000000000..f169d5f8e4
--- /dev/null
+++ b/liuxin/data-structure/answer/src/main/java/com/coding/basic/queue/CircleQueue.java
@@ -0,0 +1,47 @@
+package com.coding.basic.queue;
+
+public class CircleQueue {
+
+ //用数组来保存循环队列的元素
+ private Object[] elementData ;
+ int size = 0;
+ //队头
+ private int front = 0;
+ //队尾
+ private int rear = 0;
+
+ public CircleQueue(int capacity){
+ elementData = new Object[capacity];
+ }
+ public boolean isEmpty() {
+ return (front == rear) && !isFull();
+
+ }
+
+ public boolean isFull(){
+ return size == elementData.length;
+ }
+ public int size() {
+ return size;
+ }
+
+ public void enQueue(E data) {
+ if(isFull()){
+ throw new RuntimeException("The queue is full");
+ }
+ rear = (rear+1) % elementData.length;
+ elementData[rear++] = data;
+ size++;
+ }
+
+ public E deQueue() {
+ if(isEmpty()){
+ throw new RuntimeException("The queue is empty");
+ }
+ E data = (E)elementData[front];
+ elementData[front] = null;
+ front = (front+1) % elementData.length;
+ size --;
+ return data;
+ }
+}
diff --git a/liuxin/data-structure/answer/src/main/java/com/coding/basic/queue/CircleQueueTest.java b/liuxin/data-structure/answer/src/main/java/com/coding/basic/queue/CircleQueueTest.java
new file mode 100644
index 0000000000..7307eb77d4
--- /dev/null
+++ b/liuxin/data-structure/answer/src/main/java/com/coding/basic/queue/CircleQueueTest.java
@@ -0,0 +1,44 @@
+package com.coding.basic.queue;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+
+
+public class CircleQueueTest {
+
+ @Before
+ public void setUp() throws Exception {
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+ @Test
+ public void test() {
+ CircleQueue queue = new CircleQueue(5);
+ Assert.assertTrue(queue.isEmpty());
+ Assert.assertFalse(queue.isFull());
+
+ queue.enQueue("a");
+ queue.enQueue("b");
+ queue.enQueue("c");
+ queue.enQueue("d");
+ queue.enQueue("e");
+
+ Assert.assertTrue(queue.isFull());
+ Assert.assertFalse(queue.isEmpty());
+ Assert.assertEquals(5, queue.size());
+
+ Assert.assertEquals("a", queue.deQueue());
+ Assert.assertEquals("b", queue.deQueue());
+ Assert.assertEquals("c", queue.deQueue());
+ Assert.assertEquals("d", queue.deQueue());
+ Assert.assertEquals("e", queue.deQueue());
+
+ }
+
+}
diff --git a/liuxin/data-structure/answer/src/main/java/com/coding/basic/queue/Josephus.java b/liuxin/data-structure/answer/src/main/java/com/coding/basic/queue/Josephus.java
new file mode 100644
index 0000000000..36ec615d36
--- /dev/null
+++ b/liuxin/data-structure/answer/src/main/java/com/coding/basic/queue/Josephus.java
@@ -0,0 +1,39 @@
+package com.coding.basic.queue;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 用Queue来实现Josephus问题
+ * 在这个古老的问题当中, N个深陷绝境的人一致同意用这种方式减少生存人数: N个人围成一圈(位置记为0到N-1), 并且从第一个人报数, 报到M的人会被杀死, 直到最后一个人留下来
+ * @author liuxin
+ *
+ */
+public class Josephus {
+
+ public static List execute(int n, int m){
+
+ Queue queue = new Queue();
+ for (int i = 0; i < n; i++){
+ queue.enQueue(i);
+ }
+
+ List result = new ArrayList();
+ int i = 0;
+
+ while (!queue.isEmpty()) {
+
+ int x = queue.deQueue();
+
+ if (++i % m == 0){
+ result.add(x);
+ } else{
+ queue.enQueue(x);
+ }
+ }
+
+
+ return result;
+ }
+
+}
diff --git a/liuxin/data-structure/answer/src/main/java/com/coding/basic/queue/JosephusTest.java b/liuxin/data-structure/answer/src/main/java/com/coding/basic/queue/JosephusTest.java
new file mode 100644
index 0000000000..7d90318b51
--- /dev/null
+++ b/liuxin/data-structure/answer/src/main/java/com/coding/basic/queue/JosephusTest.java
@@ -0,0 +1,27 @@
+package com.coding.basic.queue;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+
+
+public class JosephusTest {
+
+ @Before
+ public void setUp() throws Exception {
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+ @Test
+ public void testExecute() {
+
+ Assert.assertEquals("[1, 3, 5, 0, 4, 2, 6]", Josephus.execute(7, 2).toString());
+
+ }
+
+}
diff --git a/liuxin/data-structure/answer/src/main/java/com/coding/basic/queue/Queue.java b/liuxin/data-structure/answer/src/main/java/com/coding/basic/queue/Queue.java
new file mode 100644
index 0000000000..c4c4b7325e
--- /dev/null
+++ b/liuxin/data-structure/answer/src/main/java/com/coding/basic/queue/Queue.java
@@ -0,0 +1,61 @@
+package com.coding.basic.queue;
+
+import java.util.NoSuchElementException;
+
+public class Queue {
+ private Node first;
+ private Node last;
+ private int size;
+
+
+ private static class Node {
+ private E item;
+ private Node next;
+ }
+
+
+ public Queue() {
+ first = null;
+ last = null;
+ size = 0;
+ }
+
+
+ public boolean isEmpty() {
+ return first == null;
+ }
+
+ public int size() {
+ return size;
+ }
+
+
+
+ public void enQueue(E data) {
+ Node oldlast = last;
+ last = new Node();
+ last.item = data;
+ last.next = null;
+ if (isEmpty()) {
+ first = last;
+ }
+ else{
+ oldlast.next = last;
+ }
+ size++;
+ }
+
+ public E deQueue() {
+ if (isEmpty()) {
+ throw new NoSuchElementException("Queue underflow");
+ }
+ E item = first.item;
+ first = first.next;
+ size--;
+ if (isEmpty()) {
+ last = null;
+ }
+ return item;
+ }
+
+}
diff --git a/liuxin/data-structure/answer/src/main/java/com/coding/basic/queue/QueueWithTwoStacks.java b/liuxin/data-structure/answer/src/main/java/com/coding/basic/queue/QueueWithTwoStacks.java
new file mode 100644
index 0000000000..bc97df0800
--- /dev/null
+++ b/liuxin/data-structure/answer/src/main/java/com/coding/basic/queue/QueueWithTwoStacks.java
@@ -0,0 +1,55 @@
+package com.coding.basic.queue;
+
+import java.util.NoSuchElementException;
+import java.util.Stack;
+
+public class QueueWithTwoStacks {
+ private Stack stack1;
+ private Stack stack2;
+
+
+ public QueueWithTwoStacks() {
+ stack1 = new Stack();
+ stack2 = new Stack();
+ }
+
+
+ private void moveStack1ToStack2() {
+ while (!stack1.isEmpty()){
+ stack2.push(stack1.pop());
+ }
+
+ }
+
+
+ public boolean isEmpty() {
+ return stack1.isEmpty() && stack2.isEmpty();
+ }
+
+
+
+ public int size() {
+ return stack1.size() + stack2.size();
+ }
+
+
+
+ public void enQueue(E item) {
+ stack1.push(item);
+ }
+
+ public E deQueue() {
+ if (isEmpty()) {
+ throw new NoSuchElementException("Queue is empty");
+ }
+ if (stack2.isEmpty()) {
+ moveStack1ToStack2();
+ }
+
+ return stack2.pop();
+ }
+
+
+
+ }
+
diff --git a/liuxin/data-structure/answer/src/main/java/com/coding/basic/stack/QuickMinStack.java b/liuxin/data-structure/answer/src/main/java/com/coding/basic/stack/QuickMinStack.java
new file mode 100644
index 0000000000..faf2644ab1
--- /dev/null
+++ b/liuxin/data-structure/answer/src/main/java/com/coding/basic/stack/QuickMinStack.java
@@ -0,0 +1,44 @@
+package com.coding.basic.stack;
+
+import java.util.Stack;
+/**
+ * 设计一个栈,支持栈的push和pop操作,以及第三种操作findMin, 它返回改数据结构中的最小元素
+ * finMin操作最坏的情形下时间复杂度应该是O(1) , 简单来讲,操作一次就可以得到最小值
+ * @author liuxin
+ *
+ */
+public class QuickMinStack {
+
+ private Stack normalStack = new Stack();
+ private Stack minNumStack = new Stack();
+
+ public void push(int data){
+
+ normalStack.push(data);
+
+ if(minNumStack.isEmpty()){
+ minNumStack.push(data);
+ } else{
+ if(minNumStack.peek() >= data) {
+ minNumStack.push(data);
+ }
+ }
+
+ }
+ public int pop(){
+ if(normalStack.isEmpty()){
+ throw new RuntimeException("the stack is empty");
+ }
+ int value = normalStack.pop();
+ if(value == minNumStack.peek()){
+ minNumStack.pop();
+ }
+ return value;
+ }
+ public int findMin(){
+ if(minNumStack.isEmpty()){
+ throw new RuntimeException("the stack is empty");
+ }
+ return minNumStack.peek();
+ }
+}
\ No newline at end of file
diff --git a/liuxin/data-structure/answer/src/main/java/com/coding/basic/stack/QuickMinStackTest.java b/liuxin/data-structure/answer/src/main/java/com/coding/basic/stack/QuickMinStackTest.java
new file mode 100644
index 0000000000..efe41a9f8f
--- /dev/null
+++ b/liuxin/data-structure/answer/src/main/java/com/coding/basic/stack/QuickMinStackTest.java
@@ -0,0 +1,39 @@
+package com.coding.basic.stack;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+
+public class QuickMinStackTest {
+
+ @Before
+ public void setUp() throws Exception {
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+ @Test
+ public void test() {
+ QuickMinStack stack = new QuickMinStack();
+ stack.push(5);
+ Assert.assertEquals(5, stack.findMin());
+ stack.push(6);
+ Assert.assertEquals(5, stack.findMin());
+ stack.push(4);
+ Assert.assertEquals(4, stack.findMin());
+ stack.push(4);
+ Assert.assertEquals(4, stack.findMin());
+
+ stack.pop();
+ Assert.assertEquals(4, stack.findMin());
+ stack.pop();
+ Assert.assertEquals(5, stack.findMin());
+ stack.pop();
+ Assert.assertEquals(5, stack.findMin());
+ }
+
+}
diff --git a/liuxin/src/com/coding/basic/Stack.java b/liuxin/data-structure/answer/src/main/java/com/coding/basic/stack/Stack.java
similarity index 78%
rename from liuxin/src/com/coding/basic/Stack.java
rename to liuxin/data-structure/answer/src/main/java/com/coding/basic/stack/Stack.java
index a5a04de76d..fedb243604 100644
--- a/liuxin/src/com/coding/basic/Stack.java
+++ b/liuxin/data-structure/answer/src/main/java/com/coding/basic/stack/Stack.java
@@ -1,4 +1,6 @@
-package com.coding.basic;
+package com.coding.basic.stack;
+
+import com.coding.basic.array.ArrayList;
public class Stack {
private ArrayList elementData = new ArrayList();
diff --git a/liuxin/data-structure/answer/src/main/java/com/coding/basic/stack/StackUtil.java b/liuxin/data-structure/answer/src/main/java/com/coding/basic/stack/StackUtil.java
new file mode 100644
index 0000000000..7c86d22fe7
--- /dev/null
+++ b/liuxin/data-structure/answer/src/main/java/com/coding/basic/stack/StackUtil.java
@@ -0,0 +1,168 @@
+package com.coding.basic.stack;
+import java.util.Stack;
+public class StackUtil {
+
+ public static void bad_reverse(Stack s) {
+ if(s == null || s.isEmpty()){
+ return;
+ }
+ Stack tmpStack = new Stack();
+ while(!s.isEmpty()){
+ tmpStack.push(s.pop());
+ }
+
+ s = tmpStack;
+
+ }
+
+
+
+ public static void reverse_247565311(Stack s){
+ if(s == null || s.isEmpty()) {
+ return;
+ }
+
+ int size = s.size();
+ Stack tmpStack = new Stack();
+
+ for(int i=0;ii){
+ tmpStack.push(s.pop());
+ }
+ s.push(top);
+ while(tmpStack.size()>0){
+ s.push(tmpStack.pop());
+ }
+ }
+ }
+
+
+
+ /**
+ * 假设栈中的元素是Integer, 从栈顶到栈底是 : 5,4,3,2,1 调用该方法后, 元素次序变为: 1,2,3,4,5
+ * 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助
+ */
+ public static void reverse(Stack s) {
+ if(s == null || s.isEmpty()){
+ return;
+ }
+
+ Stack tmp = new Stack();
+ while(!s.isEmpty()){
+ tmp.push(s.pop());
+ }
+ while(!tmp.isEmpty()){
+ Integer top = tmp.pop();
+ addToBottom(s,top);
+ }
+
+
+ }
+ public static void addToBottom(Stack s, Integer value){
+ if(s.isEmpty()){
+ s.push(value);
+ } else{
+ Integer top = s.pop();
+ addToBottom(s,value);
+ s.push(top);
+ }
+
+ }
+ /**
+ * 删除栈中的某个元素 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助
+ *
+ * @param o
+ */
+ public static void remove(Stack s,Object o) {
+ if(s == null || s.isEmpty()){
+ return;
+ }
+ Stack tmpStack = new Stack();
+
+ while(!s.isEmpty()){
+ Object value = s.pop();
+ if(!value.equals(o)){
+ tmpStack.push(value);
+ }
+ }
+
+ while(!tmpStack.isEmpty()){
+ s.push(tmpStack.pop());
+ }
+ }
+
+ /**
+ * 从栈顶取得len个元素, 原来的栈中元素保持不变
+ * 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助
+ * @param len
+ * @return
+ */
+ public static Object[] getTop(Stack s,int len) {
+
+ if(s == null || s.isEmpty() || s.size() stack = new Stack();
+ for(int i=0;i s = new Stack();
+ s.push(1);
+ s.push(2);
+ s.push(3);
+
+ StackUtil.addToBottom(s, 0);
+
+ Assert.assertEquals("[0, 1, 2, 3]", s.toString());
+
+ }
+ @Test
+ public void testReverse() {
+ Stack s = new Stack();
+ s.push(1);
+ s.push(2);
+ s.push(3);
+ s.push(4);
+ s.push(5);
+ Assert.assertEquals("[1, 2, 3, 4, 5]", s.toString());
+ StackUtil.reverse(s);
+ Assert.assertEquals("[5, 4, 3, 2, 1]", s.toString());
+ }
+ @Test
+ public void testReverse_247565311() {
+ Stack s = new Stack();
+ s.push(1);
+ s.push(2);
+ s.push(3);
+
+ Assert.assertEquals("[1, 2, 3]", s.toString());
+ StackUtil.reverse_247565311(s);
+ Assert.assertEquals("[3, 2, 1]", s.toString());
+ }
+ @Test
+ public void testRemove() {
+ Stack s = new Stack();
+ s.push(1);
+ s.push(2);
+ s.push(3);
+ StackUtil.remove(s, 2);
+ Assert.assertEquals("[1, 3]", s.toString());
+ }
+
+ @Test
+ public void testGetTop() {
+ Stack s = new Stack();
+ s.push(1);
+ s.push(2);
+ s.push(3);
+ s.push(4);
+ s.push(5);
+ {
+ Object[] values = StackUtil.getTop(s, 3);
+ Assert.assertEquals(5, values[0]);
+ Assert.assertEquals(4, values[1]);
+ Assert.assertEquals(3, values[2]);
+ }
+ }
+
+ @Test
+ public void testIsValidPairs() {
+ Assert.assertTrue(StackUtil.isValidPairs("([e{d}f])"));
+ Assert.assertFalse(StackUtil.isValidPairs("([b{x]y})"));
+ }
+
+}
diff --git a/liuxin/data-structure/answer/src/main/java/com/coding/basic/stack/StackWithTwoQueues.java b/liuxin/data-structure/answer/src/main/java/com/coding/basic/stack/StackWithTwoQueues.java
new file mode 100644
index 0000000000..7a58fbff56
--- /dev/null
+++ b/liuxin/data-structure/answer/src/main/java/com/coding/basic/stack/StackWithTwoQueues.java
@@ -0,0 +1,53 @@
+package com.coding.basic.stack;
+
+import java.util.ArrayDeque;
+import java.util.Queue;
+
+public class StackWithTwoQueues {
+ Queue queue1 = new ArrayDeque<>();
+ Queue queue2 = new ArrayDeque<>();
+
+ public void push(int data) {
+ //两个栈都为空时,优先考虑queue1
+ if (queue1.isEmpty()&&queue2.isEmpty()) {
+ queue1.add(data);
+ return;
+ }
+
+ if (queue1.isEmpty()) {
+ queue2.add(data);
+ return;
+ }
+
+ if (queue2.isEmpty()) {
+ queue1.add(data);
+ return;
+ }
+
+ }
+
+ public int pop() {
+
+ if (queue1.isEmpty()&&queue2.isEmpty()) {
+ throw new RuntimeException("stack is empty");
+ }
+
+ if (queue1.isEmpty()) {
+ while (queue2.size()>1) {
+ queue1.add(queue2.poll());
+ }
+ return queue2.poll();
+ }
+
+ if (queue2.isEmpty()) {
+ while (queue1.size()>1) {
+ queue2.add(queue1.poll());
+ }
+ return queue1.poll();
+ }
+
+ throw new RuntimeException("no queue is empty, this is not allowed");
+
+
+ }
+}
diff --git a/liuxin/data-structure/answer/src/main/java/com/coding/basic/stack/StackWithTwoQueuesTest.java b/liuxin/data-structure/answer/src/main/java/com/coding/basic/stack/StackWithTwoQueuesTest.java
new file mode 100644
index 0000000000..4541b1f040
--- /dev/null
+++ b/liuxin/data-structure/answer/src/main/java/com/coding/basic/stack/StackWithTwoQueuesTest.java
@@ -0,0 +1,36 @@
+package com.coding.basic.stack;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+
+
+public class StackWithTwoQueuesTest {
+
+ @Before
+ public void setUp() throws Exception {
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+ @Test
+ public void test() {
+ StackWithTwoQueues stack = new StackWithTwoQueues();
+ stack.push(1);
+ stack.push(2);
+ stack.push(3);
+ stack.push(4);
+ Assert.assertEquals(4, stack.pop());
+ Assert.assertEquals(3, stack.pop());
+
+ stack.push(5);
+ Assert.assertEquals(5, stack.pop());
+ Assert.assertEquals(2, stack.pop());
+ Assert.assertEquals(1, stack.pop());
+ }
+
+}
diff --git a/liuxin/data-structure/answer/src/main/java/com/coding/basic/stack/Tail.java b/liuxin/data-structure/answer/src/main/java/com/coding/basic/stack/Tail.java
new file mode 100644
index 0000000000..7f30ce55c8
--- /dev/null
+++ b/liuxin/data-structure/answer/src/main/java/com/coding/basic/stack/Tail.java
@@ -0,0 +1,5 @@
+package com.coding.basic.stack;
+
+public class Tail {
+
+}
diff --git a/liuxin/data-structure/answer/src/main/java/com/coding/basic/stack/TwoStackInOneArray.java b/liuxin/data-structure/answer/src/main/java/com/coding/basic/stack/TwoStackInOneArray.java
new file mode 100644
index 0000000000..a532fd6e6c
--- /dev/null
+++ b/liuxin/data-structure/answer/src/main/java/com/coding/basic/stack/TwoStackInOneArray.java
@@ -0,0 +1,117 @@
+package com.coding.basic.stack;
+
+import java.util.Arrays;
+
+/**
+ * 用一个数组实现两个栈
+ * 将数组的起始位置看作是第一个栈的栈底,将数组的尾部看作第二个栈的栈底,压栈时,栈顶指针分别向中间移动,直到两栈顶指针相遇,则扩容。
+ * @author liuxin
+ *
+ */
+public class TwoStackInOneArray {
+ private Object[] data = new Object[10];
+ private int size;
+ private int top1, top2;
+
+ public TwoStackInOneArray(int n){
+ data = new Object[n];
+ size = n;
+ top1 = -1;
+ top2 = data.length;
+ }
+ /**
+ * 向第一个栈中压入元素
+ * @param o
+ */
+ public void push1(Object o){
+ ensureCapacity();
+ data[++top1] = o;
+ }
+ /*
+ * 向第二个栈压入元素
+ */
+ public void push2(Object o){
+ ensureCapacity();
+ data[--top2] = o;
+ }
+ public void ensureCapacity(){
+ if(top2-top1>1){
+ return;
+ } else{
+
+ Object[] newArray = new Object[data.length*2];
+ System.arraycopy(data, 0, newArray, 0, top1+1);
+
+ int stack2Size = data.length-top2;
+ int newTop2 = newArray.length-stack2Size;
+ System.arraycopy(data, top2, newArray, newTop2, stack2Size);
+
+ top2 = newTop2;
+ data = newArray;
+ }
+ }
+ /**
+ * 从第一个栈中弹出元素
+ * @return
+ */
+ public Object pop1(){
+ if(top1 == -1){
+ throw new RuntimeException("Stack1 is empty");
+ }
+ Object o = data[top1];
+ data[top1] = null;
+ top1--;
+ return o;
+
+ }
+ /**
+ * 从第二个栈弹出元素
+ * @return
+ */
+ public Object pop2(){
+ if(top2 == data.length){
+ throw new RuntimeException("Stack2 is empty");
+ }
+ Object o = data[top2];
+ data[top2] = null;
+ top2++;
+ return o;
+ }
+ /**
+ * 获取第一个栈的栈顶元素
+ * @return
+ */
+
+ public Object peek1(){
+ if(top1 == -1){
+ throw new RuntimeException("Stack1 is empty");
+ }
+ return data[top1];
+ }
+
+
+ /**
+ * 获取第二个栈的栈顶元素
+ * @return
+ */
+
+ public Object peek2(){
+ if(top2 == data.length){
+ throw new RuntimeException("Stack2 is empty");
+ }
+ return data[top2];
+ }
+
+ public Object[] stack1ToArray(){
+ return Arrays.copyOf(data, top1+1);
+ }
+ public Object[] stack2ToArray(){
+ int size = data.length-top2;
+ Object [] stack2Data = new Object[size];
+ int j=0;
+ for(int i=data.length-1; i>=top2 ;i--){
+ stack2Data[j++] = data[i];
+ }
+ return stack2Data;
+ }
+}
diff --git a/liuxin/data-structure/answer/src/main/java/com/coding/basic/stack/TwoStackInOneArrayTest.java b/liuxin/data-structure/answer/src/main/java/com/coding/basic/stack/TwoStackInOneArrayTest.java
new file mode 100644
index 0000000000..b743d422c6
--- /dev/null
+++ b/liuxin/data-structure/answer/src/main/java/com/coding/basic/stack/TwoStackInOneArrayTest.java
@@ -0,0 +1,65 @@
+package com.coding.basic.stack;
+
+import java.util.Arrays;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+
+
+public class TwoStackInOneArrayTest {
+
+ @Before
+ public void setUp() throws Exception {
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+ @Test
+ public void test1() {
+ TwoStackInOneArray stack = new TwoStackInOneArray(10);
+ stack.push1(1);
+ stack.push1(2);
+ stack.push1(3);
+ stack.push1(4);
+ stack.push1(5);
+
+ stack.push2(1);
+ stack.push2(2);
+ stack.push2(3);
+ stack.push2(4);
+ stack.push2(5);
+
+ for(int i=1;i<=5;i++){
+ Assert.assertEquals(stack.peek1(), stack.peek2());
+ Assert.assertEquals(stack.pop1(), stack.pop2());
+ }
+
+
+ }
+ @Test
+ public void test2() {
+ TwoStackInOneArray stack = new TwoStackInOneArray(5);
+ stack.push1(1);
+ stack.push1(2);
+ stack.push1(3);
+ stack.push1(4);
+ stack.push1(5);
+ stack.push1(6);
+ stack.push1(7);
+
+ stack.push2(1);
+ stack.push2(2);
+ stack.push2(3);
+ stack.push2(4);
+
+
+ Assert.assertEquals("[1, 2, 3, 4, 5, 6, 7]",Arrays.toString(stack.stack1ToArray()));
+ Assert.assertEquals("[1, 2, 3, 4]",Arrays.toString(stack.stack2ToArray()));
+ }
+
+}
diff --git a/liuxin/data-structure/answer/src/main/java/com/coding/basic/stack/expr/InfixExpr.java b/liuxin/data-structure/answer/src/main/java/com/coding/basic/stack/expr/InfixExpr.java
new file mode 100644
index 0000000000..cebef21fa3
--- /dev/null
+++ b/liuxin/data-structure/answer/src/main/java/com/coding/basic/stack/expr/InfixExpr.java
@@ -0,0 +1,72 @@
+package com.coding.basic.stack.expr;
+
+import java.util.List;
+import java.util.Stack;
+
+
+public class InfixExpr {
+ String expr = null;
+
+ public InfixExpr(String expr) {
+ this.expr = expr;
+ }
+
+ public float evaluate() {
+
+
+ TokenParser parser = new TokenParser();
+ List tokens = parser.parse(this.expr);
+
+
+ Stack opStack = new Stack<>();
+ Stack numStack = new Stack<>();
+
+ for(Token token : tokens){
+
+ if (token.isOperator()){
+
+ while(!opStack.isEmpty()
+ && !token.hasHigherPriority(opStack.peek())){
+ Token prevOperator = opStack.pop();
+ Float f2 = numStack.pop();
+ Float f1 = numStack.pop();
+ Float result = calculate(prevOperator.toString(), f1,f2);
+ numStack.push(result);
+
+ }
+ opStack.push(token);
+ }
+ if(token.isNumber()){
+ numStack.push(new Float(token.getIntValue()));
+ }
+ }
+
+ while(!opStack.isEmpty()){
+ Token token = opStack.pop();
+ Float f2 = numStack.pop();
+ Float f1 = numStack.pop();
+ numStack.push(calculate(token.toString(), f1,f2));
+ }
+
+
+ return numStack.pop().floatValue();
+ }
+ private Float calculate(String op, Float f1, Float f2){
+ if(op.equals("+")){
+ return f1+f2;
+ }
+ if(op.equals("-")){
+ return f1-f2;
+ }
+ if(op.equals("*")){
+ return f1*f2;
+ }
+ if(op.equals("/")){
+ return f1/f2;
+ }
+ throw new RuntimeException(op + " is not supported");
+ }
+
+
+
+}
diff --git a/liuxin/data-structure/answer/src/main/java/com/coding/basic/stack/expr/InfixExprTest.java b/liuxin/data-structure/answer/src/main/java/com/coding/basic/stack/expr/InfixExprTest.java
new file mode 100644
index 0000000000..20e34e8852
--- /dev/null
+++ b/liuxin/data-structure/answer/src/main/java/com/coding/basic/stack/expr/InfixExprTest.java
@@ -0,0 +1,52 @@
+package com.coding.basic.stack.expr;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+
+public class InfixExprTest {
+
+ @Before
+ public void setUp() throws Exception {
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+ @Test
+ public void testEvaluate() {
+ //InfixExpr expr = new InfixExpr("300*20+12*5-20/4");
+ {
+ InfixExpr expr = new InfixExpr("2+3*4+5");
+ Assert.assertEquals(19.0, expr.evaluate(), 0.001f);
+ }
+ {
+ InfixExpr expr = new InfixExpr("3*20+12*5-40/2");
+ Assert.assertEquals(100.0, expr.evaluate(), 0.001f);
+ }
+
+ {
+ InfixExpr expr = new InfixExpr("3*20/2");
+ Assert.assertEquals(30, expr.evaluate(), 0.001f);
+ }
+
+ {
+ InfixExpr expr = new InfixExpr("20/2*3");
+ Assert.assertEquals(30, expr.evaluate(), 0.001f);
+ }
+
+ {
+ InfixExpr expr = new InfixExpr("10-30+50");
+ Assert.assertEquals(30, expr.evaluate(), 0.001f);
+ }
+ {
+ InfixExpr expr = new InfixExpr("10-2*3+50");
+ Assert.assertEquals(54, expr.evaluate(), 0.001f);
+ }
+
+ }
+
+}
diff --git a/liuxin/data-structure/answer/src/main/java/com/coding/basic/stack/expr/InfixToPostfix.java b/liuxin/data-structure/answer/src/main/java/com/coding/basic/stack/expr/InfixToPostfix.java
new file mode 100644
index 0000000000..9e501eda20
--- /dev/null
+++ b/liuxin/data-structure/answer/src/main/java/com/coding/basic/stack/expr/InfixToPostfix.java
@@ -0,0 +1,43 @@
+package com.coding.basic.stack.expr;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Stack;
+
+public class InfixToPostfix {
+
+ public static List convert(String expr) {
+ List inFixTokens = new TokenParser().parse(expr);
+
+ List postFixTokens = new ArrayList<>();
+
+ Stack opStack = new Stack();
+ for(Token token : inFixTokens){
+
+ if(token.isOperator()){
+
+ while(!opStack.isEmpty()
+ && !token.hasHigherPriority(opStack.peek())){
+ postFixTokens.add(opStack.pop());
+
+ }
+ opStack.push(token);
+
+ }
+ if(token.isNumber()){
+
+ postFixTokens.add(token);
+
+ }
+ }
+
+ while(!opStack.isEmpty()){
+ postFixTokens.add(opStack.pop());
+ }
+
+ return postFixTokens;
+ }
+
+
+
+}
diff --git a/liuxin/data-structure/answer/src/main/java/com/coding/basic/stack/expr/InfixToPostfixTest.java b/liuxin/data-structure/answer/src/main/java/com/coding/basic/stack/expr/InfixToPostfixTest.java
new file mode 100644
index 0000000000..f879f55f14
--- /dev/null
+++ b/liuxin/data-structure/answer/src/main/java/com/coding/basic/stack/expr/InfixToPostfixTest.java
@@ -0,0 +1,41 @@
+package com.coding.basic.stack.expr;
+
+import java.util.List;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+
+
+public class InfixToPostfixTest {
+
+ @Before
+ public void setUp() throws Exception {
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+ @Test
+ public void testConvert() {
+ {
+ List tokens = InfixToPostfix.convert("2+3");
+ Assert.assertEquals("[2, 3, +]", tokens.toString());
+ }
+ {
+
+ List tokens = InfixToPostfix.convert("2+3*4");
+ Assert.assertEquals("[2, 3, 4, *, +]", tokens.toString());
+ }
+
+ {
+
+ List tokens = InfixToPostfix.convert("2-3*4+5");
+ Assert.assertEquals("[2, 3, 4, *, -, 5, +]", tokens.toString());
+ }
+ }
+
+}
diff --git a/liuxin/data-structure/answer/src/main/java/com/coding/basic/stack/expr/PostfixExpr.java b/liuxin/data-structure/answer/src/main/java/com/coding/basic/stack/expr/PostfixExpr.java
new file mode 100644
index 0000000000..c54eb69e2a
--- /dev/null
+++ b/liuxin/data-structure/answer/src/main/java/com/coding/basic/stack/expr/PostfixExpr.java
@@ -0,0 +1,46 @@
+package com.coding.basic.stack.expr;
+
+import java.util.List;
+import java.util.Stack;
+
+public class PostfixExpr {
+String expr = null;
+
+ public PostfixExpr(String expr) {
+ this.expr = expr;
+ }
+
+ public float evaluate() {
+ TokenParser parser = new TokenParser();
+ List tokens = parser.parse(this.expr);
+
+
+ Stack numStack = new Stack<>();
+ for(Token token : tokens){
+ if(token.isNumber()){
+ numStack.push(new Float(token.getIntValue()));
+ } else{
+ Float f2 = numStack.pop();
+ Float f1 = numStack.pop();
+ numStack.push(calculate(token.toString(),f1,f2));
+ }
+ }
+ return numStack.pop().floatValue();
+ }
+
+ private Float calculate(String op, Float f1, Float f2){
+ if(op.equals("+")){
+ return f1+f2;
+ }
+ if(op.equals("-")){
+ return f1-f2;
+ }
+ if(op.equals("*")){
+ return f1*f2;
+ }
+ if(op.equals("/")){
+ return f1/f2;
+ }
+ throw new RuntimeException(op + " is not supported");
+ }
+}
diff --git a/liuxin/data-structure/answer/src/main/java/com/coding/basic/stack/expr/PostfixExprTest.java b/liuxin/data-structure/answer/src/main/java/com/coding/basic/stack/expr/PostfixExprTest.java
new file mode 100644
index 0000000000..c0435a2db5
--- /dev/null
+++ b/liuxin/data-structure/answer/src/main/java/com/coding/basic/stack/expr/PostfixExprTest.java
@@ -0,0 +1,41 @@
+package com.coding.basic.stack.expr;
+
+
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+
+
+public class PostfixExprTest {
+
+ @Before
+ public void setUp() throws Exception {
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+ @Test
+ public void testEvaluate() {
+ {
+ PostfixExpr expr = new PostfixExpr("6 5 2 3 + 8 * + 3 + *");
+ Assert.assertEquals(288, expr.evaluate(),0.0f);
+ }
+ {
+ //9+(3-1)*3+10/2
+ PostfixExpr expr = new PostfixExpr("9 3 1-3*+ 10 2/+");
+ Assert.assertEquals(20, expr.evaluate(),0.0f);
+ }
+
+ {
+ //10-2*3+50
+ PostfixExpr expr = new PostfixExpr("10 2 3 * - 50 +");
+ Assert.assertEquals(54, expr.evaluate(),0.0f);
+ }
+ }
+
+}
diff --git a/liuxin/data-structure/answer/src/main/java/com/coding/basic/stack/expr/PrefixExpr.java b/liuxin/data-structure/answer/src/main/java/com/coding/basic/stack/expr/PrefixExpr.java
new file mode 100644
index 0000000000..f811fd6d9a
--- /dev/null
+++ b/liuxin/data-structure/answer/src/main/java/com/coding/basic/stack/expr/PrefixExpr.java
@@ -0,0 +1,52 @@
+package com.coding.basic.stack.expr;
+
+import java.util.List;
+import java.util.Stack;
+
+public class PrefixExpr {
+ String expr = null;
+
+ public PrefixExpr(String expr) {
+ this.expr = expr;
+ }
+
+ public float evaluate() {
+ TokenParser parser = new TokenParser();
+ List tokens = parser.parse(this.expr);
+
+ Stack exprStack = new Stack<>();
+ Stack numStack = new Stack<>();
+ for(Token token : tokens){
+ exprStack.push(token);
+ }
+
+ while(!exprStack.isEmpty()){
+ Token t = exprStack.pop();
+ if(t.isNumber()){
+ numStack.push(new Float(t.getIntValue()));
+ }else{
+ Float f1 = numStack.pop();
+ Float f2 = numStack.pop();
+ numStack.push(calculate(t.toString(),f1,f2));
+
+ }
+ }
+ return numStack.pop().floatValue();
+ }
+
+ private Float calculate(String op, Float f1, Float f2){
+ if(op.equals("+")){
+ return f1+f2;
+ }
+ if(op.equals("-")){
+ return f1-f2;
+ }
+ if(op.equals("*")){
+ return f1*f2;
+ }
+ if(op.equals("/")){
+ return f1/f2;
+ }
+ throw new RuntimeException(op + " is not supported");
+ }
+}
diff --git a/liuxin/data-structure/answer/src/main/java/com/coding/basic/stack/expr/PrefixExprTest.java b/liuxin/data-structure/answer/src/main/java/com/coding/basic/stack/expr/PrefixExprTest.java
new file mode 100644
index 0000000000..5cec210e75
--- /dev/null
+++ b/liuxin/data-structure/answer/src/main/java/com/coding/basic/stack/expr/PrefixExprTest.java
@@ -0,0 +1,45 @@
+package com.coding.basic.stack.expr;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+
+public class PrefixExprTest {
+
+ @Before
+ public void setUp() throws Exception {
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+ @Test
+ public void testEvaluate() {
+ {
+ // 2*3+4*5
+ PrefixExpr expr = new PrefixExpr("+ * 2 3* 4 5");
+ Assert.assertEquals(26, expr.evaluate(),0.001f);
+ }
+ {
+ // 4*2 + 6+9*2/3 -8
+ PrefixExpr expr = new PrefixExpr("-++6/*2 9 3 * 4 2 8");
+ Assert.assertEquals(12, expr.evaluate(),0.001f);
+ }
+ {
+ //(3+4)*5-6
+ PrefixExpr expr = new PrefixExpr("- * + 3 4 5 6");
+ Assert.assertEquals(29, expr.evaluate(),0.001f);
+ }
+ {
+ //1+((2+3)*4)-5
+ PrefixExpr expr = new PrefixExpr("- + 1 * + 2 3 4 5");
+ Assert.assertEquals(16, expr.evaluate(),0.001f);
+ }
+
+
+ }
+
+}
diff --git a/liuxin/data-structure/answer/src/main/java/com/coding/basic/stack/expr/Token.java b/liuxin/data-structure/answer/src/main/java/com/coding/basic/stack/expr/Token.java
new file mode 100644
index 0000000000..8579743fe9
--- /dev/null
+++ b/liuxin/data-structure/answer/src/main/java/com/coding/basic/stack/expr/Token.java
@@ -0,0 +1,50 @@
+package com.coding.basic.stack.expr;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+class Token {
+ public static final List OPERATORS = Arrays.asList("+", "-", "*", "/");
+ private static final Map priorities = new HashMap<>();
+ static {
+ priorities.put("+", 1);
+ priorities.put("-", 1);
+ priorities.put("*", 2);
+ priorities.put("/", 2);
+ }
+ static final int OPERATOR = 1;
+ static final int NUMBER = 2;
+ String value;
+ int type;
+ public Token(int type, String value){
+ this.type = type;
+ this.value = value;
+ }
+
+ public boolean isNumber() {
+ return type == NUMBER;
+ }
+
+ public boolean isOperator() {
+ return type == OPERATOR;
+ }
+
+ public int getIntValue() {
+ return Integer.valueOf(value).intValue();
+ }
+ public String toString(){
+ return value;
+ }
+
+ public boolean hasHigherPriority(Token t){
+ if(!this.isOperator() && !t.isOperator()){
+ throw new RuntimeException("numbers can't compare priority");
+ }
+ return priorities.get(this.value) - priorities.get(t.value) > 0;
+ }
+
+
+
+}
\ No newline at end of file
diff --git a/liuxin/data-structure/answer/src/main/java/com/coding/basic/stack/expr/TokenParser.java b/liuxin/data-structure/answer/src/main/java/com/coding/basic/stack/expr/TokenParser.java
new file mode 100644
index 0000000000..d3b0f167e1
--- /dev/null
+++ b/liuxin/data-structure/answer/src/main/java/com/coding/basic/stack/expr/TokenParser.java
@@ -0,0 +1,57 @@
+package com.coding.basic.stack.expr;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class TokenParser {
+
+
+ public List parse(String expr) {
+ List tokens = new ArrayList<>();
+
+ int i = 0;
+
+ while (i < expr.length()) {
+
+ char c = expr.charAt(i);
+
+ if (isOperator(c)) {
+
+ Token t = new Token(Token.OPERATOR, String.valueOf(c));
+ tokens.add(t);
+ i++;
+
+ } else if (Character.isDigit(c)) {
+
+ int nextOperatorIndex = indexOfNextOperator(i, expr);
+ String value = expr.substring(i, nextOperatorIndex);
+ Token t = new Token(Token.NUMBER, value);
+ tokens.add(t);
+ i = nextOperatorIndex;
+
+ } else{
+ System.out.println("char :["+c+"] is not number or operator,ignore");
+ i++;
+ }
+
+ }
+ return tokens;
+ }
+
+ private int indexOfNextOperator(int i, String expr) {
+
+ while (Character.isDigit(expr.charAt(i))) {
+ i++;
+ if (i == expr.length()) {
+ break;
+ }
+ }
+ return i;
+
+ }
+
+ private boolean isOperator(char c) {
+ String sc = String.valueOf(c);
+ return Token.OPERATORS.contains(sc);
+ }
+}
diff --git a/liuxin/data-structure/answer/src/main/java/com/coding/basic/stack/expr/TokenParserTest.java b/liuxin/data-structure/answer/src/main/java/com/coding/basic/stack/expr/TokenParserTest.java
new file mode 100644
index 0000000000..399d3e857e
--- /dev/null
+++ b/liuxin/data-structure/answer/src/main/java/com/coding/basic/stack/expr/TokenParserTest.java
@@ -0,0 +1,41 @@
+package com.coding.basic.stack.expr;
+
+import static org.junit.Assert.*;
+
+import java.util.List;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class TokenParserTest {
+
+ @Before
+ public void setUp() throws Exception {
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+ @Test
+ public void test() {
+
+ TokenParser parser = new TokenParser();
+ List tokens = parser.parse("300*20+12*5-20/4");
+
+ Assert.assertEquals(300, tokens.get(0).getIntValue());
+ Assert.assertEquals("*", tokens.get(1).toString());
+ Assert.assertEquals(20, tokens.get(2).getIntValue());
+ Assert.assertEquals("+", tokens.get(3).toString());
+ Assert.assertEquals(12, tokens.get(4).getIntValue());
+ Assert.assertEquals("*", tokens.get(5).toString());
+ Assert.assertEquals(5, tokens.get(6).getIntValue());
+ Assert.assertEquals("-", tokens.get(7).toString());
+ Assert.assertEquals(20, tokens.get(8).getIntValue());
+ Assert.assertEquals("/", tokens.get(9).toString());
+ Assert.assertEquals(4, tokens.get(10).getIntValue());
+ }
+
+}
diff --git a/liuxin/data-structure/answer/src/main/java/com/coding/basic/tree/BinarySearchTree.java b/liuxin/data-structure/answer/src/main/java/com/coding/basic/tree/BinarySearchTree.java
new file mode 100644
index 0000000000..284e5b0011
--- /dev/null
+++ b/liuxin/data-structure/answer/src/main/java/com/coding/basic/tree/BinarySearchTree.java
@@ -0,0 +1,189 @@
+package com.coding.basic.tree;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.coding.basic.queue.Queue;
+
+
+public class BinarySearchTree {
+
+ BinaryTreeNode root;
+ public BinarySearchTree(BinaryTreeNode root){
+ this.root = root;
+ }
+ public BinaryTreeNode getRoot(){
+ return root;
+ }
+ public T findMin(){
+ if(root == null){
+ return null;
+ }
+ return findMin(root).data;
+ }
+ public T findMax(){
+ if(root == null){
+ return null;
+ }
+ return findMax(root).data;
+ }
+ public int height() {
+ return height(root);
+ }
+ public int size() {
+ return size(root);
+ }
+ public void remove(T e){
+ remove(e, root);
+ }
+
+ private BinaryTreeNode remove(T x, BinaryTreeNode t){
+ if(t == null){
+ return t;
+ }
+ int compareResult = x.compareTo(t.data);
+
+ if(compareResult< 0 ){
+ t.left = remove(x,t.left);
+
+ } else if(compareResult > 0){
+ t.right = remove(x, t.right);
+
+ } else {
+ if(t.left != null && t.right != null){
+
+ t.data = findMin(t.right).data;
+ t.right = remove(t.data,t.right);
+
+ } else{
+ t = (t.left != null) ? t.left : t.right;
+ }
+ }
+ return t;
+ }
+
+ private BinaryTreeNode findMin(BinaryTreeNode p){
+ if (p==null){
+ return null;
+ } else if (p.left == null){
+ return p;
+ } else{
+ return findMin(p.left);
+ }
+ }
+ private BinaryTreeNode findMax(BinaryTreeNode p){
+ if (p==null){
+ return null;
+ }else if (p.right==null){
+ return p;
+ } else{
+ return findMax(p.right);
+ }
+ }
+ private int height(BinaryTreeNode t){
+ if (t==null){
+ return 0;
+ }else {
+ int leftChildHeight=height(t.left);
+ int rightChildHeight=height(t.right);
+ if(leftChildHeight > rightChildHeight){
+ return leftChildHeight+1;
+ } else{
+ return rightChildHeight+1;
+ }
+ }
+ }
+ private int size(BinaryTreeNode t){
+ if (t == null){
+ return 0;
+ }
+ return size(t.left) + 1 + size(t.right);
+
+ }
+
+ public List levelVisit(){
+ List result = new ArrayList();
+ if(root == null){
+ return result;
+ }
+ Queue> queue = new Queue>();
+ BinaryTreeNode node = root;
+ queue.enQueue(node);
+ while (!queue.isEmpty()) {
+ node = queue.deQueue();
+ result.add(node.data);
+ if (node.left != null){
+ queue.enQueue(node.left);
+ }
+ if (node.right != null){
+ queue.enQueue(node.right);
+ }
+ }
+ return result;
+ }
+ public boolean isValid(){
+ return isValid(root);
+ }
+ public T getLowestCommonAncestor(T n1, T n2){
+ if (root == null){
+ return null;
+ }
+ return lowestCommonAncestor(root,n1,n2);
+
+ }
+ public List getNodesBetween(T n1, T n2){
+ List elements = new ArrayList<>();
+ getNodesBetween(elements,root,n1,n2);
+ return elements;
+ }
+
+ public void getNodesBetween(List elements ,BinaryTreeNode node, T n1, T n2){
+
+ if (node == null) {
+ return;
+ }
+
+ if (n1.compareTo(node.data) < 0) {
+ getNodesBetween(elements,node.left, n1, n2);
+ }
+
+ if ((n1.compareTo(node.data) <= 0 )
+ && (n2.compareTo(node.data) >= 0 )) {
+ elements.add(node.data);
+ }
+ if (n2.compareTo(node.data)>0) {
+ getNodesBetween(elements,node.right, n1, n2);
+ }
+ }
+ private T lowestCommonAncestor(BinaryTreeNode node,T n1, T n2){
+ if(node == null){
+ return null;
+ }
+ // 如果n1和n2都比 node的值小, LCA在左孩子
+ if (node.data.compareTo(n1) > 0 && node.data.compareTo(n2) >0){
+ return lowestCommonAncestor(node.left, n1, n2);
+ }
+
+ // 如果n1和n2都比 node的值小, LCA在右孩子
+ if (node.data.compareTo(n1) < 0 && node.data.compareTo(n2) <0)
+ return lowestCommonAncestor(node.right, n1, n2);
+
+ return node.data;
+ }
+ private boolean isValid(BinaryTreeNode t){
+ if(t == null){
+ return true;
+ }
+ if(t.left != null && findMax(t.left).data.compareTo(t.data) >0){
+ return false;
+ }
+ if(t.right !=null && findMin(t.right).data.compareTo(t.data) <0){
+ return false;
+ }
+ if(!isValid(t.left) || !isValid(t.right)){
+ return false;
+ }
+ return true;
+ }
+}
+
diff --git a/liuxin/data-structure/answer/src/main/java/com/coding/basic/tree/BinarySearchTreeTest.java b/liuxin/data-structure/answer/src/main/java/com/coding/basic/tree/BinarySearchTreeTest.java
new file mode 100644
index 0000000000..590e60306c
--- /dev/null
+++ b/liuxin/data-structure/answer/src/main/java/com/coding/basic/tree/BinarySearchTreeTest.java
@@ -0,0 +1,108 @@
+package com.coding.basic.tree;
+
+import java.util.List;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+
+
+public class BinarySearchTreeTest {
+
+ BinarySearchTree tree = null;
+
+ @Before
+ public void setUp() throws Exception {
+ BinaryTreeNode root = new BinaryTreeNode(6);
+ root.left = new BinaryTreeNode(2);
+ root.right = new BinaryTreeNode(8);
+ root.left.left = new BinaryTreeNode(1);
+ root.left.right = new BinaryTreeNode(4);
+ root.left.right.left = new BinaryTreeNode(3);
+ root.left.right.right = new BinaryTreeNode(5);
+ tree = new BinarySearchTree(root);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ tree = null;
+ }
+
+ @Test
+ public void testFindMin() {
+ Assert.assertEquals(1, tree.findMin().intValue());
+
+ }
+
+ @Test
+ public void testFindMax() {
+ Assert.assertEquals(8, tree.findMax().intValue());
+ }
+
+ @Test
+ public void testHeight() {
+ Assert.assertEquals(4, tree.height());
+ }
+
+ @Test
+ public void testSize() {
+ Assert.assertEquals(7, tree.size());
+ }
+
+ @Test
+ public void testRemoveLeaf() {
+ tree.remove(3);
+ BinaryTreeNode root= tree.getRoot();
+ Assert.assertEquals(4, root.left.right.data.intValue());
+
+ }
+ @Test
+ public void testRemoveMiddleNode1() {
+ tree.remove(4);
+ BinaryTreeNode root= tree.getRoot();
+ Assert.assertEquals(5, root.left.right.data.intValue());
+ Assert.assertEquals(3, root.left.right.left.data.intValue());
+ }
+ @Test
+ public void testRemoveMiddleNode2() {
+ tree.remove(2);
+ BinaryTreeNode root= tree.getRoot();
+ Assert.assertEquals(3, root.left.data.intValue());
+ Assert.assertEquals(4, root.left.right.data.intValue());
+ }
+
+ @Test
+ public void testLevelVisit() {
+ List values = tree.levelVisit();
+ Assert.assertEquals("[6, 2, 8, 1, 4, 3, 5]", values.toString());
+
+ }
+ @Test
+ public void testLCA(){
+ Assert.assertEquals(2,tree.getLowestCommonAncestor(1, 5).intValue());
+ Assert.assertEquals(2,tree.getLowestCommonAncestor(1, 4).intValue());
+ Assert.assertEquals(6,tree.getLowestCommonAncestor(3, 8).intValue());
+ }
+ @Test
+ public void testIsValid() {
+
+ Assert.assertTrue(tree.isValid());
+
+ BinaryTreeNode root = new BinaryTreeNode(6);
+ root.left = new BinaryTreeNode(2);
+ root.right = new BinaryTreeNode(8);
+ root.left.left = new BinaryTreeNode(4);
+ root.left.right = new BinaryTreeNode(1);
+ root.left.right.left = new BinaryTreeNode(3);
+ tree = new BinarySearchTree(root);
+
+ Assert.assertFalse(tree.isValid());
+ }
+ @Test
+ public void testGetNodesBetween(){
+ List numbers = this.tree.getNodesBetween(3, 8);
+ Assert.assertEquals("[3, 4, 5, 6, 8]",numbers.toString());
+ }
+}
diff --git a/liuxin/data-structure/answer/src/main/java/com/coding/basic/tree/BinaryTreeNode.java b/liuxin/data-structure/answer/src/main/java/com/coding/basic/tree/BinaryTreeNode.java
new file mode 100644
index 0000000000..3f6f4d2b44
--- /dev/null
+++ b/liuxin/data-structure/answer/src/main/java/com/coding/basic/tree/BinaryTreeNode.java
@@ -0,0 +1,36 @@
+package com.coding.basic.tree;
+
+public class BinaryTreeNode {
+
+ public T data;
+ public BinaryTreeNode left;
+ public BinaryTreeNode right;
+
+ public BinaryTreeNode(T data){
+ this.data=data;
+ }
+ public T getData() {
+ return data;
+ }
+ public void setData(T data) {
+ this.data = data;
+ }
+ public BinaryTreeNode getLeft() {
+ return left;
+ }
+ public void setLeft(BinaryTreeNode left) {
+ this.left = left;
+ }
+ public BinaryTreeNode getRight() {
+ return right;
+ }
+ public void setRight(BinaryTreeNode right) {
+ this.right = right;
+ }
+
+ public BinaryTreeNode insert(Object o){
+ return null;
+ }
+
+
+}
diff --git a/liuxin/data-structure/answer/src/main/java/com/coding/basic/tree/BinaryTreeUtil.java b/liuxin/data-structure/answer/src/main/java/com/coding/basic/tree/BinaryTreeUtil.java
new file mode 100644
index 0000000000..f2a6515fa6
--- /dev/null
+++ b/liuxin/data-structure/answer/src/main/java/com/coding/basic/tree/BinaryTreeUtil.java
@@ -0,0 +1,116 @@
+package com.coding.basic.tree;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Stack;
+
+public class BinaryTreeUtil {
+ /**
+ * 用递归的方式实现对二叉树的前序遍历, 需要通过BinaryTreeUtilTest测试
+ *
+ * @param root
+ * @return
+ */
+ public static List preOrderVisit(BinaryTreeNode root) {
+ List result = new ArrayList();
+ preOrderVisit(root, result);
+ return result;
+ }
+
+ /**
+ * 用递归的方式实现对二叉树的中遍历
+ *
+ * @param root
+ * @return
+ */
+ public static List inOrderVisit(BinaryTreeNode root) {
+ List result = new ArrayList();
+ inOrderVisit(root, result);
+ return result;
+ }
+
+ /**
+ * 用递归的方式实现对二叉树的后遍历
+ *
+ * @param root
+ * @return
+ */
+ public static List postOrderVisit(BinaryTreeNode root) {
+ List result = new ArrayList();
+ postOrderVisit(root, result);
+ return result;
+ }
+
+ public static List preOrderWithoutRecursion(BinaryTreeNode root) {
+
+ List result = new ArrayList();
+ Stack> stack = new Stack>();
+
+ BinaryTreeNode node = root;
+
+ if(node != null){
+ stack.push(node);
+ }
+
+ while(!stack.isEmpty()){
+ node = stack.pop();
+ result.add(node.data);
+
+ if(node.right != null){
+ stack.push(node.right);
+ }
+
+ if(node.left != null){
+ stack.push(node.right);
+ }
+ }
+ return result;
+ }
+
+ public static List inOrderWithoutRecursion(BinaryTreeNode root) {
+
+ List result = new ArrayList();
+ BinaryTreeNode node = root;
+ Stack> stack = new Stack>();
+
+ while (node != null || !stack.isEmpty()) {
+
+ while (node != null) {
+ stack.push(node);
+ node = node.left;
+ }
+ BinaryTreeNode currentNode = stack.pop();
+ result.add(currentNode.data);
+ node = currentNode.right;
+ }
+ return result;
+ }
+
+ private static void preOrderVisit(BinaryTreeNode node, List result) {
+ if (node == null) {
+ return;
+ }
+ result.add(node.getData());
+ preOrderVisit(node.getLeft(), result);
+ preOrderVisit(node.getRight(), result);
+ }
+
+ private static void inOrderVisit(BinaryTreeNode node, List result) {
+ if (node == null) {
+ return;
+ }
+ inOrderVisit(node.getLeft(), result);
+ result.add(node.getData());
+ inOrderVisit(node.getRight(), result);
+ }
+
+ private static void postOrderVisit(BinaryTreeNode node, List result) {
+ if (node == null) {
+ return;
+ }
+ postOrderVisit(node.getLeft(), result);
+ postOrderVisit(node.getRight(), result);
+ result.add(node.getData());
+ }
+
+}
diff --git a/liuxin/data-structure/answer/src/main/java/com/coding/basic/tree/BinaryTreeUtilTest.java b/liuxin/data-structure/answer/src/main/java/com/coding/basic/tree/BinaryTreeUtilTest.java
new file mode 100644
index 0000000000..41857e137d
--- /dev/null
+++ b/liuxin/data-structure/answer/src/main/java/com/coding/basic/tree/BinaryTreeUtilTest.java
@@ -0,0 +1,75 @@
+package com.coding.basic.tree;
+
+import java.util.List;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+
+
+public class BinaryTreeUtilTest {
+
+ BinaryTreeNode root = null;
+ @Before
+ public void setUp() throws Exception {
+ root = new BinaryTreeNode(1);
+ root.setLeft(new BinaryTreeNode(2));
+ root.setRight(new BinaryTreeNode(5));
+ root.getLeft().setLeft(new BinaryTreeNode(3));
+ root.getLeft().setRight(new BinaryTreeNode(4));
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+ @Test
+ public void testPreOrderVisit() {
+
+ List result = BinaryTreeUtil.preOrderVisit(root);
+ Assert.assertEquals("[1, 2, 3, 4, 5]", result.toString());
+
+
+ }
+ @Test
+ public void testInOrderVisit() {
+
+
+ List result = BinaryTreeUtil.inOrderVisit(root);
+ Assert.assertEquals("[3, 2, 4, 1, 5]", result.toString());
+
+ }
+
+ @Test
+ public void testPostOrderVisit() {
+
+
+ List result = BinaryTreeUtil.postOrderVisit(root);
+ Assert.assertEquals("[3, 4, 2, 5, 1]", result.toString());
+
+ }
+
+
+ @Test
+ public void testInOrderVisitWithoutRecursion() {
+ BinaryTreeNode node = root.getLeft().getRight();
+ node.setLeft(new BinaryTreeNode(6));
+ node.setRight(new BinaryTreeNode(7));
+
+ List result = BinaryTreeUtil.inOrderWithoutRecursion(root);
+ Assert.assertEquals("[3, 2, 6, 4, 7, 1, 5]", result.toString());
+
+ }
+ @Test
+ public void testPreOrderVisitWithoutRecursion() {
+ BinaryTreeNode node = root.getLeft().getRight();
+ node.setLeft(new BinaryTreeNode(6));
+ node.setRight(new BinaryTreeNode(7));
+
+ List result = BinaryTreeUtil.preOrderWithoutRecursion(root);
+ Assert.assertEquals("[1, 2, 3, 4, 6, 7, 5]", result.toString());
+
+ }
+}
diff --git a/liuxin/data-structure/answer/src/main/java/com/coding/basic/tree/FileList.java b/liuxin/data-structure/answer/src/main/java/com/coding/basic/tree/FileList.java
new file mode 100644
index 0000000000..85fb8ab2a4
--- /dev/null
+++ b/liuxin/data-structure/answer/src/main/java/com/coding/basic/tree/FileList.java
@@ -0,0 +1,34 @@
+package com.coding.basic.tree;
+
+import java.io.File;
+
+public class FileList {
+ public void list(File f) {
+ list(f, 0);
+ }
+
+ public void list(File f, int depth) {
+ printName(f, depth);
+ if (f.isDirectory()) {
+ File[] files = f.listFiles();
+ for (File i : files)
+ list(i, depth + 1);
+ }
+ }
+
+ void printName(File f, int depth) {
+ String name = f.getName();
+ for (int i = 0; i < depth; i++)
+ System.out.print("+");
+ if (f.isDirectory())
+ System.out.println("Dir: " + name);
+ else
+ System.out.println(f.getName() + " " + f.length());
+ }
+
+ public static void main(String args[]) {
+ FileList L = new FileList();
+ File f = new File("C:\\coderising\\tmp");
+ L.list(f);
+ }
+}
diff --git a/liuxin/data-structure/assignment/pom.xml b/liuxin/data-structure/assignment/pom.xml
new file mode 100644
index 0000000000..5024466d17
--- /dev/null
+++ b/liuxin/data-structure/assignment/pom.xml
@@ -0,0 +1,32 @@
+
+ 4.0.0
+
+ com.coderising
+ ds-assignment
+ 0.0.1-SNAPSHOT
+ jar
+
+ ds-assignment
+ http://maven.apache.org
+
+
+ UTF-8
+
+
+
+
+
+ junit
+ junit
+ 4.12
+
+
+
+
+
+ aliyunmaven
+ http://maven.aliyun.com/nexus/content/groups/public/
+
+
+
diff --git a/liuxin/data-structure/assignment/src/main/java/com/coderising/download/DownloadThread.java b/liuxin/data-structure/assignment/src/main/java/com/coderising/download/DownloadThread.java
new file mode 100644
index 0000000000..900a3ad358
--- /dev/null
+++ b/liuxin/data-structure/assignment/src/main/java/com/coderising/download/DownloadThread.java
@@ -0,0 +1,20 @@
+package com.coderising.download;
+
+import com.coderising.download.api.Connection;
+
+public class DownloadThread extends Thread{
+
+ Connection conn;
+ int startPos;
+ int endPos;
+
+ public DownloadThread( Connection conn, int startPos, int endPos){
+
+ this.conn = conn;
+ this.startPos = startPos;
+ this.endPos = endPos;
+ }
+ public void run(){
+
+ }
+}
diff --git a/liuxin/data-structure/assignment/src/main/java/com/coderising/download/FileDownloader.java b/liuxin/data-structure/assignment/src/main/java/com/coderising/download/FileDownloader.java
new file mode 100644
index 0000000000..c3c8a3f27d
--- /dev/null
+++ b/liuxin/data-structure/assignment/src/main/java/com/coderising/download/FileDownloader.java
@@ -0,0 +1,73 @@
+package com.coderising.download;
+
+import com.coderising.download.api.Connection;
+import com.coderising.download.api.ConnectionException;
+import com.coderising.download.api.ConnectionManager;
+import com.coderising.download.api.DownloadListener;
+
+
+public class FileDownloader {
+
+ String url;
+
+ DownloadListener listener;
+
+ ConnectionManager cm;
+
+
+ public FileDownloader(String _url) {
+ this.url = _url;
+
+ }
+
+ public void execute(){
+ // 在这里实现你的代码, 注意: 需要用多线程实现下载
+ // 这个类依赖于其他几个接口, 你需要写这几个接口的实现代码
+ // (1) ConnectionManager , 可以打开一个连接,通过Connection可以读取其中的一段(用startPos, endPos来指定)
+ // (2) DownloadListener, 由于是多线程下载, 调用这个类的客户端不知道什么时候结束,所以你需要实现当所有
+ // 线程都执行完以后, 调用listener的notifiedFinished方法, 这样客户端就能收到通知。
+ // 具体的实现思路:
+ // 1. 需要调用ConnectionManager的open方法打开连接, 然后通过Connection.getContentLength方法获得文件的长度
+ // 2. 至少启动3个线程下载, 注意每个线程需要先调用ConnectionManager的open方法
+ // 然后调用read方法, read方法中有读取文件的开始位置和结束位置的参数, 返回值是byte[]数组
+ // 3. 把byte数组写入到文件中
+ // 4. 所有的线程都下载完成以后, 需要调用listener的notifiedFinished方法
+
+ // 下面的代码是示例代码, 也就是说只有一个线程, 你需要改造成多线程的。
+ Connection conn = null;
+ try {
+
+ conn = cm.open(this.url);
+
+ int length = conn.getContentLength();
+
+ new DownloadThread(conn,0,length-1).start();
+
+ } catch (ConnectionException e) {
+ e.printStackTrace();
+ }finally{
+ if(conn != null){
+ conn.close();
+ }
+ }
+
+
+
+
+ }
+
+ public void setListener(DownloadListener listener) {
+ this.listener = listener;
+ }
+
+
+
+ public void setConnectionManager(ConnectionManager ucm){
+ this.cm = ucm;
+ }
+
+ public DownloadListener getListener(){
+ return this.listener;
+ }
+
+}
diff --git a/liuxin/data-structure/assignment/src/main/java/com/coderising/download/FileDownloaderTest.java b/liuxin/data-structure/assignment/src/main/java/com/coderising/download/FileDownloaderTest.java
new file mode 100644
index 0000000000..4ff7f46ae0
--- /dev/null
+++ b/liuxin/data-structure/assignment/src/main/java/com/coderising/download/FileDownloaderTest.java
@@ -0,0 +1,59 @@
+package com.coderising.download;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.coderising.download.api.ConnectionManager;
+import com.coderising.download.api.DownloadListener;
+import com.coderising.download.impl.ConnectionManagerImpl;
+
+public class FileDownloaderTest {
+ boolean downloadFinished = false;
+ @Before
+ public void setUp() throws Exception {
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+ @Test
+ public void testDownload() {
+
+ String url = "http://localhost:8080/test.jpg";
+
+ FileDownloader downloader = new FileDownloader(url);
+
+
+ ConnectionManager cm = new ConnectionManagerImpl();
+ downloader.setConnectionManager(cm);
+
+ downloader.setListener(new DownloadListener() {
+ @Override
+ public void notifyFinished() {
+ downloadFinished = true;
+ }
+
+ });
+
+
+ downloader.execute();
+
+ // 等待多线程下载程序执行完毕
+ while (!downloadFinished) {
+ try {
+ System.out.println("还没有下载完成,休眠五秒");
+ //休眠5秒
+ Thread.sleep(5000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ System.out.println("下载完成!");
+
+
+
+ }
+
+}
diff --git a/liuxin/data-structure/assignment/src/main/java/com/coderising/download/api/Connection.java b/liuxin/data-structure/assignment/src/main/java/com/coderising/download/api/Connection.java
new file mode 100644
index 0000000000..0957eaf7f4
--- /dev/null
+++ b/liuxin/data-structure/assignment/src/main/java/com/coderising/download/api/Connection.java
@@ -0,0 +1,23 @@
+package com.coderising.download.api;
+
+import java.io.IOException;
+
+public interface Connection {
+ /**
+ * 给定开始和结束位置, 读取数据, 返回值是字节数组
+ * @param startPos 开始位置, 从0开始
+ * @param endPos 结束位置
+ * @return
+ */
+ public byte[] read(int startPos,int endPos) throws IOException;
+ /**
+ * 得到数据内容的长度
+ * @return
+ */
+ public int getContentLength();
+
+ /**
+ * 关闭连接
+ */
+ public void close();
+}
diff --git a/liuxin/data-structure/assignment/src/main/java/com/coderising/download/api/ConnectionException.java b/liuxin/data-structure/assignment/src/main/java/com/coderising/download/api/ConnectionException.java
new file mode 100644
index 0000000000..1551a80b3d
--- /dev/null
+++ b/liuxin/data-structure/assignment/src/main/java/com/coderising/download/api/ConnectionException.java
@@ -0,0 +1,5 @@
+package com.coderising.download.api;
+
+public class ConnectionException extends Exception {
+
+}
diff --git a/liuxin/data-structure/assignment/src/main/java/com/coderising/download/api/ConnectionManager.java b/liuxin/data-structure/assignment/src/main/java/com/coderising/download/api/ConnectionManager.java
new file mode 100644
index 0000000000..ce045393b1
--- /dev/null
+++ b/liuxin/data-structure/assignment/src/main/java/com/coderising/download/api/ConnectionManager.java
@@ -0,0 +1,10 @@
+package com.coderising.download.api;
+
+public interface ConnectionManager {
+ /**
+ * 给定一个url , 打开一个连接
+ * @param url
+ * @return
+ */
+ public Connection open(String url) throws ConnectionException;
+}
diff --git a/liuxin/data-structure/assignment/src/main/java/com/coderising/download/api/DownloadListener.java b/liuxin/data-structure/assignment/src/main/java/com/coderising/download/api/DownloadListener.java
new file mode 100644
index 0000000000..bf9807b307
--- /dev/null
+++ b/liuxin/data-structure/assignment/src/main/java/com/coderising/download/api/DownloadListener.java
@@ -0,0 +1,5 @@
+package com.coderising.download.api;
+
+public interface DownloadListener {
+ public void notifyFinished();
+}
diff --git a/liuxin/data-structure/assignment/src/main/java/com/coderising/download/impl/ConnectionImpl.java b/liuxin/data-structure/assignment/src/main/java/com/coderising/download/impl/ConnectionImpl.java
new file mode 100644
index 0000000000..36a9d2ce15
--- /dev/null
+++ b/liuxin/data-structure/assignment/src/main/java/com/coderising/download/impl/ConnectionImpl.java
@@ -0,0 +1,27 @@
+package com.coderising.download.impl;
+
+import java.io.IOException;
+
+import com.coderising.download.api.Connection;
+
+public class ConnectionImpl implements Connection{
+
+ @Override
+ public byte[] read(int startPos, int endPos) throws IOException {
+
+ return null;
+ }
+
+ @Override
+ public int getContentLength() {
+
+ return 0;
+ }
+
+ @Override
+ public void close() {
+
+
+ }
+
+}
diff --git a/liuxin/data-structure/assignment/src/main/java/com/coderising/download/impl/ConnectionManagerImpl.java b/liuxin/data-structure/assignment/src/main/java/com/coderising/download/impl/ConnectionManagerImpl.java
new file mode 100644
index 0000000000..172371dd55
--- /dev/null
+++ b/liuxin/data-structure/assignment/src/main/java/com/coderising/download/impl/ConnectionManagerImpl.java
@@ -0,0 +1,15 @@
+package com.coderising.download.impl;
+
+import com.coderising.download.api.Connection;
+import com.coderising.download.api.ConnectionException;
+import com.coderising.download.api.ConnectionManager;
+
+public class ConnectionManagerImpl implements ConnectionManager {
+
+ @Override
+ public Connection open(String url) throws ConnectionException {
+
+ return null;
+ }
+
+}
diff --git a/liuxin/data-structure/assignment/src/main/java/com/coderising/litestruts/LoginAction.java b/liuxin/data-structure/assignment/src/main/java/com/coderising/litestruts/LoginAction.java
new file mode 100644
index 0000000000..dcdbe226ed
--- /dev/null
+++ b/liuxin/data-structure/assignment/src/main/java/com/coderising/litestruts/LoginAction.java
@@ -0,0 +1,39 @@
+package com.coderising.litestruts;
+
+/**
+ * 这是一个用来展示登录的业务类, 其中的用户名和密码都是硬编码的。
+ * @author liuxin
+ *
+ */
+public class LoginAction{
+ private String name ;
+ private String password;
+ private String message;
+
+ public String getName() {
+ return name;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public String execute(){
+ if("test".equals(name) && "1234".equals(password)){
+ this.message = "login successful";
+ return "success";
+ }
+ this.message = "login failed,please check your user/pwd";
+ return "fail";
+ }
+
+ public void setName(String name){
+ this.name = name;
+ }
+ public void setPassword(String password){
+ this.password = password;
+ }
+ public String getMessage(){
+ return this.message;
+ }
+}
diff --git a/liuxin/data-structure/assignment/src/main/java/com/coderising/litestruts/Struts.java b/liuxin/data-structure/assignment/src/main/java/com/coderising/litestruts/Struts.java
new file mode 100644
index 0000000000..85e2e22de3
--- /dev/null
+++ b/liuxin/data-structure/assignment/src/main/java/com/coderising/litestruts/Struts.java
@@ -0,0 +1,34 @@
+package com.coderising.litestruts;
+
+import java.util.Map;
+
+
+
+public class Struts {
+
+ public static View runAction(String actionName, Map parameters) {
+
+ /*
+
+ 0. 读取配置文件struts.xml
+
+ 1. 根据actionName找到相对应的class , 例如LoginAction, 通过反射实例化(创建对象)
+ 据parameters中的数据,调用对象的setter方法, 例如parameters中的数据是
+ ("name"="test" , "password"="1234") ,
+ 那就应该调用 setName和setPassword方法
+
+ 2. 通过反射调用对象的exectue 方法, 并获得返回值,例如"success"
+
+ 3. 通过反射找到对象的所有getter方法(例如 getMessage),
+ 通过反射来调用, 把值和属性形成一个HashMap , 例如 {"message": "登录成功"} ,
+ 放到View对象的parameters
+
+ 4. 根据struts.xml中的 配置,以及execute的返回值, 确定哪一个jsp,
+ 放到View对象的jsp字段中。
+
+ */
+
+ return null;
+ }
+
+}
diff --git a/liuxin/data-structure/assignment/src/main/java/com/coderising/litestruts/StrutsTest.java b/liuxin/data-structure/assignment/src/main/java/com/coderising/litestruts/StrutsTest.java
new file mode 100644
index 0000000000..b8c81faf3c
--- /dev/null
+++ b/liuxin/data-structure/assignment/src/main/java/com/coderising/litestruts/StrutsTest.java
@@ -0,0 +1,43 @@
+package com.coderising.litestruts;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+
+
+
+
+public class StrutsTest {
+
+ @Test
+ public void testLoginActionSuccess() {
+
+ String actionName = "login";
+
+ Map params = new HashMap();
+ params.put("name","test");
+ params.put("password","1234");
+
+
+ View view = Struts.runAction(actionName,params);
+
+ Assert.assertEquals("/jsp/homepage.jsp", view.getJsp());
+ Assert.assertEquals("login successful", view.getParameters().get("message"));
+ }
+
+ @Test
+ public void testLoginActionFailed() {
+ String actionName = "login";
+ Map params = new HashMap();
+ params.put("name","test");
+ params.put("password","123456"); //密码和预设的不一致
+
+ View view = Struts.runAction(actionName,params);
+
+ Assert.assertEquals("/jsp/showLogin.jsp", view.getJsp());
+ Assert.assertEquals("login failed,please check your user/pwd", view.getParameters().get("message"));
+ }
+}
diff --git a/liuxin/data-structure/assignment/src/main/java/com/coderising/litestruts/View.java b/liuxin/data-structure/assignment/src/main/java/com/coderising/litestruts/View.java
new file mode 100644
index 0000000000..07df2a5dab
--- /dev/null
+++ b/liuxin/data-structure/assignment/src/main/java/com/coderising/litestruts/View.java
@@ -0,0 +1,23 @@
+package com.coderising.litestruts;
+
+import java.util.Map;
+
+public class View {
+ private String jsp;
+ private Map parameters;
+
+ public String getJsp() {
+ return jsp;
+ }
+ public View setJsp(String jsp) {
+ this.jsp = jsp;
+ return this;
+ }
+ public Map getParameters() {
+ return parameters;
+ }
+ public View setParameters(Map parameters) {
+ this.parameters = parameters;
+ return this;
+ }
+}
diff --git a/liuxin/data-structure/assignment/src/main/java/com/coderising/litestruts/struts.xml b/liuxin/data-structure/assignment/src/main/java/com/coderising/litestruts/struts.xml
new file mode 100644
index 0000000000..e5d9aebba8
--- /dev/null
+++ b/liuxin/data-structure/assignment/src/main/java/com/coderising/litestruts/struts.xml
@@ -0,0 +1,11 @@
+
+
+
+ /jsp/homepage.jsp
+ /jsp/showLogin.jsp
+
+
+ /jsp/welcome.jsp
+ /jsp/error.jsp
+
+
\ No newline at end of file
diff --git a/liuxin/data-structure/assignment/src/main/java/com/coderising/ood/course/bad/Course.java b/liuxin/data-structure/assignment/src/main/java/com/coderising/ood/course/bad/Course.java
new file mode 100644
index 0000000000..436d092f58
--- /dev/null
+++ b/liuxin/data-structure/assignment/src/main/java/com/coderising/ood/course/bad/Course.java
@@ -0,0 +1,24 @@
+package com.coderising.ood.course.bad;
+
+import java.util.List;
+
+public class Course {
+ private String id;
+ private String desc;
+ private int duration ;
+
+ List prerequisites;
+
+ public List getPrerequisites() {
+ return prerequisites;
+ }
+
+
+ public boolean equals(Object o){
+ if(o == null || !(o instanceof Course)){
+ return false;
+ }
+ Course c = (Course)o;
+ return (c != null) && c.id.equals(id);
+ }
+}
diff --git a/liuxin/data-structure/assignment/src/main/java/com/coderising/ood/course/bad/CourseOffering.java b/liuxin/data-structure/assignment/src/main/java/com/coderising/ood/course/bad/CourseOffering.java
new file mode 100644
index 0000000000..ab8c764584
--- /dev/null
+++ b/liuxin/data-structure/assignment/src/main/java/com/coderising/ood/course/bad/CourseOffering.java
@@ -0,0 +1,26 @@
+package com.coderising.ood.course.bad;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+public class CourseOffering {
+ private Course course;
+ private String location;
+ private String teacher;
+ private int maxStudents;
+
+ List students = new ArrayList();
+
+ public int getMaxStudents() {
+ return maxStudents;
+ }
+
+ public List getStudents() {
+ return students;
+ }
+
+ public Course getCourse() {
+ return course;
+ }
+}
diff --git a/liuxin/data-structure/assignment/src/main/java/com/coderising/ood/course/bad/CourseService.java b/liuxin/data-structure/assignment/src/main/java/com/coderising/ood/course/bad/CourseService.java
new file mode 100644
index 0000000000..8c34bad0c3
--- /dev/null
+++ b/liuxin/data-structure/assignment/src/main/java/com/coderising/ood/course/bad/CourseService.java
@@ -0,0 +1,16 @@
+package com.coderising.ood.course.bad;
+
+
+
+public class CourseService {
+
+ public void chooseCourse(Student student, CourseOffering sc){
+ //如果学生上过该科目的先修科目,并且该课程还未满, 则学生可以加入该课程
+ if(student.getCoursesAlreadyTaken().containsAll(
+ sc.getCourse().getPrerequisites())
+ && sc.getMaxStudents() > sc.getStudents().size()){
+ sc.getStudents().add(student);
+ }
+
+ }
+}
diff --git a/liuxin/data-structure/assignment/src/main/java/com/coderising/ood/course/bad/Student.java b/liuxin/data-structure/assignment/src/main/java/com/coderising/ood/course/bad/Student.java
new file mode 100644
index 0000000000..a651923ef5
--- /dev/null
+++ b/liuxin/data-structure/assignment/src/main/java/com/coderising/ood/course/bad/Student.java
@@ -0,0 +1,14 @@
+package com.coderising.ood.course.bad;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Student {
+ private String id;
+ private String name;
+ private List coursesAlreadyTaken = new ArrayList();
+
+ public List getCoursesAlreadyTaken() {
+ return coursesAlreadyTaken;
+ }
+}
diff --git a/liuxin/data-structure/assignment/src/main/java/com/coderising/ood/course/good/Course.java b/liuxin/data-structure/assignment/src/main/java/com/coderising/ood/course/good/Course.java
new file mode 100644
index 0000000000..aefc9692bb
--- /dev/null
+++ b/liuxin/data-structure/assignment/src/main/java/com/coderising/ood/course/good/Course.java
@@ -0,0 +1,18 @@
+package com.coderising.ood.course.good;
+
+import java.util.List;
+
+public class Course {
+ private String id;
+ private String desc;
+ private int duration ;
+
+ List prerequisites;
+
+ public List getPrerequisites() {
+ return prerequisites;
+ }
+
+}
+
+
diff --git a/liuxin/data-structure/assignment/src/main/java/com/coderising/ood/course/good/CourseOffering.java b/liuxin/data-structure/assignment/src/main/java/com/coderising/ood/course/good/CourseOffering.java
new file mode 100644
index 0000000000..8660ec8109
--- /dev/null
+++ b/liuxin/data-structure/assignment/src/main/java/com/coderising/ood/course/good/CourseOffering.java
@@ -0,0 +1,34 @@
+package com.coderising.ood.course.good;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class CourseOffering {
+ private Course course;
+ private String location;
+ private String teacher;
+ private int maxStudents;
+
+ List students = new ArrayList();
+
+ public List getStudents() {
+ return students;
+ }
+ public int getMaxStudents() {
+ return maxStudents;
+ }
+ public Course getCourse() {
+ return course;
+ }
+
+
+ // 第二步: 把主要逻辑移动到CourseOffering 中
+ public void addStudent(Student student){
+
+ if(student.canAttend(course)
+ && this.maxStudents > students.size()){
+ students.add(student);
+ }
+ }
+ // 第三步: 重构CourseService
+}
diff --git a/liuxin/data-structure/assignment/src/main/java/com/coderising/ood/course/good/CourseService.java b/liuxin/data-structure/assignment/src/main/java/com/coderising/ood/course/good/CourseService.java
new file mode 100644
index 0000000000..22ba4a5450
--- /dev/null
+++ b/liuxin/data-structure/assignment/src/main/java/com/coderising/ood/course/good/CourseService.java
@@ -0,0 +1,14 @@
+package com.coderising.ood.course.good;
+
+
+
+public class CourseService {
+
+ public void chooseCourse(Student student, CourseOffering sc){
+ //第一步:重构: canAttend , 但是还有问题
+ if(student.canAttend(sc.getCourse())
+ && sc.getMaxStudents() > sc.getStudents().size()){
+ sc.getStudents().add(student);
+ }
+ }
+}
diff --git a/liuxin/data-structure/assignment/src/main/java/com/coderising/ood/course/good/Student.java b/liuxin/data-structure/assignment/src/main/java/com/coderising/ood/course/good/Student.java
new file mode 100644
index 0000000000..2c7e128b2a
--- /dev/null
+++ b/liuxin/data-structure/assignment/src/main/java/com/coderising/ood/course/good/Student.java
@@ -0,0 +1,21 @@
+package com.coderising.ood.course.good;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Student {
+ private String id;
+ private String name;
+ private List coursesAlreadyTaken = new ArrayList();
+
+ public List getCoursesAlreadyTaken() {
+ return coursesAlreadyTaken;
+ }
+
+ public boolean canAttend(Course course){
+ return this.coursesAlreadyTaken.containsAll(
+ course.getPrerequisites());
+ }
+}
+
+
diff --git a/liuxin/data-structure/assignment/src/main/java/com/coderising/ood/ocp/DateUtil.java b/liuxin/data-structure/assignment/src/main/java/com/coderising/ood/ocp/DateUtil.java
new file mode 100644
index 0000000000..b6cf28c096
--- /dev/null
+++ b/liuxin/data-structure/assignment/src/main/java/com/coderising/ood/ocp/DateUtil.java
@@ -0,0 +1,10 @@
+package com.coderising.ood.ocp;
+
+public class DateUtil {
+
+ public static String getCurrentDateAsString() {
+
+ return null;
+ }
+
+}
diff --git a/liuxin/data-structure/assignment/src/main/java/com/coderising/ood/ocp/Logger.java b/liuxin/data-structure/assignment/src/main/java/com/coderising/ood/ocp/Logger.java
new file mode 100644
index 0000000000..0357c4d912
--- /dev/null
+++ b/liuxin/data-structure/assignment/src/main/java/com/coderising/ood/ocp/Logger.java
@@ -0,0 +1,38 @@
+package com.coderising.ood.ocp;
+
+public class Logger {
+
+ public final int RAW_LOG = 1;
+ public final int RAW_LOG_WITH_DATE = 2;
+ public final int EMAIL_LOG = 1;
+ public final int SMS_LOG = 2;
+ public final int PRINT_LOG = 3;
+
+ int type = 0;
+ int method = 0;
+
+ public Logger(int logType, int logMethod){
+ this.type = logType;
+ this.method = logMethod;
+ }
+ public void log(String msg){
+
+ String logMsg = msg;
+
+ if(this.type == RAW_LOG){
+ logMsg = msg;
+ } else if(this.type == RAW_LOG_WITH_DATE){
+ String txtDate = DateUtil.getCurrentDateAsString();
+ logMsg = txtDate + ": " + msg;
+ }
+
+ if(this.method == EMAIL_LOG){
+ MailUtil.send(logMsg);
+ } else if(this.method == SMS_LOG){
+ SMSUtil.send(logMsg);
+ } else if(this.method == PRINT_LOG){
+ System.out.println(logMsg);
+ }
+ }
+}
+
diff --git a/liuxin/data-structure/assignment/src/main/java/com/coderising/ood/ocp/MailUtil.java b/liuxin/data-structure/assignment/src/main/java/com/coderising/ood/ocp/MailUtil.java
new file mode 100644
index 0000000000..ec54b839c5
--- /dev/null
+++ b/liuxin/data-structure/assignment/src/main/java/com/coderising/ood/ocp/MailUtil.java
@@ -0,0 +1,10 @@
+package com.coderising.ood.ocp;
+
+public class MailUtil {
+
+ public static void send(String logMsg) {
+ // TODO Auto-generated method stub
+
+ }
+
+}
diff --git a/liuxin/data-structure/assignment/src/main/java/com/coderising/ood/ocp/SMSUtil.java b/liuxin/data-structure/assignment/src/main/java/com/coderising/ood/ocp/SMSUtil.java
new file mode 100644
index 0000000000..13cf802418
--- /dev/null
+++ b/liuxin/data-structure/assignment/src/main/java/com/coderising/ood/ocp/SMSUtil.java
@@ -0,0 +1,10 @@
+package com.coderising.ood.ocp;
+
+public class SMSUtil {
+
+ public static void send(String logMsg) {
+ // TODO Auto-generated method stub
+
+ }
+
+}
diff --git a/liuxin/data-structure/assignment/src/main/java/com/coderising/ood/srp/Configuration.java b/liuxin/data-structure/assignment/src/main/java/com/coderising/ood/srp/Configuration.java
new file mode 100644
index 0000000000..f328c1816a
--- /dev/null
+++ b/liuxin/data-structure/assignment/src/main/java/com/coderising/ood/srp/Configuration.java
@@ -0,0 +1,23 @@
+package com.coderising.ood.srp;
+import java.util.HashMap;
+import java.util.Map;
+
+public class Configuration {
+
+ static Map configurations = new HashMap<>();
+ static{
+ configurations.put(ConfigurationKeys.SMTP_SERVER, "smtp.163.com");
+ configurations.put(ConfigurationKeys.ALT_SMTP_SERVER, "smtp1.163.com");
+ configurations.put(ConfigurationKeys.EMAIL_ADMIN, "admin@company.com");
+ }
+ /**
+ * 应该从配置文件读, 但是这里简化为直接从一个map 中去读
+ * @param key
+ * @return
+ */
+ public String getProperty(String key) {
+
+ return configurations.get(key);
+ }
+
+}
diff --git a/liuxin/data-structure/assignment/src/main/java/com/coderising/ood/srp/ConfigurationKeys.java b/liuxin/data-structure/assignment/src/main/java/com/coderising/ood/srp/ConfigurationKeys.java
new file mode 100644
index 0000000000..8695aed644
--- /dev/null
+++ b/liuxin/data-structure/assignment/src/main/java/com/coderising/ood/srp/ConfigurationKeys.java
@@ -0,0 +1,9 @@
+package com.coderising.ood.srp;
+
+public class ConfigurationKeys {
+
+ public static final String SMTP_SERVER = "smtp.server";
+ public static final String ALT_SMTP_SERVER = "alt.smtp.server";
+ public static final String EMAIL_ADMIN = "email.admin";
+
+}
diff --git a/liuxin/data-structure/assignment/src/main/java/com/coderising/ood/srp/DBUtil.java b/liuxin/data-structure/assignment/src/main/java/com/coderising/ood/srp/DBUtil.java
new file mode 100644
index 0000000000..82e9261d18
--- /dev/null
+++ b/liuxin/data-structure/assignment/src/main/java/com/coderising/ood/srp/DBUtil.java
@@ -0,0 +1,25 @@
+package com.coderising.ood.srp;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+public class DBUtil {
+
+ /**
+ * 应该从数据库读, 但是简化为直接生成。
+ * @param sql
+ * @return
+ */
+ public static List query(String sql){
+
+ List userList = new ArrayList();
+ for (int i = 1; i <= 3; i++) {
+ HashMap userInfo = new HashMap();
+ userInfo.put("NAME", "User" + i);
+ userInfo.put("EMAIL", "aa@bb.com");
+ userList.add(userInfo);
+ }
+
+ return userList;
+ }
+}
diff --git a/liuxin/data-structure/assignment/src/main/java/com/coderising/ood/srp/MailUtil.java b/liuxin/data-structure/assignment/src/main/java/com/coderising/ood/srp/MailUtil.java
new file mode 100644
index 0000000000..9f9e749af7
--- /dev/null
+++ b/liuxin/data-structure/assignment/src/main/java/com/coderising/ood/srp/MailUtil.java
@@ -0,0 +1,18 @@
+package com.coderising.ood.srp;
+
+public class MailUtil {
+
+ public static void sendEmail(String toAddress, String fromAddress, String subject, String message, String smtpHost,
+ boolean debug) {
+ //假装发了一封邮件
+ StringBuilder buffer = new StringBuilder();
+ buffer.append("From:").append(fromAddress).append("\n");
+ buffer.append("To:").append(toAddress).append("\n");
+ buffer.append("Subject:").append(subject).append("\n");
+ buffer.append("Content:").append(message).append("\n");
+ System.out.println(buffer.toString());
+
+ }
+
+
+}
diff --git a/liuxin/data-structure/assignment/src/main/java/com/coderising/ood/srp/PromotionMail.java b/liuxin/data-structure/assignment/src/main/java/com/coderising/ood/srp/PromotionMail.java
new file mode 100644
index 0000000000..781587a846
--- /dev/null
+++ b/liuxin/data-structure/assignment/src/main/java/com/coderising/ood/srp/PromotionMail.java
@@ -0,0 +1,199 @@
+package com.coderising.ood.srp;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+
+public class PromotionMail {
+
+
+ protected String sendMailQuery = null;
+
+
+ protected String smtpHost = null;
+ protected String altSmtpHost = null;
+ protected String fromAddress = null;
+ protected String toAddress = null;
+ protected String subject = null;
+ protected String message = null;
+
+ protected String productID = null;
+ protected String productDesc = null;
+
+ private static Configuration config;
+
+
+
+ private static final String NAME_KEY = "NAME";
+ private static final String EMAIL_KEY = "EMAIL";
+
+
+ public static void main(String[] args) throws Exception {
+
+ File f = new File("C:\\coderising\\workspace_ds\\ood-example\\src\\product_promotion.txt");
+ boolean emailDebug = false;
+
+ PromotionMail pe = new PromotionMail(f, emailDebug);
+
+ }
+
+
+ public PromotionMail(File file, boolean mailDebug) throws Exception {
+
+ //读取配置文件, 文件中只有一行用空格隔开, 例如 P8756 iPhone8
+ readFile(file);
+
+
+ config = new Configuration();
+
+ setSMTPHost();
+ setAltSMTPHost();
+
+
+ setFromAddress();
+
+
+ setLoadQuery();
+
+ sendEMails(mailDebug, loadMailingList());
+
+
+ }
+
+
+
+
+ protected void setProductID(String productID)
+ {
+ this.productID = productID;
+
+ }
+
+ protected String getproductID()
+ {
+ return productID;
+ }
+
+ protected void setLoadQuery() throws Exception {
+
+ sendMailQuery = "Select name from subscriptions "
+ + "where product_id= '" + productID +"' "
+ + "and send_mail=1 ";
+
+
+ System.out.println("loadQuery set");
+ }
+
+
+ protected void setSMTPHost()
+ {
+ smtpHost = config.getProperty(ConfigurationKeys.SMTP_SERVER);
+ }
+
+
+ protected void setAltSMTPHost()
+ {
+ altSmtpHost = config.getProperty(ConfigurationKeys.ALT_SMTP_SERVER);
+
+ }
+
+
+ protected void setFromAddress()
+ {
+ fromAddress = config.getProperty(ConfigurationKeys.EMAIL_ADMIN);
+ }
+
+ protected void setMessage(HashMap userInfo) throws IOException
+ {
+
+ String name = (String) userInfo.get(NAME_KEY);
+
+ subject = "您关注的产品降价了";
+ message = "尊敬的 "+name+", 您关注的产品 " + productDesc + " 降价了,欢迎购买!" ;
+
+
+
+ }
+
+
+ protected void readFile(File file) throws IOException // @02C
+ {
+ BufferedReader br = null;
+ try {
+ br = new BufferedReader(new FileReader(file));
+ String temp = br.readLine();
+ String[] data = temp.split(" ");
+
+ setProductID(data[0]);
+ setProductDesc(data[1]);
+
+ System.out.println("产品ID = " + productID + "\n");
+ System.out.println("产品描述 = " + productDesc + "\n");
+
+ } catch (IOException e) {
+ throw new IOException(e.getMessage());
+ } finally {
+ br.close();
+ }
+ }
+
+ private void setProductDesc(String desc) {
+ this.productDesc = desc;
+ }
+
+
+ protected void configureEMail(HashMap userInfo) throws IOException
+ {
+ toAddress = (String) userInfo.get(EMAIL_KEY);
+ if (toAddress.length() > 0)
+ setMessage(userInfo);
+ }
+
+ protected List loadMailingList() throws Exception {
+ return DBUtil.query(this.sendMailQuery);
+ }
+
+
+ protected void sendEMails(boolean debug, List mailingList) throws IOException
+ {
+
+ System.out.println("开始发送邮件");
+
+
+ if (mailingList != null) {
+ Iterator iter = mailingList.iterator();
+ while (iter.hasNext()) {
+ configureEMail((HashMap) iter.next());
+ try
+ {
+ if (toAddress.length() > 0)
+ MailUtil.sendEmail(toAddress, fromAddress, subject, message, smtpHost, debug);
+ }
+ catch (Exception e)
+ {
+
+ try {
+ MailUtil.sendEmail(toAddress, fromAddress, subject, message, altSmtpHost, debug);
+
+ } catch (Exception e2)
+ {
+ System.out.println("通过备用 SMTP服务器发送邮件失败: " + e2.getMessage());
+ }
+ }
+ }
+
+
+ }
+
+ else {
+ System.out.println("没有邮件发送");
+
+ }
+
+ }
+}
diff --git a/liuxin/data-structure/assignment/src/main/java/com/coderising/ood/srp/product_promotion.txt b/liuxin/data-structure/assignment/src/main/java/com/coderising/ood/srp/product_promotion.txt
new file mode 100644
index 0000000000..a98917f829
--- /dev/null
+++ b/liuxin/data-structure/assignment/src/main/java/com/coderising/ood/srp/product_promotion.txt
@@ -0,0 +1,4 @@
+P8756 iPhone8
+P3946 XiaoMi10
+P8904 Oppo R15
+P4955 Vivo X20
\ No newline at end of file
diff --git a/liuxin/src/com/coding/basic/Iterator.java b/liuxin/data-structure/assignment/src/main/java/com/coding/basic/Iterator.java
similarity index 100%
rename from liuxin/src/com/coding/basic/Iterator.java
rename to liuxin/data-structure/assignment/src/main/java/com/coding/basic/Iterator.java
diff --git a/liuxin/src/com/coding/basic/List.java b/liuxin/data-structure/assignment/src/main/java/com/coding/basic/List.java
similarity index 100%
rename from liuxin/src/com/coding/basic/List.java
rename to liuxin/data-structure/assignment/src/main/java/com/coding/basic/List.java
diff --git a/liuxin/data-structure/assignment/src/main/java/com/coding/basic/array/ArrayList.java b/liuxin/data-structure/assignment/src/main/java/com/coding/basic/array/ArrayList.java
new file mode 100644
index 0000000000..4576c016af
--- /dev/null
+++ b/liuxin/data-structure/assignment/src/main/java/com/coding/basic/array/ArrayList.java
@@ -0,0 +1,35 @@
+package com.coding.basic.array;
+
+import com.coding.basic.Iterator;
+import com.coding.basic.List;
+
+public class ArrayList implements List {
+
+ private int size = 0;
+
+ private Object[] elementData = new Object[100];
+
+ public void add(Object o){
+
+ }
+ public void add(int index, Object o){
+
+ }
+
+ public Object get(int index){
+ return null;
+ }
+
+ public Object remove(int index){
+ return null;
+ }
+
+ public int size(){
+ return -1;
+ }
+
+ public Iterator iterator(){
+ return null;
+ }
+
+}
diff --git a/liuxin/data-structure/assignment/src/main/java/com/coding/basic/array/ArrayUtil.java b/liuxin/data-structure/assignment/src/main/java/com/coding/basic/array/ArrayUtil.java
new file mode 100644
index 0000000000..45740e6d57
--- /dev/null
+++ b/liuxin/data-structure/assignment/src/main/java/com/coding/basic/array/ArrayUtil.java
@@ -0,0 +1,96 @@
+package com.coding.basic.array;
+
+public class ArrayUtil {
+
+ /**
+ * 给定一个整形数组a , 对该数组的值进行置换
+ 例如: a = [7, 9 , 30, 3] , 置换后为 [3, 30, 9,7]
+ 如果 a = [7, 9, 30, 3, 4] , 置换后为 [4,3, 30 , 9,7]
+ * @param origin
+ * @return
+ */
+ public void reverseArray(int[] origin){
+
+ }
+
+ /**
+ * 现在有如下的一个数组: int oldArr[]={1,3,4,5,0,0,6,6,0,5,4,7,6,7,0,5}
+ * 要求将以上数组中值为0的项去掉,将不为0的值存入一个新的数组,生成的新数组为:
+ * {1,3,4,5,6,6,5,4,7,6,7,5}
+ * @param oldArray
+ * @return
+ */
+
+ public int[] removeZero(int[] oldArray){
+ return null;
+ }
+
+ /**
+ * 给定两个已经排序好的整形数组, a1和a2 , 创建一个新的数组a3, 使得a3 包含a1和a2 的所有元素, 并且仍然是有序的
+ * 例如 a1 = [3, 5, 7,8] a2 = [4, 5, 6,7] 则 a3 为[3,4,5,6,7,8] , 注意: 已经消除了重复
+ * @param array1
+ * @param array2
+ * @return
+ */
+
+ public int[] merge(int[] array1, int[] array2){
+ return null;
+ }
+ /**
+ * 把一个已经存满数据的数组 oldArray的容量进行扩展, 扩展后的新数据大小为oldArray.length + size
+ * 注意,老数组的元素在新数组中需要保持
+ * 例如 oldArray = [2,3,6] , size = 3,则返回的新数组为
+ * [2,3,6,0,0,0]
+ * @param oldArray
+ * @param size
+ * @return
+ */
+ public int[] grow(int [] oldArray, int size){
+ return null;
+ }
+
+ /**
+ * 斐波那契数列为:1,1,2,3,5,8,13,21...... ,给定一个最大值, 返回小于该值的数列
+ * 例如, max = 15 , 则返回的数组应该为 [1,1,2,3,5,8,13]
+ * max = 1, 则返回空数组 []
+ * @param max
+ * @return
+ */
+ public int[] fibonacci(int max){
+ return null;
+ }
+
+ /**
+ * 返回小于给定最大值max的所有素数数组
+ * 例如max = 23, 返回的数组为[2,3,5,7,11,13,17,19]
+ * @param max
+ * @return
+ */
+ public int[] getPrimes(int max){
+ return null;
+ }
+
+ /**
+ * 所谓“完数”, 是指这个数恰好等于它的因子之和,例如6=1+2+3
+ * 给定一个最大值max, 返回一个数组, 数组中是小于max 的所有完数
+ * @param max
+ * @return
+ */
+ public int[] getPerfectNumbers(int max){
+ return null;
+ }
+
+ /**
+ * 用seperator 把数组 array给连接起来
+ * 例如array= [3,8,9], seperator = "-"
+ * 则返回值为"3-8-9"
+ * @param array
+ * @param s
+ * @return
+ */
+ public String join(int[] array, String seperator){
+ return null;
+ }
+
+
+}
diff --git a/liuxin/data-structure/assignment/src/main/java/com/coding/basic/linklist/LRUPageFrame.java b/liuxin/data-structure/assignment/src/main/java/com/coding/basic/linklist/LRUPageFrame.java
new file mode 100644
index 0000000000..994a241a3d
--- /dev/null
+++ b/liuxin/data-structure/assignment/src/main/java/com/coding/basic/linklist/LRUPageFrame.java
@@ -0,0 +1,57 @@
+package com.coding.basic.linklist;
+
+
+public class LRUPageFrame {
+
+ private static class Node {
+
+ Node prev;
+ Node next;
+ int pageNum;
+
+ Node() {
+ }
+ }
+
+ private int capacity;
+
+ private int currentSize;
+ private Node first;// 链表头
+ private Node last;// 链表尾
+
+
+ public LRUPageFrame(int capacity) {
+ this.currentSize = 0;
+ this.capacity = capacity;
+
+ }
+
+ /**
+ * 获取缓存中对象
+ *
+ * @param key
+ * @return
+ */
+ public void access(int pageNum) {
+
+
+ }
+
+
+ public String toString(){
+ StringBuilder buffer = new StringBuilder();
+ Node node = first;
+ while(node != null){
+ buffer.append(node.pageNum);
+
+ node = node.next;
+ if(node != null){
+ buffer.append(",");
+ }
+ }
+ return buffer.toString();
+ }
+
+
+
+}
diff --git a/liuxin/data-structure/assignment/src/main/java/com/coding/basic/linklist/LRUPageFrameTest.java b/liuxin/data-structure/assignment/src/main/java/com/coding/basic/linklist/LRUPageFrameTest.java
new file mode 100644
index 0000000000..7fd72fc2b4
--- /dev/null
+++ b/liuxin/data-structure/assignment/src/main/java/com/coding/basic/linklist/LRUPageFrameTest.java
@@ -0,0 +1,34 @@
+package com.coding.basic.linklist;
+
+import org.junit.Assert;
+
+import org.junit.Test;
+
+
+public class LRUPageFrameTest {
+
+ @Test
+ public void testAccess() {
+ LRUPageFrame frame = new LRUPageFrame(3);
+ frame.access(7);
+ frame.access(0);
+ frame.access(1);
+ Assert.assertEquals("1,0,7", frame.toString());
+ frame.access(2);
+ Assert.assertEquals("2,1,0", frame.toString());
+ frame.access(0);
+ Assert.assertEquals("0,2,1", frame.toString());
+ frame.access(0);
+ Assert.assertEquals("0,2,1", frame.toString());
+ frame.access(3);
+ Assert.assertEquals("3,0,2", frame.toString());
+ frame.access(0);
+ Assert.assertEquals("0,3,2", frame.toString());
+ frame.access(4);
+ Assert.assertEquals("4,0,3", frame.toString());
+ frame.access(5);
+ Assert.assertEquals("5,4,0", frame.toString());
+
+ }
+
+}
diff --git a/liuxin/data-structure/assignment/src/main/java/com/coding/basic/linklist/LinkedList.java b/liuxin/data-structure/assignment/src/main/java/com/coding/basic/linklist/LinkedList.java
new file mode 100644
index 0000000000..f4c7556a2e
--- /dev/null
+++ b/liuxin/data-structure/assignment/src/main/java/com/coding/basic/linklist/LinkedList.java
@@ -0,0 +1,125 @@
+package com.coding.basic.linklist;
+
+import com.coding.basic.Iterator;
+import com.coding.basic.List;
+
+public class LinkedList implements List {
+
+ private Node head;
+
+ public void add(Object o){
+
+ }
+ public void add(int index , Object o){
+
+ }
+ public Object get(int index){
+ return null;
+ }
+ public Object remove(int index){
+ return null;
+ }
+
+ public int size(){
+ return -1;
+ }
+
+ public void addFirst(Object o){
+
+ }
+ public void addLast(Object o){
+
+ }
+ public Object removeFirst(){
+ return null;
+ }
+ public Object removeLast(){
+ return null;
+ }
+ public Iterator iterator(){
+ return null;
+ }
+
+
+ private static class Node{
+ Object data;
+ Node next;
+
+ }
+
+ /**
+ * 把该链表逆置
+ * 例如链表为 3->7->10 , 逆置后变为 10->7->3
+ */
+ public void reverse(){
+
+ }
+
+ /**
+ * 删除一个单链表的前半部分
+ * 例如:list = 2->5->7->8 , 删除以后的值为 7->8
+ * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10
+
+ */
+ public void removeFirstHalf(){
+
+ }
+
+ /**
+ * 从第i个元素开始, 删除length 个元素 , 注意i从0开始
+ * @param i
+ * @param length
+ */
+ public void remove(int i, int length){
+
+ }
+ /**
+ * 假定当前链表和listB均包含已升序排列的整数
+ * 从当前链表中取出那些listB所指定的元素
+ * 例如当前链表 = 11->101->201->301->401->501->601->701
+ * listB = 1->3->4->6
+ * 返回的结果应该是[101,301,401,601]
+ * @param list
+ */
+ public int[] getElements(LinkedList list){
+ return null;
+ }
+
+ /**
+ * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。
+ * 从当前链表中中删除在listB中出现的元素
+
+ * @param list
+ */
+
+ public void subtract(LinkedList list){
+
+ }
+
+ /**
+ * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。
+ * 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同)
+ */
+ public void removeDuplicateValues(){
+
+ }
+
+ /**
+ * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。
+ * 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素)
+ * @param min
+ * @param max
+ */
+ public void removeRange(int min, int max){
+
+ }
+
+ /**
+ * 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同)
+ * 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列
+ * @param list
+ */
+ public LinkedList intersection( LinkedList list){
+ return null;
+ }
+}
diff --git a/liuxin/data-structure/assignment/src/main/java/com/coding/basic/queue/CircleQueue.java b/liuxin/data-structure/assignment/src/main/java/com/coding/basic/queue/CircleQueue.java
new file mode 100644
index 0000000000..2e0550c67e
--- /dev/null
+++ b/liuxin/data-structure/assignment/src/main/java/com/coding/basic/queue/CircleQueue.java
@@ -0,0 +1,39 @@
+package com.coding.basic.queue;
+
+/**
+ * 用数组实现循环队列
+ * @author liuxin
+ *
+ * @param
+ */
+public class CircleQueue {
+
+ private final static int DEFAULT_SIZE = 10;
+
+ //用数组来保存循环队列的元素
+ private Object[] elementData = new Object[DEFAULT_SIZE] ;
+
+ //队头
+ private int front = 0;
+ //队尾
+ private int rear = 0;
+
+ public boolean isEmpty() {
+ return false;
+
+ }
+
+ public int size() {
+ return -1;
+ }
+
+
+
+ public void enQueue(E data) {
+
+ }
+
+ public E deQueue() {
+ return null;
+ }
+}
diff --git a/liuxin/data-structure/assignment/src/main/java/com/coding/basic/queue/Josephus.java b/liuxin/data-structure/assignment/src/main/java/com/coding/basic/queue/Josephus.java
new file mode 100644
index 0000000000..6a3ea639b9
--- /dev/null
+++ b/liuxin/data-structure/assignment/src/main/java/com/coding/basic/queue/Josephus.java
@@ -0,0 +1,18 @@
+package com.coding.basic.queue;
+
+import java.util.List;
+
+/**
+ * 用Queue来实现Josephus问题
+ * 在这个古老的问题当中, N个深陷绝境的人一致同意用这种方式减少生存人数: N个人围成一圈(位置记为0到N-1), 并且从第一个人报数, 报到M的人会被杀死, 直到最后一个人留下来
+ * 该方法返回一个List, 包含了被杀死人的次序
+ * @author liuxin
+ *
+ */
+public class Josephus {
+
+ public static List execute(int n, int m){
+ return null;
+ }
+
+}
diff --git a/liuxin/data-structure/assignment/src/main/java/com/coding/basic/queue/JosephusTest.java b/liuxin/data-structure/assignment/src/main/java/com/coding/basic/queue/JosephusTest.java
new file mode 100644
index 0000000000..7d90318b51
--- /dev/null
+++ b/liuxin/data-structure/assignment/src/main/java/com/coding/basic/queue/JosephusTest.java
@@ -0,0 +1,27 @@
+package com.coding.basic.queue;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+
+
+public class JosephusTest {
+
+ @Before
+ public void setUp() throws Exception {
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+ @Test
+ public void testExecute() {
+
+ Assert.assertEquals("[1, 3, 5, 0, 4, 2, 6]", Josephus.execute(7, 2).toString());
+
+ }
+
+}
diff --git a/liuxin/data-structure/assignment/src/main/java/com/coding/basic/queue/Queue.java b/liuxin/data-structure/assignment/src/main/java/com/coding/basic/queue/Queue.java
new file mode 100644
index 0000000000..c4c4b7325e
--- /dev/null
+++ b/liuxin/data-structure/assignment/src/main/java/com/coding/basic/queue/Queue.java
@@ -0,0 +1,61 @@
+package com.coding.basic.queue;
+
+import java.util.NoSuchElementException;
+
+public class Queue {
+ private Node first;
+ private Node last;
+ private int size;
+
+
+ private static class Node {
+ private E item;
+ private Node next;
+ }
+
+
+ public Queue() {
+ first = null;
+ last = null;
+ size = 0;
+ }
+
+
+ public boolean isEmpty() {
+ return first == null;
+ }
+
+ public int size() {
+ return size;
+ }
+
+
+
+ public void enQueue(E data) {
+ Node oldlast = last;
+ last = new Node();
+ last.item = data;
+ last.next = null;
+ if (isEmpty()) {
+ first = last;
+ }
+ else{
+ oldlast.next = last;
+ }
+ size++;
+ }
+
+ public E deQueue() {
+ if (isEmpty()) {
+ throw new NoSuchElementException("Queue underflow");
+ }
+ E item = first.item;
+ first = first.next;
+ size--;
+ if (isEmpty()) {
+ last = null;
+ }
+ return item;
+ }
+
+}
diff --git a/liuxin/data-structure/assignment/src/main/java/com/coding/basic/queue/QueueWithTwoStacks.java b/liuxin/data-structure/assignment/src/main/java/com/coding/basic/queue/QueueWithTwoStacks.java
new file mode 100644
index 0000000000..cef19a8b59
--- /dev/null
+++ b/liuxin/data-structure/assignment/src/main/java/com/coding/basic/queue/QueueWithTwoStacks.java
@@ -0,0 +1,47 @@
+package com.coding.basic.queue;
+
+import java.util.Stack;
+
+/**
+ * 用两个栈来实现一个队列
+ * @author liuxin
+ *
+ * @param
+ */
+public class QueueWithTwoStacks {
+ private Stack stack1;
+ private Stack stack2;
+
+
+ public QueueWithTwoStacks() {
+ stack1 = new Stack();
+ stack2 = new Stack();
+ }
+
+
+
+
+ public boolean isEmpty() {
+ return false;
+ }
+
+
+
+ public int size() {
+ return -1;
+ }
+
+
+
+ public void enQueue(E item) {
+
+ }
+
+ public E deQueue() {
+ return null;
+ }
+
+
+
+ }
+
diff --git a/liuxin/data-structure/assignment/src/main/java/com/coding/basic/stack/QuickMinStack.java b/liuxin/data-structure/assignment/src/main/java/com/coding/basic/stack/QuickMinStack.java
new file mode 100644
index 0000000000..f391d92b8f
--- /dev/null
+++ b/liuxin/data-structure/assignment/src/main/java/com/coding/basic/stack/QuickMinStack.java
@@ -0,0 +1,19 @@
+package com.coding.basic.stack;
+
+/**
+ * 设计一个栈,支持栈的push和pop操作,以及第三种操作findMin, 它返回改数据结构中的最小元素
+ * finMin操作最坏的情形下时间复杂度应该是O(1) , 简单来讲,操作一次就可以得到最小值
+ * @author liuxin
+ *
+ */
+public class QuickMinStack {
+ public void push(int data){
+
+ }
+ public int pop(){
+ return -1;
+ }
+ public int findMin(){
+ return -1;
+ }
+}
diff --git a/group17/1204187480/code/homework/basic/src/main/java/com/coding/basic/Stack.java b/liuxin/data-structure/assignment/src/main/java/com/coding/basic/stack/Stack.java
similarity index 78%
rename from group17/1204187480/code/homework/basic/src/main/java/com/coding/basic/Stack.java
rename to liuxin/data-structure/assignment/src/main/java/com/coding/basic/stack/Stack.java
index a5a04de76d..fedb243604 100644
--- a/group17/1204187480/code/homework/basic/src/main/java/com/coding/basic/Stack.java
+++ b/liuxin/data-structure/assignment/src/main/java/com/coding/basic/stack/Stack.java
@@ -1,4 +1,6 @@
-package com.coding.basic;
+package com.coding.basic.stack;
+
+import com.coding.basic.array.ArrayList;
public class Stack {
private ArrayList elementData = new ArrayList();
diff --git a/liuxin/data-structure/assignment/src/main/java/com/coding/basic/stack/StackUtil.java b/liuxin/data-structure/assignment/src/main/java/com/coding/basic/stack/StackUtil.java
new file mode 100644
index 0000000000..b0ec38161d
--- /dev/null
+++ b/liuxin/data-structure/assignment/src/main/java/com/coding/basic/stack/StackUtil.java
@@ -0,0 +1,48 @@
+package com.coding.basic.stack;
+import java.util.Stack;
+public class StackUtil {
+
+
+
+ /**
+ * 假设栈中的元素是Integer, 从栈顶到栈底是 : 5,4,3,2,1 调用该方法后, 元素次序变为: 1,2,3,4,5
+ * 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助
+ */
+ public static void reverse(Stack s) {
+
+
+
+ }
+
+ /**
+ * 删除栈中的某个元素 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助
+ *
+ * @param o
+ */
+ public static void remove(Stack s,Object o) {
+
+ }
+
+ /**
+ * 从栈顶取得len个元素, 原来的栈中元素保持不变
+ * 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助
+ * @param len
+ * @return
+ */
+ public static Object[] getTop(Stack s,int len) {
+ return null;
+ }
+ /**
+ * 字符串s 可能包含这些字符: ( ) [ ] { }, a,b,c... x,yz
+ * 使用堆栈检查字符串s中的括号是不是成对出现的。
+ * 例如s = "([e{d}f])" , 则该字符串中的括号是成对出现, 该方法返回true
+ * 如果 s = "([b{x]y})", 则该字符串中的括号不是成对出现的, 该方法返回false;
+ * @param s
+ * @return
+ */
+ public static boolean isValidPairs(String s){
+ return false;
+ }
+
+
+}
diff --git a/liuxin/data-structure/assignment/src/main/java/com/coding/basic/stack/StackUtilTest.java b/liuxin/data-structure/assignment/src/main/java/com/coding/basic/stack/StackUtilTest.java
new file mode 100644
index 0000000000..76f2cb7668
--- /dev/null
+++ b/liuxin/data-structure/assignment/src/main/java/com/coding/basic/stack/StackUtilTest.java
@@ -0,0 +1,65 @@
+package com.coding.basic.stack;
+
+import java.util.Stack;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+public class StackUtilTest {
+
+ @Before
+ public void setUp() throws Exception {
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+
+ @Test
+ public void testReverse() {
+ Stack s = new Stack();
+ s.push(1);
+ s.push(2);
+ s.push(3);
+ s.push(4);
+ s.push(5);
+ Assert.assertEquals("[1, 2, 3, 4, 5]", s.toString());
+ StackUtil.reverse(s);
+ Assert.assertEquals("[5, 4, 3, 2, 1]", s.toString());
+ }
+
+ @Test
+ public void testRemove() {
+ Stack s = new Stack();
+ s.push(1);
+ s.push(2);
+ s.push(3);
+ StackUtil.remove(s, 2);
+ Assert.assertEquals("[1, 3]", s.toString());
+ }
+
+ @Test
+ public void testGetTop() {
+ Stack s = new Stack();
+ s.push(1);
+ s.push(2);
+ s.push(3);
+ s.push(4);
+ s.push(5);
+ {
+ Object[] values = StackUtil.getTop(s, 3);
+ Assert.assertEquals(5, values[0]);
+ Assert.assertEquals(4, values[1]);
+ Assert.assertEquals(3, values[2]);
+ }
+ }
+
+ @Test
+ public void testIsValidPairs() {
+ Assert.assertTrue(StackUtil.isValidPairs("([e{d}f])"));
+ Assert.assertFalse(StackUtil.isValidPairs("([b{x]y})"));
+ }
+
+}
diff --git a/liuxin/data-structure/assignment/src/main/java/com/coding/basic/stack/StackWithTwoQueues.java b/liuxin/data-structure/assignment/src/main/java/com/coding/basic/stack/StackWithTwoQueues.java
new file mode 100644
index 0000000000..d0ab4387d2
--- /dev/null
+++ b/liuxin/data-structure/assignment/src/main/java/com/coding/basic/stack/StackWithTwoQueues.java
@@ -0,0 +1,16 @@
+package com.coding.basic.stack;
+
+
+public class StackWithTwoQueues {
+
+
+ public void push(int data) {
+
+ }
+
+ public int pop() {
+ return -1;
+ }
+
+
+}
diff --git a/liuxin/data-structure/assignment/src/main/java/com/coding/basic/stack/TwoStackInOneArray.java b/liuxin/data-structure/assignment/src/main/java/com/coding/basic/stack/TwoStackInOneArray.java
new file mode 100644
index 0000000000..e86d056a24
--- /dev/null
+++ b/liuxin/data-structure/assignment/src/main/java/com/coding/basic/stack/TwoStackInOneArray.java
@@ -0,0 +1,57 @@
+package com.coding.basic.stack;
+
+/**
+ * 用一个数组实现两个栈
+ * 将数组的起始位置看作是第一个栈的栈底,将数组的尾部看作第二个栈的栈底,压栈时,栈顶指针分别向中间移动,直到两栈顶指针相遇,则扩容。
+ * @author liuxin
+ *
+ */
+public class TwoStackInOneArray {
+ Object[] data = new Object[10];
+
+ /**
+ * 向第一个栈中压入元素
+ * @param o
+ */
+ public void push1(Object o){
+
+ }
+ /**
+ * 从第一个栈中弹出元素
+ * @return
+ */
+ public Object pop1(){
+ return null;
+ }
+
+ /**
+ * 获取第一个栈的栈顶元素
+ * @return
+ */
+
+ public Object peek1(){
+ return null;
+ }
+ /*
+ * 向第二个栈压入元素
+ */
+ public void push2(Object o){
+
+ }
+ /**
+ * 从第二个栈弹出元素
+ * @return
+ */
+ public Object pop2(){
+ return null;
+ }
+ /**
+ * 获取第二个栈的栈顶元素
+ * @return
+ */
+
+ public Object peek2(){
+ return null;
+ }
+
+}
diff --git a/liuxin/data-structure/assignment/src/main/java/com/coding/basic/stack/expr/InfixExpr.java b/liuxin/data-structure/assignment/src/main/java/com/coding/basic/stack/expr/InfixExpr.java
new file mode 100644
index 0000000000..ef85ff007f
--- /dev/null
+++ b/liuxin/data-structure/assignment/src/main/java/com/coding/basic/stack/expr/InfixExpr.java
@@ -0,0 +1,15 @@
+package com.coding.basic.stack.expr;
+
+public class InfixExpr {
+ String expr = null;
+
+ public InfixExpr(String expr) {
+ this.expr = expr;
+ }
+
+ public float evaluate() {
+ return 0.0f;
+ }
+
+
+}
diff --git a/liuxin/data-structure/assignment/src/main/java/com/coding/basic/stack/expr/InfixExprTest.java b/liuxin/data-structure/assignment/src/main/java/com/coding/basic/stack/expr/InfixExprTest.java
new file mode 100644
index 0000000000..20e34e8852
--- /dev/null
+++ b/liuxin/data-structure/assignment/src/main/java/com/coding/basic/stack/expr/InfixExprTest.java
@@ -0,0 +1,52 @@
+package com.coding.basic.stack.expr;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+
+public class InfixExprTest {
+
+ @Before
+ public void setUp() throws Exception {
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+ @Test
+ public void testEvaluate() {
+ //InfixExpr expr = new InfixExpr("300*20+12*5-20/4");
+ {
+ InfixExpr expr = new InfixExpr("2+3*4+5");
+ Assert.assertEquals(19.0, expr.evaluate(), 0.001f);
+ }
+ {
+ InfixExpr expr = new InfixExpr("3*20+12*5-40/2");
+ Assert.assertEquals(100.0, expr.evaluate(), 0.001f);
+ }
+
+ {
+ InfixExpr expr = new InfixExpr("3*20/2");
+ Assert.assertEquals(30, expr.evaluate(), 0.001f);
+ }
+
+ {
+ InfixExpr expr = new InfixExpr("20/2*3");
+ Assert.assertEquals(30, expr.evaluate(), 0.001f);
+ }
+
+ {
+ InfixExpr expr = new InfixExpr("10-30+50");
+ Assert.assertEquals(30, expr.evaluate(), 0.001f);
+ }
+ {
+ InfixExpr expr = new InfixExpr("10-2*3+50");
+ Assert.assertEquals(54, expr.evaluate(), 0.001f);
+ }
+
+ }
+
+}
diff --git a/liuxin/data-structure/assignment/src/main/java/com/coding/basic/stack/expr/InfixToPostfix.java b/liuxin/data-structure/assignment/src/main/java/com/coding/basic/stack/expr/InfixToPostfix.java
new file mode 100644
index 0000000000..96a2194a67
--- /dev/null
+++ b/liuxin/data-structure/assignment/src/main/java/com/coding/basic/stack/expr/InfixToPostfix.java
@@ -0,0 +1,14 @@
+package com.coding.basic.stack.expr;
+
+import java.util.List;
+
+public class InfixToPostfix {
+
+ public static List convert(String expr) {
+
+ return null;
+ }
+
+
+
+}
diff --git a/liuxin/data-structure/assignment/src/main/java/com/coding/basic/stack/expr/PostfixExpr.java b/liuxin/data-structure/assignment/src/main/java/com/coding/basic/stack/expr/PostfixExpr.java
new file mode 100644
index 0000000000..dcbb18be4b
--- /dev/null
+++ b/liuxin/data-structure/assignment/src/main/java/com/coding/basic/stack/expr/PostfixExpr.java
@@ -0,0 +1,18 @@
+package com.coding.basic.stack.expr;
+
+import java.util.List;
+import java.util.Stack;
+
+public class PostfixExpr {
+String expr = null;
+
+ public PostfixExpr(String expr) {
+ this.expr = expr;
+ }
+
+ public float evaluate() {
+ return 0.0f;
+ }
+
+
+}
diff --git a/liuxin/data-structure/assignment/src/main/java/com/coding/basic/stack/expr/PostfixExprTest.java b/liuxin/data-structure/assignment/src/main/java/com/coding/basic/stack/expr/PostfixExprTest.java
new file mode 100644
index 0000000000..c0435a2db5
--- /dev/null
+++ b/liuxin/data-structure/assignment/src/main/java/com/coding/basic/stack/expr/PostfixExprTest.java
@@ -0,0 +1,41 @@
+package com.coding.basic.stack.expr;
+
+
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+
+
+public class PostfixExprTest {
+
+ @Before
+ public void setUp() throws Exception {
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+ @Test
+ public void testEvaluate() {
+ {
+ PostfixExpr expr = new PostfixExpr("6 5 2 3 + 8 * + 3 + *");
+ Assert.assertEquals(288, expr.evaluate(),0.0f);
+ }
+ {
+ //9+(3-1)*3+10/2
+ PostfixExpr expr = new PostfixExpr("9 3 1-3*+ 10 2/+");
+ Assert.assertEquals(20, expr.evaluate(),0.0f);
+ }
+
+ {
+ //10-2*3+50
+ PostfixExpr expr = new PostfixExpr("10 2 3 * - 50 +");
+ Assert.assertEquals(54, expr.evaluate(),0.0f);
+ }
+ }
+
+}
diff --git a/liuxin/data-structure/assignment/src/main/java/com/coding/basic/stack/expr/PrefixExpr.java b/liuxin/data-structure/assignment/src/main/java/com/coding/basic/stack/expr/PrefixExpr.java
new file mode 100644
index 0000000000..956927e2df
--- /dev/null
+++ b/liuxin/data-structure/assignment/src/main/java/com/coding/basic/stack/expr/PrefixExpr.java
@@ -0,0 +1,18 @@
+package com.coding.basic.stack.expr;
+
+import java.util.List;
+import java.util.Stack;
+
+public class PrefixExpr {
+ String expr = null;
+
+ public PrefixExpr(String expr) {
+ this.expr = expr;
+ }
+
+ public float evaluate() {
+ return 0.0f;
+ }
+
+
+}
diff --git a/liuxin/data-structure/assignment/src/main/java/com/coding/basic/stack/expr/PrefixExprTest.java b/liuxin/data-structure/assignment/src/main/java/com/coding/basic/stack/expr/PrefixExprTest.java
new file mode 100644
index 0000000000..5cec210e75
--- /dev/null
+++ b/liuxin/data-structure/assignment/src/main/java/com/coding/basic/stack/expr/PrefixExprTest.java
@@ -0,0 +1,45 @@
+package com.coding.basic.stack.expr;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+
+public class PrefixExprTest {
+
+ @Before
+ public void setUp() throws Exception {
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+ @Test
+ public void testEvaluate() {
+ {
+ // 2*3+4*5
+ PrefixExpr expr = new PrefixExpr("+ * 2 3* 4 5");
+ Assert.assertEquals(26, expr.evaluate(),0.001f);
+ }
+ {
+ // 4*2 + 6+9*2/3 -8
+ PrefixExpr expr = new PrefixExpr("-++6/*2 9 3 * 4 2 8");
+ Assert.assertEquals(12, expr.evaluate(),0.001f);
+ }
+ {
+ //(3+4)*5-6
+ PrefixExpr expr = new PrefixExpr("- * + 3 4 5 6");
+ Assert.assertEquals(29, expr.evaluate(),0.001f);
+ }
+ {
+ //1+((2+3)*4)-5
+ PrefixExpr expr = new PrefixExpr("- + 1 * + 2 3 4 5");
+ Assert.assertEquals(16, expr.evaluate(),0.001f);
+ }
+
+
+ }
+
+}
diff --git a/liuxin/data-structure/assignment/src/main/java/com/coding/basic/stack/expr/Token.java b/liuxin/data-structure/assignment/src/main/java/com/coding/basic/stack/expr/Token.java
new file mode 100644
index 0000000000..8579743fe9
--- /dev/null
+++ b/liuxin/data-structure/assignment/src/main/java/com/coding/basic/stack/expr/Token.java
@@ -0,0 +1,50 @@
+package com.coding.basic.stack.expr;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+class Token {
+ public static final List OPERATORS = Arrays.asList("+", "-", "*", "/");
+ private static final Map priorities = new HashMap<>();
+ static {
+ priorities.put("+", 1);
+ priorities.put("-", 1);
+ priorities.put("*", 2);
+ priorities.put("/", 2);
+ }
+ static final int OPERATOR = 1;
+ static final int NUMBER = 2;
+ String value;
+ int type;
+ public Token(int type, String value){
+ this.type = type;
+ this.value = value;
+ }
+
+ public boolean isNumber() {
+ return type == NUMBER;
+ }
+
+ public boolean isOperator() {
+ return type == OPERATOR;
+ }
+
+ public int getIntValue() {
+ return Integer.valueOf(value).intValue();
+ }
+ public String toString(){
+ return value;
+ }
+
+ public boolean hasHigherPriority(Token t){
+ if(!this.isOperator() && !t.isOperator()){
+ throw new RuntimeException("numbers can't compare priority");
+ }
+ return priorities.get(this.value) - priorities.get(t.value) > 0;
+ }
+
+
+
+}
\ No newline at end of file
diff --git a/liuxin/data-structure/assignment/src/main/java/com/coding/basic/stack/expr/TokenParser.java b/liuxin/data-structure/assignment/src/main/java/com/coding/basic/stack/expr/TokenParser.java
new file mode 100644
index 0000000000..d3b0f167e1
--- /dev/null
+++ b/liuxin/data-structure/assignment/src/main/java/com/coding/basic/stack/expr/TokenParser.java
@@ -0,0 +1,57 @@
+package com.coding.basic.stack.expr;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class TokenParser {
+
+
+ public List parse(String expr) {
+ List tokens = new ArrayList<>();
+
+ int i = 0;
+
+ while (i < expr.length()) {
+
+ char c = expr.charAt(i);
+
+ if (isOperator(c)) {
+
+ Token t = new Token(Token.OPERATOR, String.valueOf(c));
+ tokens.add(t);
+ i++;
+
+ } else if (Character.isDigit(c)) {
+
+ int nextOperatorIndex = indexOfNextOperator(i, expr);
+ String value = expr.substring(i, nextOperatorIndex);
+ Token t = new Token(Token.NUMBER, value);
+ tokens.add(t);
+ i = nextOperatorIndex;
+
+ } else{
+ System.out.println("char :["+c+"] is not number or operator,ignore");
+ i++;
+ }
+
+ }
+ return tokens;
+ }
+
+ private int indexOfNextOperator(int i, String expr) {
+
+ while (Character.isDigit(expr.charAt(i))) {
+ i++;
+ if (i == expr.length()) {
+ break;
+ }
+ }
+ return i;
+
+ }
+
+ private boolean isOperator(char c) {
+ String sc = String.valueOf(c);
+ return Token.OPERATORS.contains(sc);
+ }
+}
diff --git a/liuxin/data-structure/assignment/src/main/java/com/coding/basic/stack/expr/TokenParserTest.java b/liuxin/data-structure/assignment/src/main/java/com/coding/basic/stack/expr/TokenParserTest.java
new file mode 100644
index 0000000000..399d3e857e
--- /dev/null
+++ b/liuxin/data-structure/assignment/src/main/java/com/coding/basic/stack/expr/TokenParserTest.java
@@ -0,0 +1,41 @@
+package com.coding.basic.stack.expr;
+
+import static org.junit.Assert.*;
+
+import java.util.List;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class TokenParserTest {
+
+ @Before
+ public void setUp() throws Exception {
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+ @Test
+ public void test() {
+
+ TokenParser parser = new TokenParser();
+ List tokens = parser.parse("300*20+12*5-20/4");
+
+ Assert.assertEquals(300, tokens.get(0).getIntValue());
+ Assert.assertEquals("*", tokens.get(1).toString());
+ Assert.assertEquals(20, tokens.get(2).getIntValue());
+ Assert.assertEquals("+", tokens.get(3).toString());
+ Assert.assertEquals(12, tokens.get(4).getIntValue());
+ Assert.assertEquals("*", tokens.get(5).toString());
+ Assert.assertEquals(5, tokens.get(6).getIntValue());
+ Assert.assertEquals("-", tokens.get(7).toString());
+ Assert.assertEquals(20, tokens.get(8).getIntValue());
+ Assert.assertEquals("/", tokens.get(9).toString());
+ Assert.assertEquals(4, tokens.get(10).getIntValue());
+ }
+
+}
diff --git a/liuxin/data-structure/assignment/src/main/java/com/coding/basic/tree/BinarySearchTree.java b/liuxin/data-structure/assignment/src/main/java/com/coding/basic/tree/BinarySearchTree.java
new file mode 100644
index 0000000000..4536ee7a2b
--- /dev/null
+++ b/liuxin/data-structure/assignment/src/main/java/com/coding/basic/tree/BinarySearchTree.java
@@ -0,0 +1,55 @@
+package com.coding.basic.tree;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.coding.basic.queue.Queue;
+
+public class BinarySearchTree {
+
+ BinaryTreeNode root;
+ public BinarySearchTree(BinaryTreeNode root){
+ this.root = root;
+ }
+ public BinaryTreeNode getRoot(){
+ return root;
+ }
+ public T findMin(){
+ return null;
+ }
+ public T findMax(){
+ return null;
+ }
+ public int height() {
+ return -1;
+ }
+ public int size() {
+ return -1;
+ }
+ public void remove(T e){
+
+ }
+ public List levelVisit(){
+
+ return null;
+ }
+ public boolean isValid(){
+ return false;
+ }
+ public T getLowestCommonAncestor(T n1, T n2){
+ return null;
+
+ }
+ /**
+ * 返回所有满足下列条件的节点的值: n1 <= n <= n2 , n 为
+ * 该二叉查找树中的某一节点
+ * @param n1
+ * @param n2
+ * @return
+ */
+ public List getNodesBetween(T n1, T n2){
+ return null;
+ }
+
+}
+
diff --git a/liuxin/data-structure/assignment/src/main/java/com/coding/basic/tree/BinarySearchTreeTest.java b/liuxin/data-structure/assignment/src/main/java/com/coding/basic/tree/BinarySearchTreeTest.java
new file mode 100644
index 0000000000..4a53dbe2f1
--- /dev/null
+++ b/liuxin/data-structure/assignment/src/main/java/com/coding/basic/tree/BinarySearchTreeTest.java
@@ -0,0 +1,109 @@
+package com.coding.basic.tree;
+
+import java.util.List;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+
+
+public class BinarySearchTreeTest {
+
+ BinarySearchTree tree = null;
+
+ @Before
+ public void setUp() throws Exception {
+ BinaryTreeNode root = new BinaryTreeNode(6);
+ root.left = new BinaryTreeNode(2);
+ root.right = new BinaryTreeNode(8);
+ root.left.left = new BinaryTreeNode(1);
+ root.left.right = new BinaryTreeNode(4);
+ root.left.right.left = new BinaryTreeNode(3);
+ root.left.right.right = new BinaryTreeNode(5);
+ tree = new BinarySearchTree(root);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ tree = null;
+ }
+
+ @Test
+ public void testFindMin() {
+ Assert.assertEquals(1, tree.findMin().intValue());
+
+ }
+
+ @Test
+ public void testFindMax() {
+ Assert.assertEquals(8, tree.findMax().intValue());
+ }
+
+ @Test
+ public void testHeight() {
+ Assert.assertEquals(4, tree.height());
+ }
+
+ @Test
+ public void testSize() {
+ Assert.assertEquals(7, tree.size());
+ }
+
+ @Test
+ public void testRemoveLeaf() {
+ tree.remove(3);
+ BinaryTreeNode root= tree.getRoot();
+ Assert.assertEquals(4, root.left.right.data.intValue());
+
+ }
+ @Test
+ public void testRemoveMiddleNode1() {
+ tree.remove(4);
+ BinaryTreeNode root= tree.getRoot();
+ Assert.assertEquals(5, root.left.right.data.intValue());
+ Assert.assertEquals(3, root.left.right.left.data.intValue());
+ }
+ @Test
+ public void testRemoveMiddleNode2() {
+ tree.remove(2);
+ BinaryTreeNode root= tree.getRoot();
+ Assert.assertEquals(3, root.left.data.intValue());
+ Assert.assertEquals(4, root.left.right.data.intValue());
+ }
+
+ @Test
+ public void testLevelVisit() {
+ List values = tree.levelVisit();
+ Assert.assertEquals("[6, 2, 8, 1, 4, 3, 5]", values.toString());
+
+ }
+ @Test
+ public void testLCA(){
+ Assert.assertEquals(2,tree.getLowestCommonAncestor(1, 5).intValue());
+ Assert.assertEquals(2,tree.getLowestCommonAncestor(1, 4).intValue());
+ Assert.assertEquals(6,tree.getLowestCommonAncestor(3, 8).intValue());
+ }
+ @Test
+ public void testIsValid() {
+
+ Assert.assertTrue(tree.isValid());
+
+ BinaryTreeNode root = new BinaryTreeNode(6);
+ root.left = new BinaryTreeNode(2);
+ root.right = new BinaryTreeNode