文章目录
- 一、稀疏数组
-
- 二、队列
-
- 三、链表
- 3.1 链表介绍
- 3.2 单链表的应用实例
- 3.3 单链表面试题
- 3.4 双向链表应用实例
- 3.5 单向环形链表
- 四、栈
- 4.1 基本介绍
- 4.2 数组模拟栈
- 4.3 链表模拟栈
- 4.4 栈实现综合计算器
- 4.5 前缀、中缀、后缀表达式(逆波兰表达式)
- 4.6 逆波兰计算器实现
- 4.7 中缀表达式转后缀表达式(*)
- 五、递归
- 5.1 递归的应用场景
- 5.2 递归的调用机制
- 5.3 递归可以解决的问题
- 5.4 递归需要遵守的重要规则
- 5.5 迷宫问题
- 5.6 八皇后问题
一、稀疏数组
1.1 实际需求

1.2 基本介绍


1.3 应用实例


package com.gyh.sparsearray;import java.util.Arrays;
public class SparseArray {public static void main(String[] args) {int[][] chessArr = new int[11][11];chessArr[1][2] = 1;chessArr[2][3] = 2;chessArr[5][6] = 2;for (int[] cRaw : chessArr) {for (int c : cRaw) {System.out.print(c + "\t");}System.out.println();}int[][] ints = ToSparseArray(chessArr, 0);for (int[] cRaw : ints) {for (int c : cRaw) {System.out.print(c + "\t");}System.out.println();}int[][] ints1 = restoreArray(ints, 0);for (int[] cRaw : ints1) {for (int c : cRaw) {System.out.print(c + "\t");}System.out.println();}}public static int[][] restoreArray(int[][] sparseArray, int defaultValue) {int[][] ints = new int[sparseArray[0][0]][sparseArray[0][1]];for (int[] anInt : ints) {Arrays.fill(anInt, defaultValue);}for (int i = 1; i < sparseArray.length; i++) {ints[sparseArray[i][0]][sparseArray[i][1]] = sparseArray[i][2];}return ints;}public static int[][] ToSparseArray(int[][] arr, int defaultValue) {int sum = 0;for (int i = 0; i < arr.length; i++) {for (int j = 0; j < arr[i].length; j++) {if (arr[i][j] == defaultValue) continue;sum++;}}int raw = 1;int[][] SparseArray = new int[sum + 1][3];SparseArray[0][0] = arr.length;SparseArray[0][1] = arr[0].length;SparseArray[0][2] = sum;for (int i = 0; i < arr.length; i++) {for (int j = 0; j < arr[i].length; j++) {if (arr[i][j] == defaultValue) continue;SparseArray[raw][0] = i;SparseArray[raw][1] = j;SparseArray[raw][2] = arr[i][j];raw++;}}return SparseArray;}
}
二、队列
2.1 引入

2.2 基本介绍

2.3 数组模拟队列


- 注:队列中
front
指向队首元素的前面一个位置,rear
指向队尾元素, maxSize
表示队列的最大容量
package com.gyh.queue;
public class Queue {public static void main(String[] args) {ArrayQueue arrayQueue = new ArrayQueue(5);arrayQueue.addQueue(1);arrayQueue.addQueue(2);arrayQueue.addQueue(3);arrayQueue.addQueue(4);arrayQueue.addQueue(5);arrayQueue.getQueue();arrayQueue.getQueue();arrayQueue.getQueue();arrayQueue.getQueue();arrayQueue.getQueue();arrayQueue.addQueue(6);}
}
class ArrayQueue {private int maxSize; private int front = -1; private int rear = -1; private int[] arr; public ArrayQueue(int maxSize) {this.maxSize = maxSize;arr = new int[maxSize]; }public boolean isFull() {return rear == maxSize - 1;}public boolean isEmpty() {return front == rear;}public void addQueue(int data) {if (isFull()) {System.out.println("队列满不能加入数据");return;}arr[++rear] = data;}public int getQueue(){if(isEmpty()){System.out.println("队列已空");throw new ArrayIndexOutOfBoundsException("队列为空");}return arr[++front];}public void showQueue(){if(isEmpty()){System.out.println("队列为空");return;}for (int i : arr) {System.out.println(i);}}}


