diff --git a/design/bridge/IPayMode.java b/design/bridge/IPayMode.java new file mode 100644 index 0000000..4a8b271 --- /dev/null +++ b/design/bridge/IPayMode.java @@ -0,0 +1,7 @@ +package design.bridge; + +public interface IPayMode { + + boolean security(String uId); + +} diff --git a/design/bridge/Pay.java b/design/bridge/Pay.java new file mode 100644 index 0000000..8b7b81d --- /dev/null +++ b/design/bridge/Pay.java @@ -0,0 +1,17 @@ +package design.bridge; + + + +import java.math.BigDecimal; + +public abstract class Pay { + + protected IPayMode payMode; + + public Pay(IPayMode payMode) { + this.payMode = payMode; + } + + public abstract String transfer(String uId, String tradeId, BigDecimal amount); + +} diff --git a/design/bridge/PayCypher.java b/design/bridge/PayCypher.java new file mode 100644 index 0000000..8e20f0b --- /dev/null +++ b/design/bridge/PayCypher.java @@ -0,0 +1,10 @@ +package design.bridge; + +public class PayCypher implements IPayMode{ + + public boolean security(String uId) { + System.out.println("密码支付,风控校验环境安全"); + return true; + } + +} diff --git a/design/bridge/PayFaceMode.java b/design/bridge/PayFaceMode.java new file mode 100644 index 0000000..c4d466d --- /dev/null +++ b/design/bridge/PayFaceMode.java @@ -0,0 +1,10 @@ +package design.bridge; + +public class PayFaceMode implements IPayMode{ + + public boolean security(String uId) { + System.out.println("人脸支付,风控校验脸部识别"); + return true; + } + +} diff --git a/design/bridge/PayFingerprintMode.java b/design/bridge/PayFingerprintMode.java new file mode 100644 index 0000000..3cc47d0 --- /dev/null +++ b/design/bridge/PayFingerprintMode.java @@ -0,0 +1,10 @@ +package design.bridge; + +public class PayFingerprintMode implements IPayMode{ + + public boolean security(String uId) { + System.out.println("指纹支付,风控校验指纹信息"); + return true; + } + +} diff --git a/design/bridge/Run.java b/design/bridge/Run.java new file mode 100644 index 0000000..103ca7e --- /dev/null +++ b/design/bridge/Run.java @@ -0,0 +1,15 @@ +package design.bridge; + +import java.math.BigDecimal; + +public class Run { + public static void main(String[] args) { + System.out.println("\r\n模拟测试场景;微信支付、人脸方式。"); + Pay wxPay = new WxPay(new PayFaceMode()); + wxPay.transfer("weixin_1092033111", "100000109893", new BigDecimal(100)); + + System.out.println("\r\n模拟测试场景;支付宝支付、指纹方式。"); + Pay zfbPay = new ZfbPay(new PayFingerprintMode()); + zfbPay.transfer("jlu19dlxo111","100000109894",new BigDecimal(100)); + } +} diff --git a/design/bridge/WxPay.java b/design/bridge/WxPay.java new file mode 100644 index 0000000..0ea56b0 --- /dev/null +++ b/design/bridge/WxPay.java @@ -0,0 +1,23 @@ +package design.bridge; + +import java.math.BigDecimal; + +public class WxPay extends Pay { + + public WxPay(IPayMode payMode) { + super(payMode); + } + + public String transfer(String uId, String tradeId, BigDecimal amount) { + System.out.println("模拟微信渠道支付划账开始。uId:" + uId + " tradeId:" + tradeId + " amount:" + amount); + boolean security = payMode.security(uId); + System.out.println("模拟微信渠道支付风控校验。uId:" + uId + " tradeId:" + tradeId + " security:" + security); + if (!security) { + System.out.println("模拟微信渠道支付划账拦截。uId:" + uId + " tradeId:" + tradeId + " amount:" + amount); + return "0001"; + } + System.out.println("模拟微信渠道支付划账成功。uId:" + uId + " tradeId:" + tradeId + " amount:" + amount); + return "0000"; + } + +} diff --git a/design/bridge/ZfbPay.java b/design/bridge/ZfbPay.java new file mode 100644 index 0000000..22b6f7e --- /dev/null +++ b/design/bridge/ZfbPay.java @@ -0,0 +1,23 @@ +package design.bridge; + +import java.math.BigDecimal; + +public class ZfbPay extends Pay { + + public ZfbPay(IPayMode payMode) { + super(payMode); + } + + public String transfer(String uId, String tradeId, BigDecimal amount) { + System.out.println("模拟支付宝渠道支付划账开始。uId:" + uId + " tradeId:" + tradeId + " amount:" + amount); + boolean security = payMode.security(uId); + System.out.println("模拟支付宝渠道支付风控校验。uId:" + uId + " tradeId:" + tradeId + " security:" + security); + if (!security) { + System.out.println("模拟支付宝渠道支付划账拦截。uId:" + uId + " tradeId:" + tradeId + " amount:" + amount); + return "0001"; + } + System.out.println("模拟支付宝渠道支付划账成功。uId:" + uId + " tradeId:" + tradeId + " amount:" + amount); + return "0000"; + } + +} diff --git a/design/build/Builder.java b/design/build/Builder.java new file mode 100644 index 0000000..f984892 --- /dev/null +++ b/design/build/Builder.java @@ -0,0 +1,24 @@ +package design.build; + +public class Builder { + public IMenu levelOne(Double area) { + return new DecorationPackageMenu(area, "豪华欧式") + .appendCeiling(new LevelTwoCeiling()) // 吊顶,二级顶 + .appendCoat(new DuluxCoat()) // 涂料,多乐士 + .appendFloor(new ShengXiangFloor()); // 地板,圣象 + } + + public IMenu levelTwo(Double area){ + return new DecorationPackageMenu(area, "轻奢田园") + .appendCeiling(new LevelTwoCeiling()) // 吊顶,二级顶 + .appendCoat(new LiBangCoat()) // 涂料,立邦 + .appendTile(new MarcoPoloTile()); // 地砖,马可波罗 + } + + public IMenu levelThree(Double area){ + return new DecorationPackageMenu(area, "现代简约") + .appendCeiling(new LevelOneCeiling()) // 吊顶,二级顶 + .appendCoat(new LiBangCoat()) // 涂料,立邦 + .appendTile(new DongPengTile()); // 地砖,东鹏 + } +} diff --git a/design/build/DecorationPackageMenu.java b/design/build/DecorationPackageMenu.java new file mode 100644 index 0000000..6ad0251 --- /dev/null +++ b/design/build/DecorationPackageMenu.java @@ -0,0 +1,64 @@ +package design.build; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; + +public class DecorationPackageMenu implements IMenu { + + private List list = new ArrayList(); // 装修清单 + private BigDecimal price = BigDecimal.ZERO; // 装修价格 + + private BigDecimal area; // 面积 + private String grade; // 装修等级;豪华欧式、轻奢田园、现代简约 + + private DecorationPackageMenu() { + } + + + public DecorationPackageMenu(Double area, String grade) { + this.area = new BigDecimal(area); + this.grade = grade; + } + + public IMenu appendCeiling(Matter matter) { + list.add(matter); + price = price.add(area.multiply(new BigDecimal("0.2")).multiply(matter.price())); + return this; + } + + public IMenu appendCoat(Matter matter) { + list.add(matter); + price = price.add(area.multiply(new BigDecimal("1.4")).multiply(matter.price())); + return this; + } + + public IMenu appendFloor(Matter matter) { + list.add(matter); + price = price.add(area.multiply(matter.price())); + return this; + } + + public IMenu appendTile(Matter matter) { + list.add(matter); + price = price.add(area.multiply(matter.price())); + return this; + } + + public String getDetail() { + + StringBuilder detail = new StringBuilder("\r\n-------------------------------------------------------\r\n" + + "装修清单" + "\r\n" + + "套餐等级:" + grade + "\r\n" + + "套餐价格:" + price.setScale(2, BigDecimal.ROUND_HALF_UP) + " 元\r\n" + + "房屋面积:" + area.doubleValue() + " 平米\r\n" + + "材料清单:\r\n"); + + for (Matter matter : list) { + detail.append(matter.scene()).append(":").append(matter.brand()).append("、").append(matter.model()).append("、平米价格:").append(matter.price()).append(" 元。\n"); + } + + return detail.toString(); + } + +} diff --git a/design/build/DerFloor.java b/design/build/DerFloor.java new file mode 100644 index 0000000..14432b9 --- /dev/null +++ b/design/build/DerFloor.java @@ -0,0 +1,27 @@ +package design.build; + +import java.math.BigDecimal; + +public class DerFloor implements Matter { + + public String scene() { + return "地板"; + } + + public String brand() { + return "德尔(Der)"; + } + + public String model() { + return "A+"; + } + + public BigDecimal price() { + return new BigDecimal(119); + } + + public String desc() { + return "DER德尔集团是全球领先的专业木地板制造商,北京2008年奥运会家装和公装地板供应商"; + } + +} diff --git a/design/build/DongPengTile.java b/design/build/DongPengTile.java new file mode 100644 index 0000000..5ae213c --- /dev/null +++ b/design/build/DongPengTile.java @@ -0,0 +1,27 @@ +package design.build; + +import java.math.BigDecimal; + +public class DongPengTile implements Matter { + + public String scene() { + return "地砖"; + } + + public String brand() { + return "东鹏瓷砖"; + } + + public String model() { + return "10001"; + } + + public BigDecimal price() { + return new BigDecimal(102); + } + + public String desc() { + return "东鹏瓷砖以品质铸就品牌,科技推动品牌,口碑传播品牌为宗旨,2014年品牌价值132.35亿元,位列建陶行业榜首。"; + } + +} diff --git a/design/build/DuluxCoat.java b/design/build/DuluxCoat.java new file mode 100644 index 0000000..b6ad62b --- /dev/null +++ b/design/build/DuluxCoat.java @@ -0,0 +1,27 @@ +package design.build; + +import java.math.BigDecimal; + +public class DuluxCoat implements Matter { + + public String scene() { + return "涂料"; + } + + public String brand() { + return "多乐士(Dulux)"; + } + + public String model() { + return "第二代"; + } + + public BigDecimal price() { + return new BigDecimal(719); + } + + public String desc() { + return "多乐士是阿克苏诺贝尔旗下的著名建筑装饰油漆品牌,产品畅销于全球100个国家,每年全球有5000万户家庭使用多乐士油漆。"; + } + +} diff --git a/design/build/IMenu.java b/design/build/IMenu.java new file mode 100644 index 0000000..64a4d23 --- /dev/null +++ b/design/build/IMenu.java @@ -0,0 +1,13 @@ +package design.build; + +public interface IMenu { + IMenu appendCeiling(Matter matter); // 吊顶 + + IMenu appendCoat(Matter matter); // 涂料 + + IMenu appendFloor(Matter matter); // 地板 + + IMenu appendTile(Matter matter); // 地砖 + + String getDetail(); // 明细 +} diff --git a/design/build/LevelOneCeiling.java b/design/build/LevelOneCeiling.java new file mode 100644 index 0000000..9b0ea2b --- /dev/null +++ b/design/build/LevelOneCeiling.java @@ -0,0 +1,27 @@ +package design.build; + +import java.math.BigDecimal; + +public class LevelOneCeiling implements Matter { + + public String scene() { + return "吊顶"; + } + + public String brand() { + return "装修公司自带"; + } + + public String model() { + return "一级顶"; + } + + public BigDecimal price() { + return new BigDecimal(260); + } + + public String desc() { + return "造型只做低一级,只有一个层次的吊顶,一般离顶120-150mm"; + } + +} \ No newline at end of file diff --git a/design/build/LevelTwoCeiling.java b/design/build/LevelTwoCeiling.java new file mode 100644 index 0000000..fece9dd --- /dev/null +++ b/design/build/LevelTwoCeiling.java @@ -0,0 +1,27 @@ +package design.build; + +import java.math.BigDecimal; + +public class LevelTwoCeiling implements Matter { + + public String scene() { + return "吊顶"; + } + + public String brand() { + return "装修公司自带"; + } + + public String model() { + return "二级顶"; + } + + public BigDecimal price() { + return new BigDecimal(850); + } + + public String desc() { + return "两个层次的吊顶,二级吊顶高度一般就往下吊20cm,要是层高很高,也可增加每级的厚度"; + } + +} diff --git a/design/build/LiBangCoat.java b/design/build/LiBangCoat.java new file mode 100644 index 0000000..e431b46 --- /dev/null +++ b/design/build/LiBangCoat.java @@ -0,0 +1,27 @@ +package design.build; + +import java.math.BigDecimal; + +public class LiBangCoat implements Matter { + + public String scene() { + return "涂料"; + } + + public String brand() { + return "立邦"; + } + + public String model() { + return "默认级别"; + } + + public BigDecimal price() { + return new BigDecimal(650); + } + + public String desc() { + return "立邦始终以开发绿色产品、注重高科技、高品质为目标,以技术力量不断推进科研和开发,满足消费者需求。"; + } + +} diff --git a/design/build/MarcoPoloTile.java b/design/build/MarcoPoloTile.java new file mode 100644 index 0000000..c64a865 --- /dev/null +++ b/design/build/MarcoPoloTile.java @@ -0,0 +1,27 @@ +package design.build; + +import java.math.BigDecimal; + +public class MarcoPoloTile implements Matter { + + public String scene() { + return "地砖"; + } + + public String brand() { + return "马可波罗(MARCO POLO)"; + } + + public String model() { + return "缺省"; + } + + public BigDecimal price() { + return new BigDecimal(140); + } + + public String desc() { + return "“马可波罗”品牌诞生于1996年,作为国内最早品牌化的建陶品牌,以“文化陶瓷”占领市场,享有“仿古砖至尊”的美誉。"; + } + +} diff --git a/design/build/Matter.java b/design/build/Matter.java new file mode 100644 index 0000000..d233a46 --- /dev/null +++ b/design/build/Matter.java @@ -0,0 +1,16 @@ +package design.build; + +import java.math.BigDecimal; + +public interface Matter { + String scene(); // 场景;地板、地砖、涂料、吊顶 + + String brand(); // 品牌 + + String model(); // 型号 + + BigDecimal price(); // 价格 + + String desc(); // 描述 + +} diff --git a/design/build/Run.java b/design/build/Run.java new file mode 100644 index 0000000..0a9939f --- /dev/null +++ b/design/build/Run.java @@ -0,0 +1,13 @@ +package design.build; + +public class Run { + public static void main(String[] args) { + Builder builder = new Builder(); + // 豪华欧式 + System.out.println(builder.levelOne(132.52D).getDetail()); + // 轻奢田园 + System.out.println(builder.levelTwo(98.25D).getDetail()); + // 现代简约 + System.out.println(builder.levelThree(85.43D).getDetail()); + } +} diff --git a/design/build/ShengXiangFloor.java b/design/build/ShengXiangFloor.java new file mode 100644 index 0000000..5d076d5 --- /dev/null +++ b/design/build/ShengXiangFloor.java @@ -0,0 +1,27 @@ +package design.build; + +import java.math.BigDecimal; + +public class ShengXiangFloor implements Matter { + + public String scene() { + return "地板"; + } + + public String brand() { + return "圣象"; + } + + public String model() { + return "一级"; + } + + public BigDecimal price() { + return new BigDecimal(318); + } + + public String desc() { + return "圣象地板是中国地板行业著名品牌。圣象地板拥有中国驰名商标、中国名牌、国家免检、中国环境标志认证等多项荣誉。"; + } + +} diff --git a/design/decorate/CompressionDecorator.java b/design/decorate/CompressionDecorator.java new file mode 100644 index 0000000..5ce5c83 --- /dev/null +++ b/design/decorate/CompressionDecorator.java @@ -0,0 +1,77 @@ +package design.decorate; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Base64; +import java.util.zip.Deflater; +import java.util.zip.DeflaterOutputStream; +import java.util.zip.InflaterInputStream; + +/** + * 压缩装饰 + * + * @author vayi + * @version 1.0 + * @date 2020/10/26 + */ +public class CompressionDecorator extends DataSourceDecorator { + private int compLevel = 6; + + public CompressionDecorator(DataSource source) { + super(source); + } + + public int getCompressionLevel() { + return compLevel; + } + + public void setCompressionLevel(int value) { + compLevel = value; + } + + @Override + public void writeData(String data) { + // 把传入进来的data进行压缩然后丢给父类处理 + super.writeData(compress(data)); + } + + @Override + public String readData() { + return decompress(super.readData()); + } + + private String compress(String stringData) { + byte[] data = stringData.getBytes(); + try { + ByteArrayOutputStream bout = new ByteArrayOutputStream(512); + DeflaterOutputStream dos = new DeflaterOutputStream(bout, new Deflater(compLevel)); + dos.write(data); + dos.close(); + bout.close(); + return Base64.getEncoder().encodeToString(bout.toByteArray()); + } catch (IOException ex) { + return null; + } + } + + private String decompress(String stringData) { + byte[] data = Base64.getDecoder().decode(stringData); + try { + InputStream in = new ByteArrayInputStream(data); + InflaterInputStream iin = new InflaterInputStream(in); + ByteArrayOutputStream bout = new ByteArrayOutputStream(512); + int b; + while ((b = iin.read()) != -1) { + bout.write(b); + } + in.close(); + iin.close(); + bout.close(); + return new String(bout.toByteArray()); + } catch (IOException ex) { + return null; + } + } +} diff --git a/design/decorate/DataSource.java b/design/decorate/DataSource.java new file mode 100644 index 0000000..f81791f --- /dev/null +++ b/design/decorate/DataSource.java @@ -0,0 +1,12 @@ +package design.decorate; + +/** + * 定义了读取和写入操作的通用数据接口 + */ +public interface DataSource { + + void writeData(String data); + + String readData(); + +} diff --git a/design/decorate/DataSourceDecorator.java b/design/decorate/DataSourceDecorator.java new file mode 100644 index 0000000..5159561 --- /dev/null +++ b/design/decorate/DataSourceDecorator.java @@ -0,0 +1,26 @@ +package design.decorate; + +/** + * 抽象基础装饰 + * + * @author vayi + * @version 1.0 + * @date 2020/10/26 + */ +public class DataSourceDecorator implements DataSource { + private DataSource wrapper; + + DataSourceDecorator(DataSource source) { + this.wrapper = source; + } + + @Override + public void writeData(String data) { + wrapper.writeData(data); + } + + @Override + public String readData() { + return wrapper.readData(); + } +} diff --git a/design/decorate/EncryptionDecorator.java b/design/decorate/EncryptionDecorator.java new file mode 100644 index 0000000..232a0db --- /dev/null +++ b/design/decorate/EncryptionDecorator.java @@ -0,0 +1,44 @@ +package design.decorate; + +import java.util.Base64; + +/** + * 加密装饰 + * + * @author vayi + * @version 1.0 + * @date 2020/10/26 + */ +public class EncryptionDecorator extends DataSourceDecorator { + + public EncryptionDecorator(DataSource source) { + super(source); + } + + @Override + public void writeData(String data) { + // 把传入进来的data进行加密然后丢给父类处理 + super.writeData(encode(data)); + } + + @Override + public String readData() { + return decode(super.readData()); + } + + private String encode(String data) { + byte[] result = data.getBytes(); + for (int i = 0; i < result.length; i++) { + result[i] += (byte) 1; + } + return Base64.getEncoder().encodeToString(result); + } + + private String decode(String data) { + byte[] result = Base64.getDecoder().decode(data); + for (int i = 0; i < result.length; i++) { + result[i] -= (byte) 1; + } + return new String(result); + } +} diff --git a/design/decorate/FileDataSource.java b/design/decorate/FileDataSource.java new file mode 100644 index 0000000..33e5b14 --- /dev/null +++ b/design/decorate/FileDataSource.java @@ -0,0 +1,41 @@ +package design.decorate; + +import java.io.*; + +/** + * 简单数据读写器 + * + * @author vayi + * @version 1.0 + * @date 2020/10/26 + */ +public class FileDataSource implements DataSource { + private String name; + + public FileDataSource(String name) { + this.name = name; + } + + @Override + public void writeData(String data) { + File file = new File(name); + try (OutputStream fos = new FileOutputStream(file)) { + fos.write(data.getBytes(), 0, data.length()); + } catch (IOException ex) { + System.out.println(ex.getMessage()); + } + } + + @Override + public String readData() { + char[] buffer = null; + File file = new File(name); + try (FileReader reader = new FileReader(file)) { + buffer = new char[(int) file.length()]; + reader.read(buffer); + } catch (IOException ex) { + System.out.println(ex.getMessage()); + } + return new String(buffer); + } +} diff --git a/design/decorate/Run.java b/design/decorate/Run.java new file mode 100644 index 0000000..5c41ec4 --- /dev/null +++ b/design/decorate/Run.java @@ -0,0 +1,33 @@ +package design.decorate; + +/** + * 描述 + * + * @author vayi + * @version 1.0 + * @date 2020/10/26 + */ +public class Run { + + /** + * 写入流程: 获取到data -> CompressionDecorator进行压缩 -> EncryptionDecorator进行加密 -> FileDataSource写入文本 + * 读取流程: FileDataSource读取文本内容 -> EncryptionDecorator进行解密 -> CompressionDecorator进行解压 + */ + public static void main(String[] args) { + String salaryRecords = "加解密逆向解码\n加解密逆向解码\n加解密逆向解码\n加解密逆向解码\n加解密逆向解码\n加解密逆向解码" + + "\n加解密逆向解码\n加解密逆向解码\n加解密逆向解码\n加解密逆向解码\n加解密逆向解码"; + DataSourceDecorator encoded = new CompressionDecorator( + new EncryptionDecorator( + new FileDataSource("out/OutputDemo.txt"))); + encoded.writeData(salaryRecords); + DataSource plain = new FileDataSource("out/OutputDemo.txt"); + + System.out.println("- Input ----------------"); + System.out.println(salaryRecords); + System.out.println("- Encoded --------------"); + System.out.println(plain.readData()); + System.out.println("- Decoded --------------"); + System.out.println(encoded.readData()); + } + +} diff --git a/design/dutyLink/AuditHandler.java b/design/dutyLink/AuditHandler.java new file mode 100644 index 0000000..2703984 --- /dev/null +++ b/design/dutyLink/AuditHandler.java @@ -0,0 +1,43 @@ +package design.dutyLink; + +/** + * 审单责任链中心 + * + * @author vayi + * @version 1.0 + * @date 2019/11/05 + */ +public abstract class AuditHandler { + + // 下一个处理者 + AuditHandler nextHandler; + + // 状态 + String status; + + public AuditHandler(String status) { + this.status = status; + } + + void setNextHandler(AuditHandler handler) { + this.nextHandler = handler; + } + + void handlerMessage(Order order) { + if (status.equalsIgnoreCase(order.status)) { + this.process(order); + } else { + if (nextHandler != null) { + nextHandler.handlerMessage(order); + } else { + System.out.println("[" + order.code + "]审单结束: 订单当前状态 -> " + order.status); + } + } + } + + /** + * 子类实现 + */ + abstract void process(Order order); + +} diff --git a/design/dutyLink/BomSplitHandler.java b/design/dutyLink/BomSplitHandler.java new file mode 100644 index 0000000..b53ec88 --- /dev/null +++ b/design/dutyLink/BomSplitHandler.java @@ -0,0 +1,21 @@ +package design.dutyLink; + +/** + * Bom拆分 + * + * @author vayi + * @version 1.0 + * @date 2019/11/05 + */ +public class BomSplitHandler extends AuditHandler { + + public BomSplitHandler() { + super("10"); + } + + @Override + void process(Order order) { + order.status = "10"; + System.out.println("[" + order.code + "]Bom拆分结束: 订单当前状态 -> " + order.status); + } +} diff --git a/design/dutyLink/InventoryAllocateHandler.java b/design/dutyLink/InventoryAllocateHandler.java new file mode 100644 index 0000000..c24c573 --- /dev/null +++ b/design/dutyLink/InventoryAllocateHandler.java @@ -0,0 +1,21 @@ +package design.dutyLink; + +/** + * 库存分配 + * + * @author vayi + * @version 1.0 + * @date 2019/11/05 + */ +public class InventoryAllocateHandler extends AuditHandler { + + public InventoryAllocateHandler() { + super("30"); + } + + @Override + void process(Order order) { + order.status = "30"; + System.out.println("[" + order.code + "]库存分配结束: 订单当前状态 -> " + order.status); + } +} diff --git a/design/dutyLink/LockOrderHandler.java b/design/dutyLink/LockOrderHandler.java new file mode 100644 index 0000000..945e11c --- /dev/null +++ b/design/dutyLink/LockOrderHandler.java @@ -0,0 +1,21 @@ +package design.dutyLink; + +/** + * 锁单 + * + * @author vayi + * @version 1.0 + * @date 2019/11/05 + */ +public class LockOrderHandler extends AuditHandler { + + public LockOrderHandler() { + super("0"); + } + + @Override + void process(Order order) { + order.status = "0"; + System.out.println("[" + order.code + "]锁单结束: 订单当前状态 -> " + order.status); + } +} diff --git a/design/dutyLink/Order.java b/design/dutyLink/Order.java new file mode 100644 index 0000000..076a45f --- /dev/null +++ b/design/dutyLink/Order.java @@ -0,0 +1,24 @@ +package design.dutyLink; + +/** + * 订单类 + * + * @author vayi + * @version 1.0 + * @date 2019/11/05 + */ +public class Order { + String code; + String name; + String status; + String qty; + String price; + + public Order(String code, String name, String status, String qty, String price) { + this.code = code; + this.name = name; + this.status = status; + this.qty = qty; + this.price = price; + } +} diff --git a/design/dutyLink/ReleaseOrderHandler.java b/design/dutyLink/ReleaseOrderHandler.java new file mode 100644 index 0000000..a1aff28 --- /dev/null +++ b/design/dutyLink/ReleaseOrderHandler.java @@ -0,0 +1,21 @@ +package design.dutyLink; + +/** + * 订单释放 + * + * @author vayi + * @version 1.0 + * @date 2019/11/05 + */ +public class ReleaseOrderHandler extends AuditHandler { + + public ReleaseOrderHandler() { + super("90"); + } + + @Override + void process(Order order) { + order.status = "90"; + System.out.println("[" + order.code + "]订单释放结束: 订单当前状态 -> " + order.status); + } +} diff --git a/design/dutyLink/Run.java b/design/dutyLink/Run.java new file mode 100644 index 0000000..8fb9469 --- /dev/null +++ b/design/dutyLink/Run.java @@ -0,0 +1,20 @@ +package design.dutyLink; + +/** + * 运行类 + * + * @author vayi + * @version 1.0 + * @date + */ +public class Run { + + public static void main(String[] args) { + Order order = new Order("LT-00001", "辣条", "30", "1", "1.2"); + AuditHandler lock = new LockOrderHandler(); + AuditHandler bomSplitHandler = new BomSplitHandler(); + lock.setNextHandler(bomSplitHandler); + lock.handlerMessage(order); + } + +} diff --git a/design/state/Register.java b/design/state/Register.java new file mode 100644 index 0000000..e1c4681 --- /dev/null +++ b/design/state/Register.java @@ -0,0 +1,49 @@ +package design.state; + +import design.state.domain.OrderAuditStep; +import design.state.step.IOrderStep; + +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.util.Enumeration; + +/** + * 注册中心 + * + * @author vayi + * @version 1.0 + * @date 2020-03-15 + */ +public class Register { + static final String PACKAGE = "design.state.step"; + + static void register() { + // 反射获取注解标记类 + Enumeration urls = null; + try { + urls = Thread.currentThread().getContextClassLoader().getResources(PACKAGE.replace(".", "/")); + while (urls.hasMoreElements()) { + URL url = urls.nextElement(); + if ("file".equalsIgnoreCase(url.getProtocol())) { + File file = new File(url.getPath()); + if (file.isDirectory()) { + File[] files = file.listFiles(); + for (File fl : files) { + String className = fl.getName(); + className = className.substring(0, className.lastIndexOf(".")); + Class clazz = Thread.currentThread().getContextClassLoader().loadClass(PACKAGE + "." + className); + // 添加到缓存 + OrderAuditStep annotation = clazz.getAnnotation(OrderAuditStep.class); + if (annotation != null) { + IOrderStep.AUDIT_STEP.put(annotation.state().getState(), (IOrderStep) clazz.newInstance()); + } + } + } + } + } + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/design/state/Run.java b/design/state/Run.java new file mode 100644 index 0000000..3e93865 --- /dev/null +++ b/design/state/Run.java @@ -0,0 +1,31 @@ +package design.state; + +import design.singleton.EnumSingleton; +import design.singleton.HungerSingleton; +import design.singleton.LazySingleton; +import design.state.domain.AuditContext; +import design.state.domain.OrderAuditStep; +import design.state.step.IOrderStep; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * 状态模式 + */ +public class Run { + + static { + Register.register(); + } + + public static void main(String[] args) { + List list = Stream.of(100, 200, 300, 900).collect(Collectors.toList()); + list.forEach(s -> { + IOrderStep orderStep = IOrderStep.AUDIT_STEP.get(s); + orderStep.audit(); + }); + } +} diff --git a/design/state/domain/AuditContext.java b/design/state/domain/AuditContext.java new file mode 100644 index 0000000..16660d6 --- /dev/null +++ b/design/state/domain/AuditContext.java @@ -0,0 +1,18 @@ +package design.state.domain; + +import design.state.domain.State; + +import java.util.ArrayList; +import java.util.List; + +/** + * 审单上下文 + * + * @author vayi + * @version 1.0 + * @date 2020-03-15 + */ +public class AuditContext { + public List orders = new ArrayList<>(); + public State state = null; +} diff --git a/design/state/domain/OrderAuditStep.java b/design/state/domain/OrderAuditStep.java new file mode 100644 index 0000000..0535af4 --- /dev/null +++ b/design/state/domain/OrderAuditStep.java @@ -0,0 +1,12 @@ +package design.state.domain; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface OrderAuditStep { + State state() default State.LOCK; +} diff --git a/design/state/domain/State.java b/design/state/domain/State.java new file mode 100644 index 0000000..26c948c --- /dev/null +++ b/design/state/domain/State.java @@ -0,0 +1,31 @@ +package design.state.domain; + +/** + * 状态 + * + * @author vayi + * @version 1.0 + * @date 2019/11/05 + */ +public enum State { + LOCK(100, "锁定"), + SOURCING(200, "匹仓"), + ALLOCATE(300, "库存分配"), + RELEASE(900, "释放"); + + private int state; + private String name; + + public int getState() { + return this.state; + } + + public String getName() { + return this.name; + } + + State(int state, String name) { + this.state = state; + this.name = name; + } +} diff --git a/design/state/step/IOrderStep.java b/design/state/step/IOrderStep.java new file mode 100644 index 0000000..0f79c59 --- /dev/null +++ b/design/state/step/IOrderStep.java @@ -0,0 +1,34 @@ +package design.state.step; + +import design.state.domain.AuditContext; +import design.state.domain.OrderAuditStep; + +import java.util.HashMap; +import java.util.Map; + +public abstract class IOrderStep { + public static Map AUDIT_STEP = new HashMap<>(); + + /** + * 审单上下文 + */ + public AuditContext context = new AuditContext(); + + public void audit() { + processBegin(this.context); + this.process(this.context); + processAfter(this.context); + } + + protected void processBegin(AuditContext context) { + context.state = this.getClass().getAnnotation(OrderAuditStep.class).state(); + System.out.println("当前审单节点【" + context.state.getName() + "】 状态为【" + context.state.getState() + "】"); + } + + protected void processAfter(AuditContext context) { + System.out.println("当前审单节点【" + context.state.getName() + "】 完成"); + } + + abstract void process(AuditContext context); + +} diff --git a/design/state/step/OrderAllocateStep.java b/design/state/step/OrderAllocateStep.java new file mode 100644 index 0000000..7d0d8d6 --- /dev/null +++ b/design/state/step/OrderAllocateStep.java @@ -0,0 +1,20 @@ +package design.state.step; + +import design.state.domain.AuditContext; +import design.state.domain.OrderAuditStep; +import design.state.domain.State; + +/** + * 匹仓的单子处理 + * + * @author vayi + * @version 1.0 + * @date 2020-03-15 + */ +@OrderAuditStep(state = State.ALLOCATE) +public class OrderAllocateStep extends IOrderStep { + @Override + public void process(AuditContext context) { + + } +} diff --git a/design/state/step/OrderLockStep.java b/design/state/step/OrderLockStep.java new file mode 100644 index 0000000..a540d4e --- /dev/null +++ b/design/state/step/OrderLockStep.java @@ -0,0 +1,20 @@ +package design.state.step; + +import design.state.domain.AuditContext; +import design.state.domain.OrderAuditStep; +import design.state.domain.State; + +/** + * 锁定的单子处理 + * + * @author vayi + * @version 1.0 + * @date 2020-03-15 + */ +@OrderAuditStep(state = State.LOCK) +public class OrderLockStep extends IOrderStep { + @Override + public void process(AuditContext context) { + + } +} diff --git a/design/state/step/OrderReleaseStep.java b/design/state/step/OrderReleaseStep.java new file mode 100644 index 0000000..2400e5a --- /dev/null +++ b/design/state/step/OrderReleaseStep.java @@ -0,0 +1,20 @@ +package design.state.step; + +import design.state.domain.AuditContext; +import design.state.domain.OrderAuditStep; +import design.state.domain.State; + +/** + * 释放的单子处理 + * + * @author vayi + * @version 1.0 + * @date 2020-03-15 + */ +@OrderAuditStep(state = State.RELEASE) +public class OrderReleaseStep extends IOrderStep { + @Override + public void process(AuditContext context) { + + } +} diff --git a/design/state/step/OrderSourcingStep.java b/design/state/step/OrderSourcingStep.java new file mode 100644 index 0000000..55615f0 --- /dev/null +++ b/design/state/step/OrderSourcingStep.java @@ -0,0 +1,20 @@ +package design.state.step; + +import design.state.domain.AuditContext; +import design.state.domain.OrderAuditStep; +import design.state.domain.State; + +/** + * 寻源的单子处理 + * + * @author vayi + * @version 1.0 + * @date 2020-03-15 + */ +@OrderAuditStep(state = State.SOURCING) +public class OrderSourcingStep extends IOrderStep { + @Override + public void process(AuditContext context) { + + } +} diff --git a/io/BIO/TelnetServer.java b/io/BIO/TelnetServer.java new file mode 100644 index 0000000..673621f --- /dev/null +++ b/io/BIO/TelnetServer.java @@ -0,0 +1,62 @@ +package io.BIO; + +import java.io.IOException; +import java.io.InputStream; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +/** + * Telnet 服务 + */ +public class TelnetServer { + + /** + * 执行对应链接的线程池 + */ + protected static ExecutorService executorService = Executors.newCachedThreadPool(); + + public static void main(String[] args) throws Exception { + ServerSocket server = new ServerSocket(6666); + + while (true) { + System.out.println("等待客户端链接..."); + final Socket socket = server.accept(); + System.out.println("客户端接入成功"); + executorService.execute(new Runnable() { + @Override + public void run() { + handler(socket); + } + }); + } + } + + /** + * 处理接入的请求 + * @param socket + */ + private static void handler(Socket socket) { + InputStream inputStream = null; + byte[] bytes = new byte[1024]; + try { + inputStream = socket.getInputStream(); + System.out.println("数据接收..."); + while (inputStream.read(bytes) != -1) { + System.out.println("接收数据: " + new String(bytes)); + } + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (socket != null) { + try { + socket.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } + +} diff --git a/leetcode/linkTable/ProjectAnalysis.java b/leetcode/linkTable/ProjectAnalysis.java new file mode 100644 index 0000000..0303e8d --- /dev/null +++ b/leetcode/linkTable/ProjectAnalysis.java @@ -0,0 +1,106 @@ +package leetcode.linkTable; +import java.util.*; +import java.util.stream.Collectors; + +public class ProjectAnalysis { + + static class Transition { + int uniqueId; + int projectNumber; + String in, out; + + Transition(int uniqueId, int projectNumber, String in, String out) { + this.uniqueId = uniqueId; + this.projectNumber = projectNumber; + this.in = in; + this.out = out; + } + } + + public static void main(String[] args) { + List data = Arrays.asList( + new Transition(1, 1, "A", "B"), new Transition(2, 2, "H", "I"), + new Transition(3, 1, "C", "D"), new Transition(4, 1, "B", "C"), + new Transition(5, 2, "G", "H"), new Transition(6, 3, "M", "N"), + new Transition(7, 4, "Y", "Z"), new Transition(8, 3, "N", "O"), + new Transition(9, 4, "X", "Y"), new Transition(10, 1, "E", "F"), + new Transition(11, 5, "S", "T"), new Transition(12, 5, "T", "U"), + new Transition(13, 5, "U", "S"), new Transition(14, 6, "V", "W"), + new Transition(15, 6, "W", "W1"), new Transition(16, 6, "W1", "W2"), + new Transition(17, 6, "W2", "W") + ); + + Map> projects = new TreeMap<>(); + for (Transition t : data) { + projects.computeIfAbsent(t.projectNumber, k -> new ArrayList<>()).add(t); + } + + // Sorting transitions within each project by unique ID + for (List list : projects.values()) { + list.sort(Comparator.comparingInt(t -> t.uniqueId)); + } + + // Analyzing each project and printing the result + for (Map.Entry> entry : projects.entrySet()) { + int projectNumber = entry.getKey(); + List transitions = entry.getValue(); + System.out.println("项目" + projectNumber + ": " + analyzeProject(transitions)); + } + } + + private static String analyzeProject(List transitions) { + Map map = new HashMap<>(); + Set allNodes = new HashSet<>(); + + for (Transition t : transitions) { + map.put(t.in, t.out); + allNodes.add(t.in); + allNodes.add(t.out); + } + + Set visited = new HashSet<>(); + List chains = new ArrayList<>(); + boolean hasCycle = false; + Set cycleNodes = new HashSet<>(); + + // Detect all chains and cycles + for (String node : allNodes) { + if (!visited.contains(node) && map.containsKey(node)) { + List path = new ArrayList<>(); + Set pathNodes = new HashSet<>(); + String current = node; + while (current != null && !pathNodes.contains(current)) { + pathNodes.add(current); + path.add(current); + current = map.get(current); + } + if (current != null && pathNodes.contains(current)) { + hasCycle = true; // A cycle is detected + int index = path.indexOf(current); + List cycle = path.subList(index, path.size()); + cycle.add(current); + chains.add("Cycle: " + String.join(" -> ", cycle)); + cycleNodes.addAll(cycle); + } else { + chains.add("Chain: " + String.join(" -> ", path)); + } + visited.addAll(pathNodes); + } + } + + // Determine if it's a full cycle, partial cycle or just chains + if (hasCycle) { + if (cycleNodes.size() < allNodes.size()) { + return "中心成圈: " + chains.stream().filter(s -> s.startsWith("Cycle")).findFirst().orElse(""); + } else { + return "成圈: " + chains.stream().filter(s -> s.startsWith("Cycle")).findFirst().orElse(""); + } + } else { + if (chains.size() > 1) { + return "成链但不全,存在多条链: " + chains.stream().filter(s -> s.startsWith("Chain")).collect(Collectors.joining(", ")); + } else { + return "成链: " + chains.get(0); + } + } + } +} diff --git a/sort/BubbleSort.java b/sort/BubbleSort.java index 7e52271..efabeb5 100644 --- a/sort/BubbleSort.java +++ b/sort/BubbleSort.java @@ -2,6 +2,13 @@ /** * 冒泡排序 + * 重复地走访过要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。走访数列的工作是重复地进行直到没有再需要交换 + *

+ * 1、初始状态:无序区为R[1..n],有序区为空 + * 2、第i趟排序(i=0,1,2…n-1)开始时,当前无序区和有序区分别为R[0..n-i]和R[n-i+1..n]。 + * 对每一对相邻元素进行比较,从开始第一对到结尾的最后一对,如果第一个比第二个大,就交换它们两个,这样在最后的元素应该会是最大的数 + * 使R[1..n-i-1]和R[n-i..n]分别变为记录个数减少1个的新无序区和记录个数增加1个的新有序区 + * 3、循环n-1次,直到排序完成 */ public class BubbleSort { diff --git a/sort/FastSort.java b/sort/FastSort.java index 9d10b86..aa10057 100644 --- a/sort/FastSort.java +++ b/sort/FastSort.java @@ -2,12 +2,67 @@ /** * 快速排序 + * 通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序 + *

+ * 1、从数列中挑出一个元素,称为 “基准”(pivot) + * 2、重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。 + * 在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作 + * 3、递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序 */ public class FastSort { public static void main(String[] args) { - int A[] = {5, 2, 9, 4, 7, 6, 1, 3, 8}; -// int n = sizeof(A) / 1; + int[] a = {5, 2, 9, 4, 7, 6, 1, 3, 8}; + sort(a, 0, a.length - 1); + for (int i : a) { + System.out.print(i + " "); + } } + /** + * 递归进行快速排序 + */ + private static void sort(int[] a, int left, int right) { + if (right <= left) { //排序从左到右,确保右边比左边大 + return; + } + int j = partition(a, left, right); //切分 + sort(a, left, j - 1); //将左半边排序 + sort(a, j + 1, right); //将右半边排序 + } + + /** + * 快速排序切分 + */ + private static int partition(int[] a, int left, int right) { + int i = left, j = right + 1; //左右扫描指针 + int v = a[left]; //选取切分元素,这里选第一个,实际数据可以自行挑选 + while (true) { + while (a[++i] < v) { //a[i]< a[--j]){ //a[j]>v时减小j,只要比v大继续往左扫描 + if (j == left) { //扫描到左边则终止 + break; + } + } + while (v < a[--j]) { //a[j]>v时减小j,只要比v大继续往左扫描 + if (j == left) { //扫描到左边则终止 + break; + } + } + if (i >= j) { //如果左右指针交叉,终止循环 + break; + } + exch(a, i, j); //不满足上述条件(左边比v大,右边比v小,指针未交叉),左右元素交换位置 + } + exch(a, left, j); //将切分元素v放入正确的位置 + return j; //a[left..j-1]<=a[j]<=a[j+1..right],并返回j + } + + /** + * 交换两个元素 + */ + private static void exch(int[] a, int i, int j) { + int temp = a[i]; + a[i] = a[j]; + a[j] = temp; + } } diff --git a/sort/HeapSort.java b/sort/HeapSort.java new file mode 100644 index 0000000..6032235 --- /dev/null +++ b/sort/HeapSort.java @@ -0,0 +1,56 @@ +package sort; + +/** + * 堆排序 + * 堆就是完全二叉树,分为最大堆和最小堆,最大堆要求节点的元素都要不小于其孩子(最小堆要求节点元素都不大于其左右孩子),对左右孩子的大小关系不做要求 + * 所以处于最大堆的根节点的元素一定是这个堆中的最大值。堆排序算法就是抓住了堆的这一特点,每次都取堆顶的元素,将其放在序列最后面,然后将剩余的元素重新调整为最大堆,依次类推,最终得到排序的序列 + *

+ * 1、将初始待排序关键字序列(R1,R2….Rn)构造成最大堆,此堆为初始的无序区 + * 2、将堆顶元素R[1]与最后一个元素R[n]交换,此时得到新的无序区(R1,R2,……Rn-1)和新的有序区(Rn),且满足R[1,2…n-1]<=R[n] + * 3、由于交换后新的堆顶R[1]可能违反堆的性质,因此需要对当前无序区(R1,R2,……Rn-1)调整为新堆,然后再次将R[1]与无序区最后一个元素交换,得到新的无序区(R1,R2….Rn-2)和新的有序区(Rn-1,Rn)。 + * 不断重复此过程直到有序区的元素个数为n-1,则整个排序过程完成 + */ +public class HeapSort { + + public static void main(String[] args) { + int[] a = {5, 2, 9, 4, 7, 6, 1, 3, 8}; + int N = a.length; + for (int k = N / 2; k >= 1; k--) { //for循环用来构造堆,最终生成最大堆 + sink(a, k, N); + } + while (N > 1) { //循环排序无序区 + exch(a, 1, N--); //堆顶a[1]与堆的最后一个元素a[N]交换位置,并且去掉最后一个元素到有序区,减小新堆 + sink(a, 1, N); //重新生成为最大堆 + } + for (int i : a) { + System.out.print(i + " "); + } + } + + /** + * 从上至下堆有序化 + */ + private static void sink(int[] a, int k, int N) { + while (2 * k <= N) { + int j = 2 * k; + if (j < N && a[j] < a[j + 1]) { //j= a[j]) { //如果父节点大于等于值大的子节点,堆有序,终止循环 + break; + } + if (a[k] >= a[j]) { //如果父节点大于等于值大的子节点,堆有序,终止循环 + break; + } + exch(a, k, j); //交换值大的子节点和父节点的值,达到堆有序 + k = j; //子节点,作为下一个循环的父节点,继续下沉 + } + } + + /** + * 交换两个元素 + */ + private static void exch(int[] a, int i, int j) { + int temp = a[i]; + a[i] = a[j]; + a[j] = temp; + } + +} diff --git a/sort/InsertionSort.java b/sort/InsertionSort.java new file mode 100644 index 0000000..a118586 --- /dev/null +++ b/sort/InsertionSort.java @@ -0,0 +1,32 @@ +package sort; + +/** + * 插入排序 + * 对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入 + *

+ * 1、从第一个元素开始,该元素认为已经被排序 + * 2、取出下一个元素,在已排序的元素序列中从后向前扫描 + * 3、如果已排序元素大于新元素,新元素继续比较前一个元素,直到找到已排序的元素小于或者等于新元素的位置 + * 4、将新元素插入到该位置后 + * 5、重复步骤2~4 + */ +public class InsertionSort { + + public static void main(String[] args) { + int[] a = {5, 2, 9, 4, 7, 6, 1, 3, 8}; + int insertIndex, insertElement; + for (int i = 1; i < a.length; i++) { //外层循环,默认第一个元素有序,从第二个元素开始,时间复杂度N + insertIndex = i - 1; //插入的位置,默认有序数列的最后一个元素的位置 + insertElement = a[i]; //新插入的元素,默认外层循环的元素 + while (insertIndex >= 0 && a[insertIndex] > insertElement) { //内层循环,只要新元素比待插入位置的元素小就继续,时间复杂度N + a[insertIndex + 1] = a[insertIndex]; //比待插入元素大的元素后移一位 + insertIndex--; //插入位置前移一位 + } + a[insertIndex + 1] = insertElement; //内层循环结束,把新元素放到插入位置后面 + } + for (int i : a) { + System.out.print(i + " "); + } + } + +} diff --git a/sort/MergeSort.java b/sort/MergeSort.java new file mode 100644 index 0000000..a675f16 --- /dev/null +++ b/sort/MergeSort.java @@ -0,0 +1,58 @@ +package sort; + +/** + * 堆排序 + * 递归的把已有序列均分为两个子序列,使子序列有序,合并子序列 + *

+ * 1、把长度为n的输入序列分成两个长度为n/2的子序列 + * 2、对这两个子序列分别采用归并排序 + * 3、将两个排序好的子序列合并成一个最终的排序序列 + */ +public class MergeSort { + + private static int[] aux; //归并所需的辅助数组 + + public static void main(String[] args) { + int[] a = {5, 2, 9, 4, 7, 6, 1, 3, 8}; + aux = new int[a.length]; + sort(a, 0, a.length - 1); //开始递归排序 + for (int i : a) { + System.out.print(i + " "); + } + } + + /** + * 递归的排序归并 + */ + private static void sort(int[] a, int left, int right) { + if (right <= left) { //排序从左到右,确保右边比左边大 + return; + } + int mid = (left + right) / 2; //找出中间位置 + sort(a, left, mid); //将左半边排序 + sort(a, mid + 1, right); //将右半边排序 + merge(a, left, mid, right); //归并结果 + } + + /** + * 原地归并方法 + */ + private static void merge(int[] a, int left, int mid, int right) { //将a[left..mid]和a[mid+1..right]归并 + int i = left, j = mid + 1; //左右半边起始位置 + for (int k = left; k <= right; k++) { //将a[left..right]复制到aux[left..right] + aux[k] = a[k]; + } + for (int k = left; k <= right; k++) { //归并回到a[left..right] + if (i > mid) { //i比mid大代表左半边用完,只有右半边有元素 + a[k] = aux[j++]; //右边元素给a[k] + } else if (j > right) { //j比right大代表右半边用完,只有左半边有元素 + a[k] = aux[i++]; //左边元素给a[k] + } else if (aux[j] < aux[i]) { //如果右边元素大于左边 + a[k] = aux[j++]; //右边元素给a[k] + } else { //否则左边大于等于右边 + a[k] = aux[i++]; //左边元素给a[k] + } + } + } + +} diff --git a/sort/SelectionSort.java b/sort/SelectionSort.java new file mode 100644 index 0000000..8385c82 --- /dev/null +++ b/sort/SelectionSort.java @@ -0,0 +1,34 @@ +package sort; + +/** + * 选择排序 + * 在未排序序列中找到最小元素,放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小元素 + * 然后放到已排序序列的末尾,循环直到所有元素均排序完毕。 + *

+ * 1、初始状态:无序区为R[1..n],有序区为空 + * 2、第i趟排序(i=1,2,3…n-1)开始时,当前有序区和无序区分别为R[1..i-1]和R[i..n] + * 该趟排序从当前无序区中选出最小的记录 R[k],将它与无序区的第1个记录R[i]交换,使R[1..i]和R[i+1..n]分别变为记录个数增加1个的新有序区和记录个数减少1个的新无序区 + * 3、循环n-1次,排序完成 + */ +public class SelectionSort { + + public static void main(String[] args) { + int[] a = {5, 2, 9, 4, 7, 6, 1, 3, 8}; + int minIndex, temp; + for (int i = 0; i < a.length - 1; i++) { //外层循环,从无序区第一个元素开始到数组倒数第二个元素,时间复杂度N + minIndex = i; //每次外层循环假设无序区第一个元素是最小元素 + for (int j = i + 1; j < a.length; j++) { //内层循环,从假设的最小元素的后一个位置开始,到数组最后一个元素,时间复杂度N + if (a[j] < minIndex) { //判断内层循环的元素是否小于假设的最小元素 + minIndex = j; //如果比最小元素小,标记该元素的位置为新的最小元素的位置,内层循环完毕,会找出无序区的最小值 + } + } + temp = a[i]; + a[i] = a[minIndex]; + a[minIndex] = temp; //无序区真正最小值和第一个元素交换位置,下一次循环无序区从下一个值开始 + } + for (int i : a) { + System.out.print(i + " "); + } + } + +} diff --git a/sort/ShellSort.java b/sort/ShellSort.java new file mode 100644 index 0000000..2b4b6cd --- /dev/null +++ b/sort/ShellSort.java @@ -0,0 +1,38 @@ +package sort; + +/** + * 希尔排序 + * 插入排序的改进版,优先比较距离远的元素,减少交换次数 + *

+ * 1、选择一个增量序列t1,t2,…,tk,其中ti>tj,tk=1 + * 2、按增量序列个数k,对序列进行k 趟排序 + * 3、每趟排序,根据对应的增量ti,将待排序列分割成若干长度为m 的子序列,分别对各子表进行直接插入排序。 + * 仅增量因子为1 时,整个序列作为一个表来处理,表长度即为整个序列的长度 + */ +public class ShellSort { + + public static void main(String[] args) { + int[] a = {5, 2, 9, 4, 7, 6, 1, 3, 8}; + int h = 1; //希尔排序是使间隔为h的元素有序 + int insertIndex, insertElement; + while (h < a.length / 3) { //while循环,扩大h + h = 3 * h + 1; //这里用3倍作为希尔排序的间隔,是常用的值,加1是为了防止排序的都是3的倍数 + } + while (h >= 1) { //while循环让h从大到小插入排序 + for (int i = h; i < a.length; i++) { //从h位置开始,对整个数组遍历,i为插入元素的位置 + insertIndex = i - h; //插入的位置,默认前面间隔h的位置 + insertElement = a[i]; //新插入的元素,默认外层循环的最后一个元素 + while (insertIndex >= 0 && a[insertIndex] > insertElement) { //内层循环,只要新元素比待插入位置的元素小就继续 + a[insertIndex + h] = a[insertIndex]; //比待插入元素大的元素后移h位 + insertIndex -= h; //插入位置前移h位 + } + a[insertIndex + h] = insertElement; //内层循环结束,把新元素放到插入位置后面 + } + h = h / 3; //更大间隔的插入完成,缩小插入间隔 + } + for (int i : a) { + System.out.print(i + " "); + } + } + +}