diff --git a/README.md b/README.md
index 6e976e4..730fe32 100644
--- a/README.md
+++ b/README.md
@@ -140,3 +140,11 @@ eg: [1,3,4,2,5]
2的小数:1
5的小数:1,3,4,2
小数和为:1+1+3+1+1+3+4+2
+
+### 前缀树
+1)单个字符串中,字符从前到后的加到一棵多叉树上
+2)字符放在边上,节点上有专属的数据项(常见的是pass和end值)
+3)样本添加方式,每个字符串都从根节点开始加,如果没有路就新建,如果有路就复用
+4)添加时,沿途节点的pass值加1,每个字符串结束时来到的节点end值加1
+
+end值可查某个字符串出现几次,pass值可查以某个字符串为前缀的字符串出现过几次
diff --git a/src/algorithm/NetherlandsFlag.java b/src/algorithm/NetherlandsFlag.java
new file mode 100644
index 0000000..35c8134
--- /dev/null
+++ b/src/algorithm/NetherlandsFlag.java
@@ -0,0 +1,57 @@
+package algorithm;
+
+/**
+ * 荷兰国旗问题的划分
+ * arr[L....R] 以arr[R]作为划分值
+ * arr[R]的在右侧
+ *
+ * @author Wen
+ * @date 2022/8/8 22:05
+ */
+public class NetherlandsFlag {
+
+ //返回划分过后=arr[R]的数的左边界和右边界
+ public int[] cal(int[] arr, int L, int R) {
+ if (L > R) {
+ return new int[]{-1, -1};
+ }
+ if (L == R) {
+ return new int[]{L, R};
+ }
+ int index = 0;
+ int less = 0;
+ int large = R;
+ int num = arr[R];
+ while (index <= large) {
+ if (arr[index] == num) {
+ index++;
+ continue;
+ }
+ if (arr[index] < num) {
+ int temp = arr[less];
+ arr[less] = arr[index];
+ arr[index] = temp;
+ less++;
+ index++;
+ continue;
+ }
+ if (arr[index] > num) {
+ int temp = arr[large];
+ arr[large] = arr[index];
+ arr[index] = temp;
+ large--;
+ }
+ }
+ return new int[]{less , large};
+ }
+
+ public static void main(String[] args) {
+ NetherlandsFlag netherlandsFlag = new NetherlandsFlag();
+ int[] source = new int[]{1, 3, 5, 6, 3, 4, 3, 4, 8, 3};
+ netherlandsFlag.cal(source, 0, 9);
+ for (int i : source) {
+ System.out.println(i);
+ }
+ }
+
+}
diff --git a/src/ds/tree/PrefixTree.java b/src/ds/tree/PrefixTree.java
new file mode 100644
index 0000000..fd31593
--- /dev/null
+++ b/src/ds/tree/PrefixTree.java
@@ -0,0 +1,109 @@
+package ds.tree;
+
+/**
+ * @author Wen
+ * @date 2022/8/22 22:26
+ */
+public class PrefixTree {
+ private Node head;
+
+ public PrefixTree() {
+ head = new Node();
+ }
+
+ //将字符串插入前缀树中
+ public void insert(String str) {
+ if (str == null) {
+ return;
+ }
+ Node node = head;
+ node.pass++;
+ char[] chars = str.toCharArray();
+ for (char aChar : chars) {
+ int index = aChar - 'a';//在哪个节点上
+ if (node.next[index] == null) {
+ node.next[index] = new Node();
+ }
+ node.next[index].pass++;
+ node = node.next[index];
+ }
+ node.end++;
+ }
+
+ //str出现过几次
+ public Integer search(String str) {
+ if (str == null) {
+ return 0;
+ }
+ Node node = head;
+ char[] chars = str.toCharArray();
+ for (char aChar : chars) {
+ int index = aChar - 'a';//在哪个节点上
+ if (node.next[index] == null) {
+ return 0;
+ }
+ node = node.next[index];
+ }
+ return node.end;
+ }
+
+ public void delete(String str) {
+ if (search(str) > 0) {
+ Node node = head;
+ node.pass--;
+ char[] chars = str.toCharArray();
+ for (char aChar : chars) {
+ int index = aChar - 'a';//在哪个节点上
+ if (--node.next[index].pass == 0) {//pass为0后,后面节点直接丢弃
+ node.next[index] = null;
+ return;
+ }
+ node = node.next[index];
+ }
+ node.end--;
+ }
+ }
+
+ //以prefix为前缀的字符串个数
+ public Integer prefixNumber(String prefix) {
+ if (prefix == null) {
+ return 0;
+ }
+ Node node = head;
+ char[] chars = prefix.toCharArray();
+ for (char aChar : chars) {
+ int index = aChar - 'a';//在哪个节点上
+ if (node.next[index] == null) {
+ return 0;
+ }
+ node = node.next[index];
+ }
+ return node.pass;
+ }
+
+ class Node {
+ int pass;
+ int end;
+ Node[] next;
+
+ public Node() {
+ this.pass = 0;
+ this.end = 0;
+ next = new Node[26];//假设字符串都是26个小写字母
+ }
+ }
+
+ public static void main(String[] args) {
+ PrefixTree prefixTree = new PrefixTree();
+ prefixTree.insert("abc");
+ prefixTree.insert("abc");
+ prefixTree.insert("eewd");
+ prefixTree.insert("adb");
+ prefixTree.insert("eewd");
+ prefixTree.insert("abs");
+ prefixTree.insert("eewd");
+ System.out.println(prefixTree.search("abc"));
+ System.out.println(prefixTree.search("eewd"));
+ System.out.println(prefixTree.prefixNumber("ab"));
+ }
+}