package com.gyh.queue;
public class ArrayQueue2 {public static void main(String[] args) {AnnularArrayQueue annularArrayQueue = new AnnularArrayQueue(5);annularArrayQueue.addQueue(1);annularArrayQueue.addQueue(2);annularArrayQueue.addQueue(3);annularArrayQueue.addQueue(4);annularArrayQueue.getQueue();annularArrayQueue.getQueue();annularArrayQueue.getQueue();annularArrayQueue.addQueue(5);annularArrayQueue.addQueue(6);annularArrayQueue.addQueue(7);annularArrayQueue.showQueue();}
}class AnnularArrayQueue {private final int MAX_SIZE;private int front = 0; private int rear = 0; private int[] arr;public AnnularArrayQueue(int maxSize) {this.MAX_SIZE = maxSize;arr = new int[maxSize];}public int getQueueLength() {return (rear - front + MAX_SIZE) % MAX_SIZE;}public boolean isFull() {return (rear + 1) % MAX_SIZE == front;}public boolean isEmpty() {return front == rear;}public void addQueue(int data) {if (isFull()) {System.out.println("队列已满");return;}arr[rear] = data;rear = (rear + 1) % MAX_SIZE;}public int getQueue() {if (isEmpty()) {throw new ArrayIndexOutOfBoundsException("队列已空");}int data = arr[front];front = (front + 1) % MAX_SIZE;return data;}public void showQueue() {if (isEmpty()) {System.out.println("队列为空");return;}if (rear > front) {for (int i = front; i < rear; i++) {System.out.println(arr[i]);}} else {for (int i = 0; i < getQueueLength(); i++) {System.out.println(arr[(front + i) % MAX_SIZE]);}}}}
三、链表
3.1 链表介绍


3.2 单链表的应用实例

package com.gyh.Link;import java.util.Comparator;
import java.util.Objects;
public class SingleLink {public static void main(String[] args) {Hero hero = new Hero(1, "宋江", "及时雨");Hero hero1 = new Hero(2, "卢俊义", "玉麒麟");Hero hero2 = new Hero(3, "吴用", "智多星");Hero hero3 = new Hero(4, "林冲", "豹子头");SLink<Hero> heroSLink = new SLink<>(Comparator.comparingInt(Hero::getNo));heroSLink.add(hero);heroSLink.add(hero3);heroSLink.add(hero1);heroSLink.add(hero2);
heroSLink.remove(new Hero(1, null, null));heroSLink.list();}
}class SLink<T> {private int length = 0;private final Node<T> head = new Node<>(null, null); private Comparator<T> compara;public SLink(Comparator<T> compara) {this.compara = compara;}public void update(T d) {Node<T> c = head;while (c.next != null) {int compare = compara.compare(c.next.getData(), d);if (compare == 0) {c.next.setData(d);break;}c = c.next;}}public int getLength() {return length;}public void addByOrder(T d) {Node<T> c = head;boolean flag = true; while (c.next != null) {int compare = compara.compare(c.next.getData(), d);if (compare > 0) { break;} else if (compare == 0) { flag = false;break;}c = c.next;}if (flag) {c.next = new Node<>(d, c.next);length++;} elseSystem.out.println("已经存在不能添加");}public void add(T d) {Node<T> c = head;while (c.next != null) {c = c.next;}c.setNext(new Node<>(d, null));length++;}public void remove(T d) {Node<T> c = head;int com;while (c.next != null) {com = compara.compare(c.next.getData(), d);if (com == 0) {c.next = c.next.next;break;}c = c.next;}}public void list() {if (head.next == null) {System.out.println("链表为空");return;}Node<T> c = head.next;while (c != null) {System.out.println(c.data);c = c.next;}}}class Node<T> {T data;Node<T> next;public Node(T data, Node<T> next) {this.data = data;this.next = next;}public T getData() {return data;}public void setData(T data) {this.data = data;}public Node<T> getNext() {return next;}public void setNext(Node<T> next) {this.next = next;}
}class Hero {private int no;private String name;private String nickName;public Hero(int no, String name, String nickName) {this.no = no;this.name = name;this.nickName = nickName;}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Hero hero = (Hero) o;return no == hero.no &&Objects.equals(name, hero.name) &&Objects.equals(nickName, hero.nickName);}@Overridepublic int hashCode() {return Objects.hash(no, name, nickName);}@Overridepublic String toString() {return "Hero{" +"no=" + no +", name='" + name + '\'' +", nickName='" + nickName + '\'' +'}';}public int getNo() {return no;}public void setNo(int no) {this.no = no;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getNickName() {return nickName;}public void setNickName(String nickName) {this.nickName = nickName;}
}
3.3 单链表面试题

package com.gyh.Link;import java.util.Stack;
public class Test {public static void main(String[] args) {SLinkList<Hero> heroSLinkList = new SLinkList<>();Hero hero = new Hero(1, "宋江", "及时雨");Hero hero1 = new Hero(2, "卢俊义", "玉麒麟");Hero hero2 = new Hero(3, "吴用", "智多星");Hero hero3 = new Hero(4, "林冲", "豹子头");heroSLinkList.add(hero);heroSLinkList.add(hero1);heroSLinkList.add(hero2);heroSLinkList.add(hero3);heroSLinkList.printReverseLinkList();
}
}class SLinkList<T> {private int length = 0;private final Node<T> head = new Node<>(null, null); public void add(T d) {Node<T> c = head;while (c.next != null) {c = c.next;}c.setNext(new Node<>(d, null));length++;}public int getLength() {Node<T> c = head;if (c.next == null) return 0;int n = 0;while (c.next != null) {n++;c = c.next;}return n;}public T getNode(int index) {Node<T> c = head;int length = 0;while (c.next != null) {length++;c = c.next;}if (length == 0) return null;c = head.next;for (int i = 0; i < length - index; i++) {c = c.next;}return c.getData();}public void reverseLink() {if (head.next == null || head.next.next == null) return;Node<T> reverseHead = new Node<>(null, null);Node<T> cur = head.next;Node<T> next; while (cur != null) {next = cur.next;cur.next = reverseHead.next;reverseHead.next = cur;cur = next;}head.next = reverseHead.next;}public void printReverseLinkList() {if (head.next == null) return;Stack<T> stack = new Stack<>();Node<T> cur = head.next;while (cur != null) {stack.push(cur.getData());cur = cur.next;}while (stack.size() > 0) {System.out.println(stack.pop());}}public void list() {if (head.next == null) {System.out.println("链表为空");return;}Node<T> c = head.next;while (c != null) {System.out.println(c.data);c = c.next;}}
}
3.4 双向链表应用实例


package com.gyh.Link;import java.util.LinkedList;
public class DoubleLinkedListDemo {public static void main(String[] args) {}
}class DoubleLinkedList<T> {private final DuNode<T> head = new DuNode<>();public void remove(T d) {
DuNode<T> cur = head;while (cur.next != null) {if (d.equals(cur.next.data)) {cur.next = cur.next.next;if (cur.next != null) cur.next.pre = cur;}cur = cur.next;}}public void add(T d) {DuNode<T> cur = head;while (cur.next != null) {cur = cur.next;}cur.next = new DuNode<>(d, cur, null);}}class DuNode<T> {T data;DuNode<T> pre;DuNode<T> next;public DuNode() {}public DuNode(T data, DuNode<T> pre, DuNode<T> next) {this.data = data;this.pre = pre;this.next = next;}
}
3.5 单向环形链表



package com.gyh.Link;import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class SingleCircularLinkedListDemo {public static void main(String[] args) {SingleCircularLinkedList<Integer> integerSingleCircularLinkedList = new SingleCircularLinkedList<>();for (int i = 0; i < 10; i++) {integerSingleCircularLinkedList.add(i);}List<Integer> josephu = integerSingleCircularLinkedList.josephu(4, 6);josephu.forEach(System.out::println);}
}
class SingleCircularLinkedList<T> {private Node<T> last;public boolean isEmpty() {return last == null;}public void add(T d) {if (isEmpty()) {last = new Node<>(d, null);last.setNext(last);return;}last.next = new Node<T>(d, last.next);last = last.next;}public int getLength() {if (isEmpty()) return 0;int n = 1;Node<T> cur = last.next;while (cur != last) {n++;cur = cur.next;}return n;}public List<T> josephu(int k, final int m) {int n = getLength();assert k >= 1 && k <= n;if (n == 1) return Collections.singletonList(last.getData());List<T> out = new ArrayList<>();Node<T> pre = last;for (int i = 1; i < k; i++) {pre = pre.next;}while (true) {if (last.next == last) { out.add(last.getData());last = null;break;}for (int i = 1; i < m; i++) {pre = pre.next;}if (pre.next == last) last = pre; out.add(pre.next.getData()); pre.next = pre.next.next;}return out;}
}
四、栈
4.1 基本介绍



4.2 数组模拟栈

package com.gyh.stack;
public class StackDemo {public static void main(String[] args) {ArrayStack arrayStack = new ArrayStack(5);for (int i = 0; i < 5; i++) {arrayStack.push(i);}arrayStack.list();System.out.println(arrayStack.pop());System.out.println(arrayStack.pop());System.out.println(arrayStack.pop());System.out.println(arrayStack.pop());System.out.println(arrayStack.pop());}
}class ArrayStack {private final int maxSize;private int[] arr;private int stackTop; public ArrayStack(int size) {this.maxSize = size;this.arr = new int[size];this.stackTop = 0;}public boolean isFull() {return stackTop == maxSize;}public boolean isEmpty() {return stackTop == 0;}public void push(int n) {if (isFull()) {System.out.println("已满");return;}arr[stackTop++] = n;}public int pop() {if (isEmpty()) throw new RuntimeException("栈已空");return arr[--stackTop];}public void list(){if(isEmpty()) {System.out.println("栈空");return;}for (int i : arr) {System.out.println(i);}}
}
4.3 链表模拟栈
package com.gyh.stack;
public class StackDemo2 {public static void main(String[] args) {LinkedStack<Integer> integerLinkedStack = new LinkedStack<Integer>();for (int i = 0; i < 5; i++) {integerLinkedStack.push(i);}integerLinkedStack.list();System.out.println(integerLinkedStack.pop());System.out.println(integerLinkedStack.pop());System.out.println(integerLinkedStack.pop());System.out.println(integerLinkedStack.pop());System.out.println(integerLinkedStack.pop());}
}class LinkedStack<T> {private Node<T> stackTop;public boolean isEmpty() {return stackTop == null;}public void push(T d) {if (stackTop == null) {stackTop = new Node<>(d, null);return;}stackTop = new Node<>(d, stackTop);}public T pop() {if (isEmpty()) throw new RuntimeException("栈空");T d = stackTop.data;stackTop = stackTop.next;return d;}public void list() {if (isEmpty()) System.out.println("栈空");Node<T> cur = stackTop;while (cur != null) {System.out.println(cur.data);cur = cur.next;}}}class Node<T> {T data;Node<T> next;public Node(T data, Node<T> next) {this.data = data;this.next = next;}
}
4.4 栈实现综合计算器


package com.gyh.stack;import java.util.Arrays;
import java.util.List;
public class CalculatorDemo {public static void main(String[] args) {String expression = "70*2*2-5+1-5+3-4";LinkedStack<Double> numStack = new LinkedStack<>();LinkedStack<Character> operStack = new LinkedStack<>();double n1, n2, res = 0;char oper = ' ', c;char[] chars = expression.toCharArray();int length = chars.length;StringBuffer numBuf = new StringBuffer();for (int i = 0; i < length; i++) {c = chars[i];if (Calculator.isOper(c) && !operStack.isEmpty()) {oper = operStack.pop();if (Calculator.priority(oper) >= Calculator.priority(c)) { n1 = numStack.pop();n2 = numStack.pop();res = Calculator.cal(n1, n2, oper);numStack.push(res);} else {operStack.push(oper);}}if (Calculator.isOper(c)) {operStack.push(c);} else { numBuf.append(c);if (i == length - 1 || Calculator.isOper(chars[i + 1])) {numStack.push(Double.parseDouble(numBuf.toString()));numBuf = new StringBuffer();}}}while (operStack.size() > 0) {n1 = numStack.pop();n2 = numStack.pop();res = Calculator.cal(n1, n2, operStack.pop());numStack.push(res); }System.out.println(expression + "=" + res);}
}class Calculator {private static final List<Character> opters = Arrays.asList('+', '-', '*', '/');public static double cal(double num1, double num2, int oper) {double res = 0; switch (oper) {case '+':res = num1 + num2;break;case '-':res = num2 - num1;break;case '*':res = num1 * num2;break;case '/':res = num2 / num1;break;default:throw new RuntimeException("操作符异常");}return res;}public static boolean isOper(int oper) {return isOper((char) oper);}public static boolean isOper(char oper) {return opters.contains(oper);}public static int priority(int oper) {if (!isOper(oper)) {return -1;}switch (oper) {case '*':case '/':return 1;case '+':case '-':return 0;default:return -1;}}
}
4.5 前缀、中缀、后缀表达式(逆波兰表达式)





4.6 逆波兰计算器实现

package com.gyh.stack;
public class InversePolishExpressionDemo {public static void main(String[] args) {String expression = "4 5 * 8 - 60 + 8 2 / +"; LinkedStack<Integer> numStack = new LinkedStack<>();String[] chars = expression.split(" ");int n1, n2, res = 0;for (String c : chars) {if (Calculator.isOper(c.charAt(0))) {n1 = numStack.pop();n2 = numStack.pop();res = Calculator.cal(n1, n2, c.charAt(0));numStack.push(res); } else { numStack.push(Integer.parseInt(c));}}System.out.println(expression + "=" + res);}
}
4.7 中缀表达式转后缀表达式(*)


package com.gyh.stack;import java.util.Arrays;
public class MidToReverseDemo {public static void main(String[] args) {String expression = "1 + ( ( 2 + 3 ) * 4 ) - 5";String[] strs = expression.split(" ");LinkedStack<String> linkedStack = new LinkedStack<>();LinkedStack<String> tempStack = new LinkedStack<>();for (String str : strs) {if (!isNumeric(str)) { while (true) {if (str.equals("(") || linkedStack.isEmpty() || linkedStack.peek().equals("("))linkedStack.push(str);else if (str.equals(")")) { while (!linkedStack.peek().equals("(")) {tempStack.push(linkedStack.pop());}linkedStack.pop(); } else if (Calculator.priority(str.charAt(0)) > Calculator.priority(linkedStack.peek().charAt(0))) { linkedStack.push(str);} else { tempStack.push(linkedStack.pop());continue;}break;}} else { tempStack.push(str);}}while (!tempStack.isEmpty()) {linkedStack.push(tempStack.pop());}while (!linkedStack.isEmpty()) {System.out.print(linkedStack.pop() + " ");}}public static boolean isNumeric(String str) {for (int i = str.length(); --i >= 0; ) {int chr = str.charAt(i);if (chr < 48 || chr > 57)return false;}return true;}
}
五、递归
5.1 递归的应用场景

5.2 递归的调用机制


5.3 递归可以解决的问题

5.4 递归需要遵守的重要规则

5.5 迷宫问题

package com.gyh.recursion;
public class MiGong {public static void main(String[] args) {int[][] matrix = new int[8][7];for (int i = 0; i < matrix.length; i++) {for (int j = 0; j < matrix[i].length; j++) {if (i == 0 || i == matrix.length - 1 || j == 0 || j == matrix[i].length - 1) {matrix[i][j] = 1;}}}matrix[2][2] = 1;matrix[3][1] = 1;matrix[3][2] = 1;for (int[] ints : matrix) {for (int anInt : ints) {System.out.print(anInt + "\t");}System.out.println();}System.out.println("*******************");find(matrix, 1, 1);for (int[] ints : matrix) {for (int anInt : ints) {System.out.print(anInt + "\t");}System.out.println();}}public static boolean find(int[][] map, int i, int j) {if (map[6][5] == 2) { return true;}if (map[i][j] == 1 || map[i][j] == 2 || map[i][j] == 3) {return false;}map[i][j] = 2;if (find(map, i + 1, j)) {return true;} else if (find(map, i, j + 1)) {return true;} else if (find(map, i - 1, j)) {return true;} else if (find(map, i, j - 1)) {return true;} else {map[i][j] = 3;return false;}}
}
5.6 八皇后问题

package com.gyh.recursion;
public class EightQueenProblem {static int max = 8;static int[] array = new int[max];static int count = 0;private static void check(int n) {if (n == max) { printArray();count++; return;}for (int i = 0; i < max; i++) {array[n] = i;if (!isComplicit(n)) {check(n + 1);}}}private static boolean isComplicit(int n) {for (int i = 0; i < n; i++) {if (array[i] == array[n] || Math.abs(n - i) == Math.abs(array[n] - array[i])) {return true;}}return false;}private static void printArray() {for (int a : array) {System.out.print(a + "\t");}System.out.println();}public static void main(String[] args) {check(0);System.out.println("一共有" + count + "种算法");}}