常用数据结构与算法

stack
1.ArrayStackDemo
public class ArrayStackDemo {
   public static void main(String[] args) {
       ArrayStack arrayStack = new ArrayStack(4);
       String key = "";
       boolean loop = true;// 控制是否退出菜单
       Scanner scanner = new Scanner(System.in);

       while (loop) {
           System.out.println("show: 显示栈");
           System.out.println("exit: 退出");
           System.out.println("push: 入栈");
           System.out.println("pop: 出栈");
           key = scanner.next();

           switch (key) {
               case "show":
                   arrayStack.list();
                   break;
               case "exit":
                   loop = false;
                   break;
               case "push":
                   System.out.print("请输入一个数:");
                   int value = scanner.nextInt();
                   arrayStack.push(value);
                   break;
               case "pop":
                   arrayStack.pop();
                   break;
               default:
                   break;
           }
           System.out.println("程序退出~~");
       }
   }
}

// 定义一个ArrayStack表示栈
class ArrayStack {

    private int maxSize;// 表示栈的容量
    private int top = -1;// 表示栈顶,初始化为-1
    private int[] stack;// 数组模拟栈,数据放入其中

    // 构造器
    public ArrayStack(int maxSize) {
        this.maxSize = maxSize;
        stack = new int[this.maxSize];
    }

    // 栈满
    public boolean isFull() {
        return top == maxSize - 1;
    }

    // 栈空
    public boolean isEmpty() {
        return top == -1;
    }

    // 返回栈顶的值
    public int peek() {
        return stack[top];
    }

    // 入栈
    public void push(int value) {
        if (isFull()) {
            System.out.println("栈满");
            return;
        }
        top++;
        stack[top] = value;
    }

    // 出栈
    public int pop() {
        if (isEmpty()) {
            throw new RuntimeException("栈空");
        }
        int value = stack[top];
        top--;
        return value;
    }

    // 显示栈的情况
    public void list() {
        if (isEmpty()) {
            System.out.println("栈空");
            return;
        }
        for (int i = top; i >= 0; i--) {
            System.out.printf("栈[%d] = %d\n", i, stack[i]);
        }
    }

    // 返回运算符的优先级由程序猿确定,优先级越高数字越大
    public int priority(int oper) {
        if (oper == '*' || oper == '/') {
            return 1;
        } else if (oper == '+' || oper == '-') {
            return 0;
        } else {
            return -1;
        }
    }

    // 判断是否是运算符
    public boolean isOper(char value) {
        return value == '+' || value == '-' || value == '*' || value == '/';
    }

    // 计算方法
    public int cal(int num1, int num2, int oper) {
        int result = 0;
        switch (oper) {
            case '+':
                result = num1 + num2;
                break;
            case '-':
                result = num2 - num1;
                break;
            case '*':
                result = num1 * num2;
                break;
            case '/':
                result = num2 / num1;
                break;
            default:
                break;
        }
        return result;
    }

}
2.Calculator
public class Calculator {
    public static void main(String[] args) {
        String expression = "7+20*4+4";
        // 创建两个栈,数栈,符号栈
        ArrayStack numStack = new ArrayStack(10);
        ArrayStack operStack = new ArrayStack(10);
        // 定义相关变量
        int index = 0;// 用于扫描
        int num1 = 0;
        int num2 = 0;
        int oper = 0;
        int result = 0;
        char ch = ' ';// 将每次扫描得到char保存到ch
        String keepNum = ""; // 拼接多位数
        while (true) {
            ch = expression.substring(index, index + 1).charAt(0);
            if (operStack.isOper(ch)) {// 如果是运算符
                // 判断栈中是否有值
                if (!operStack.isEmpty()) {
                    // 判断优先级,如果当前运算符小于等于栈顶运算符优先级
                    if (operStack.priority(ch) <= operStack.priority(operStack.peek())) {
                        num1 = numStack.pop();
                        num2 = numStack.pop();
                        oper = operStack.pop();
                        result = numStack.cal(num1, num2, oper);// 计算
                        numStack.push(result);
                        operStack.push(ch);
                    } else {
                        operStack.push(ch);
                    }
                } else {
                    operStack.push(ch);
                }
            } else {
                keepNum += ch;
                // 如果是数,直接入数栈
                // numStack.push(ch - 48);
                // 多位数时不能直接入栈,需要判断下一位是否是运算符
                if (index == expression.length() - 1) {
                    numStack.push(Integer.parseInt(keepNum));
                } else {
                    if (operStack.isOper(expression.substring(index + 1, index + 2).charAt(0))) {
                        numStack.push(Integer.parseInt(keepNum));
                        keepNum = "";
                    }
                }
            }
            index++;
            if (index >= expression.length()) {
                break;
            }
        }
        // 扫描结束之后
        while (true) {
            if (operStack.isEmpty()) {
                break;
            }
            num1 = numStack.pop();
            num2 = numStack.pop();
            oper = (char) operStack.pop();
            result = numStack.cal(num1, num2, oper);
            numStack.push(result);
        }
        int resFinally = numStack.pop();
        System.out.printf("表达式:%s=%d", expression, resFinally);
    }
}
3.PolandNotation
/**
 * 逆波兰计算器
 * 后缀表达式
 *
 * @author xiaoxiao
 * @create 2021-05-28 15:56
 */
public class PolandNotation {
    public static void main(String[] args) {
        // 定义逆波兰表达式
//        String suffixExpression = "4 5 * 8 - 60 + 8 2 / + ";
//        List<String> list = getListString(suffixExpression);
//        System.out.println(list);
//        int result = calculator(list);
//        System.out.println("计算的结果是:" + result);
        String expression = "1+((2+3)*4)-5";
        List<String> list = toInfixExpressionList(expression);
        System.out.println(list);
        List<String> strings = pareSuffixExpressionList(list);
        System.out.println(strings);
        System.out.println(calculator(strings));
    }

    public static List<String> pareSuffixExpressionList(List<String> list) {
        // 定义两个栈
        // 符号栈
        Stack<String> s1 = new Stack<>();
        // 说明:因为s2没有pop操作,还要逆序,使用ArrayList
        // 存储中间结果
        ArrayList<String> s2 = new ArrayList<>();

        // 遍历list
        for (String item : list) {
            if (item.matches("\\d+")) {
                s2.add(item);
            } else if (item.equals("(")) {
                s1.push(item);
            } else if (item.equals(")")) {
                while (!s1.peek().equals("(")){
                    s2.add(s1.pop());
                }
                s1.pop();
            }else {
                while (s1.size() != 0 && Operation.getValue(s1.peek()) >= Operation.getValue(item)){
                    s2.add(s1.pop());
                }
                s1.push(item);
            }

        }

        while (s1.size() != 0){
            s2.add(s1.pop());
        }
        return s2;
    }

    /**
     * 将中缀表达式转化成list集合,方便使用
     *
     * @param infixExpression
     * @return
     */
    public static List<String> toInfixExpressionList(String infixExpression) {
        // 定义一个ArrayList存放中缀表达式的值
        ArrayList<String> list = new ArrayList<>();
        // i遍历指针
        int i = 0;
        // 多位数的拼接
        String str;
        // 每遍历得到一个字符,就放入c
        char c;
        do {
            // 非数字
            if ((c = infixExpression.charAt(i)) < 48 || (c = infixExpression.charAt(i)) > 57) {
                list.add(c + "");
                i++;
            } else {
                // 数字但是考虑多位数
                str = "";
                while (i < infixExpression.length() && (c = infixExpression.charAt(i)) >= 48 && (c = infixExpression.charAt(i)) <= 57) {
                    // 拼接
                    str += c;
                    i++;
                }
                list.add(str);
            }
        } while (i < infixExpression.length());
        return list;
    }

    /**
     * @param suffixExpression
     * @return 逆波兰表达式的集合
     */
    public static List<String> getListString(String suffixExpression) {
        String[] split = suffixExpression.split(" ");
        List<String> list = new ArrayList<String>();
        for (String item : split) {
            list.add(item);
        }
        return list;
    }

    /**
     * @param list
     * @return
     */
    public static int calculator(List<String> list) {
        Stack<String> stack = new Stack<String>();
        for (String item : list) {
            if (item.matches("\\d+")) {
                stack.push(item);
            } else {
                int num1 = Integer.parseInt(stack.pop());
                int num2 = Integer.parseInt(stack.pop());
                int result = 0;
                if (item.equals("+")) {
                    result = num1 + num2;
                } else if (item.equals("-")) {
                    result = num2 - num1;
                } else if (item.equals("*")) {
                    result = num1 * num2;
                } else if (item.equals("/")) {
                    result = num2 / num1;
                } else {
                    throw new RuntimeException("传入的运算符不合理");
                }
                stack.push(result + "");
            }
        }
        return Integer.parseInt(stack.pop());
    }
}

// 返回运算符的优先级
class Operation {

    private static int ADD = 1;
    private static int SUB = 1;
    private static int MUL = 2;
    private static int DIV = 2;

    /**
     * @param operation
     * @return 运算符的级别
     */
    public static int getValue(String operation) {
        int result = 0;
        switch (operation) {
            case "+":
                result = ADD;
                break;
            case "-":
                result = SUB;
                break;
            case "*":
                result = MUL;
                break;
            case "/":
                result = DIV;
                break;
            default:
                System.out.println("不存在该运算符");
                break;
        }
        return result;
    }
}
linkedlist
1.LinkedList:单链表
public class LinkedList {
    public static void main(String[] args) {

        HeroNode heroNode1 = new HeroNode(1, "宋江", "及时雨");
        HeroNode heroNode2 = new HeroNode(2, "吴用", "智多星");
        HeroNode heroNode3 = new HeroNode(5, "林冲", "豹子头");

        SingleLinkedList singleLinkedList = new SingleLinkedList();
        singleLinkedList.addHeroNode(heroNode1);
        singleLinkedList.addHeroNode(heroNode2);
        singleLinkedList.addHeroNode(heroNode3);
        singleLinkedList.list();
        System.out.println("----------------------------------------------");
//        Interview.reversePrint(singleLinkedList.getHead());

//        HeroNode heroNode4 = new HeroNode(4, "笑笑", "帅帅");
//        HeroNode heroNode5 = new HeroNode(3, "脉动", "哈哈哈");
//        singleLinkedList.addHeroNodeOrder(heroNode4);
//        singleLinkedList.addHeroNodeOrder(heroNode5);
//        singleLinkedList.list();
//        System.out.println("------------------");
//        HeroNode heroNode6 = new HeroNode(3, "脉动", "哈哈哈");
//        singleLinkedList.addHeroNodeOrder(heroNode6);
//        singleLinkedList.list();
//        HeroNode newHeroNode = new HeroNode(1, "笑笑", "帅帅");
        singleLinkedList.update(newHeroNode);
        singleLinkedList.delete(2);
        singleLinkedList.list();


    }


}

// 管理
class SingleLinkedList {
    // 头节点
    private  HeroNode head = new HeroNode(0, "", "");

    public HeroNode getHead() {
        return head;
    }

    // 增
    public void addHeroNode(HeroNode heroNode) {
        HeroNode temp = head;
        while (true) {
            if (temp.next == null) {
                break;
            }
            temp = temp.next;
        }
        temp.next = heroNode;
    }

    // 根据排名将英雄插入(如果已经有,给出提示)
    public void addHeroNodeOrder(HeroNode heroNode) {
        HeroNode temp = head;
        boolean flag = false;
        while (true) {
            if (temp.next == null) {
                break;
            }
            if (temp.next.no > heroNode.no) {
                break;
            } else if (temp.next.no == heroNode.no) {
                flag = true;
            }
            temp = temp.next;
        }

        if (flag) {
            System.out.printf("英雄%d已存在\n", heroNode.no);
        } else {
            heroNode.next = temp.next;
            temp.next = heroNode;
        }
    }

    // 修改节点
    public void update(HeroNode newHeroNode) {
        if (head.next == null) {
            System.out.println("链表为空");
            return;
        }
        HeroNode temp = head.next;
        boolean flag = false;
        while (true) {
            if (temp == null) {// 已经遍历完链表
                break;
            }
            if (temp.no == newHeroNode.no) {
                flag = true;
                break;
            }
            temp = temp.next;
        }
        // 根据flag判断是否找到
        if (flag) {
            temp.name = newHeroNode.name;
            temp.nickName = newHeroNode.nickName;
        } else {
            System.out.printf("没有找到排名%d的英雄\n", newHeroNode.no);
        }
    }

    // 删除节点,找到待删除节点的上一个节点
    public void delete(int no) {
        HeroNode temp = head.next;
        boolean flag = false;
        while (true) {
            if (temp.next == null) {
                break;
            }
            if (temp.next.no == no) {
                flag = true;
                break;
            }
            temp = temp.next;
        }
        if (flag) {
            temp.next = temp.next.next;
        } else {
            System.out.printf("没有找到排名%d的英雄", no);
        }
    }



    // 显示链表
    public void list() {

        if (head.next == null) {
            System.out.println("链表为空");
            return;
        }

        // 去掉了头
        HeroNode temp = head;

        while (true) {
            if (temp.next == null) {
                break;
            }

            temp = temp.next;
            System.out.println(temp);

        }
    }

}

// 每一个英雄就是节点
class HeroNode {

    int no;
    String name;
    String nickName;
    HeroNode next;

    public HeroNode(int no, String name, String nickName) {

        this.no = no;
        this.name = name;
        this.nickName = nickName;

    }

    @Override
    public String toString() {
        return "HeroNode{" +
                "no=" + no +
                ", name='" + name + '\'' +
                ", nickName='" + nickName + '\'' +
                '}';
    }
}
2.DoubleLinkedList:双链表
public class DoubleLinkedList {
    public static void main(String[] args) {
        HeroNode2 heroNode1 = new HeroNode2(1, "宋江", "及时雨");
        HeroNode2 heroNode2 = new HeroNode2(2, "吴用", "智多星");
        HeroNode2 heroNode3 = new HeroNode2(5, "林冲", "豹子头");

        DoubleLinkedListManager doubleLinkedListManager = new DoubleLinkedListManager();
        doubleLinkedListManager.addHeroNode(heroNode1);
        doubleLinkedListManager.addHeroNode(heroNode2);
        doubleLinkedListManager.addHeroNode(heroNode3);
        doubleLinkedListManager.list();
        System.out.println("----------------------------------------------");
        if (doubleLinkedListManager.addHeroNodeOrder(new HeroNode2(1, "笑笑", "帅帅"))){
            doubleLinkedListManager.list();
        }
//        System.out.println("----------------------------------------------");
//        doubleLinkedListManager.delete(7);
//        doubleLinkedListManager.list();


    }
}

class DoubleLinkedListManager {

    // 头节点
    private HeroNode2 head = new HeroNode2(0, "", "");

    public HeroNode2 getHead() {
        return head;
    }

    // 增加在最后
    public void addHeroNode(HeroNode2 heroNode) {

        HeroNode2 temp = head;
        while (true) {
            if (temp.next == null) {
                break;
            }
            temp = temp.next;
        }
        temp.next = heroNode;
        heroNode.pre = temp;
    }

    // 添加按照顺序
    public boolean addHeroNodeOrder(HeroNode2 heroNode){
        HeroNode2 temp = head;
        boolean flag = false;
        boolean flag1 = false;
        while (true){
            if (temp.next == null){
                flag1 =true;
                break;
            }
            if (temp.next.no > heroNode.no){
                break;
            }else if (temp.next.no == heroNode.no){
                flag = true;
                break;
            }
            temp = temp.next;
        }

        if (flag){
            System.out.printf("已经存在排名%d的英雄", heroNode.no);
            return false;
        }else if (flag1){
            temp.next = heroNode;
            heroNode.pre = temp;
            return true;
        }else{
            heroNode.next = temp.next;
            temp.next.pre = heroNode;
            temp.next = heroNode;
            heroNode.pre = temp;
        }
        return true;
    }

    // 修改节点
    public void update(HeroNode2 newHeroNode) {

        if (head.next == null) {
            System.out.println("链表为空");
            return;
        }
        HeroNode2 temp = head.next;
        boolean flag = false;
        while (true) {
            if (temp == null) {// 已经遍历完链表
                break;
            }
            if (temp.no == newHeroNode.no) {
                flag = true;
                break;
            }
            temp = temp.next;
        }
        // 根据flag判断是否找到
        if (flag) {
            temp.name = newHeroNode.name;
            temp.nickName = newHeroNode.nickName;
        } else {
            System.out.printf("没有找到排名%d的英雄\n", newHeroNode.no);
        }
    }


    // 删除节点,找到当前节点即可
    public void delete(int no) {
        if (head.next == null){
            return;
        }
        HeroNode2 temp = head.next;
        boolean flag = false;

        while (true) {
            if (temp == null) {
                break;
            }
            if (temp.no == no) {
                flag = true;
                break;
            }
            temp = temp.next;
        }
        if (flag) {
            temp.pre.next = temp.next;
            if (temp.next != null) {
                temp.next.pre = temp.pre;
            }
        } else {
            System.out.printf("没有找到排名%d的英雄", no);
        }
    }


    // 显示链表
    public void list() {

        if (head.next == null) {
            System.out.println("链表为空");
            return;
        }

        // 去掉了头
        HeroNode2 temp = head;

        while (true) {
            if (temp.next == null) {
                break;
            }

            temp = temp.next;
            System.out.println(temp);

        }

    }
}


class HeroNode2 {

    int no;
    String name;
    String nickName;
    HeroNode2 next;
    HeroNode2 pre;

    public HeroNode2(int no, String name, String nickName) {

        this.no = no;
        this.name = name;
        this.nickName = nickName;

    }

    @Override
    public String toString() {
        return "HeroNode2{" +
                "no=" + no +
                ", name='" + name + '\'' +
                ", nickName='" + nickName + '\'' +
                '}';
    }
}
3.面试题
public class Interview {

    /**
     * 求单链表中有效节点的个数
     *
     * @param head
     * @return 有效节点的个数
     */
    public static int getLinkedLength(HeroNode head) {

        if (head.next == null) {
            System.out.println("该链表为空");
            return 0;
        }

        HeroNode temp = head.next;
        int length = 0;

        while (temp != null) {
            length++;
            temp = temp.next;
        }
        return length;
    }

    /**
     * @param head,index
     * @return 倒数第K个节点 = 正数第(总数 - K)
     */
    public static HeroNode getHeroNode(HeroNode head, int index) {
        if (head.next == null) {
            System.out.println("链表为空");
            return null;
        }

        int size = getLinkedLength(head);
        if (index < 0 || size < index){
            return null;
        }
        HeroNode current = head.next;
        for (int i = 0;i < size - index;i++){
            current = current.next;
        }
        return current;
    }

    /**
     * 单链表的反转
     * @param head
     */
    public static void reverseLinkedList(HeroNode head){
        // 当前链表为空或只有一个节点
        if (head.next == null || head.next.next == null){
            return;
        }
        // 定义一个辅助变量,遍历原来的链表
        HeroNode current = head.next;
        HeroNode next = null;// current的下一个节点
        HeroNode reverseHead = new HeroNode(0, "", "");

        while (current != null){

            next = current.next;// 当前节点的保留下一个节点
            current.next = reverseHead.next;
            reverseHead.next = current;

            current = next;// current后移

        }

        head.next = reverseHead.next;


    }

    /**
     * 打印反转的链表
     * @param head
     */
    public static void reversePrint(HeroNode head){

        if (head.next == null){
            System.out.println("链表为空");
            return;
        }
        Stack<HeroNode> stack = new Stack<HeroNode>();
        HeroNode temp = head.next;
        while (temp != null){// 入栈
            stack.push(temp);
            temp = temp.next;
        }
        // 出栈
        while (stack.size() > 0){
            System.out.println(stack.pop());
        }

    }

}
recursion
1.RecursionTest
public class RecursionTest {
    public static void main(String[] args) {
//        test(10);
        int result = factorial(3);
    }
    /**
     * 打印问题
     *
     * @param n
     */
    public static void test(int n) {
        if (n > 1) {
            test(n - 1);
        }
        System.out.println("n=" + n);
    }

    public static int factorial(int n) {
        if (n == 1) {
            return 1;
        } else {
            return factorial(n - 1) * n;
        }
    }
}
2.迷宫问题
public class MiGong {
    public static void main(String[] args) {
        // 创建二维数组,模拟迷宫
        int[][] map = new int[8][7];
        // 使用1为墙,则上下都为1
        for (int i = 0; i < 7; i++) {
            map[0][i] = 1;
            map[7][i] = 1;
        }
        // 左右置为1
        for (int i = 0; i < 8; i++) {
            map[i][0] = 1;
            map[i][6] = 1;
        }
        // 设置挡板
        map[3][1] = 1;
        map[3][2] = 1;
        // 输出地图
        System.out.println("地图------------");
        for (int i = 0; i < 8; i++) {
            for (int j = 0; j < 7; j++) {
                System.out.print(map[i][j] + " ");
            }
            System.out.println();
        }
        // 使用递归找路
        getWay(map, 1, 1);
        // 输出地图,小球走过
        System.out.println("小球额走过的地图------------");
        for (int i = 0; i < 8; i++) {
            for (int j = 0; j < 7; j++) {
                System.out.print(map[i][j] + " ");
            }
            System.out.println();
        }
    }
    // 使用递归给小球找路
    /*
    说明
    1. map表示地图
    2. i,j表示从地图的哪个位置开始
    3. 如果小球能到map[6][5]则说明通路能够找到
    4. 约定: 当map[i][j]为0表示该点没走过,1表示为墙,2表示通路可以走,3表示该点已经走过但不通
    5. 走迷宫时,确定一个策略,下->右->上->左,如果走不通,再回溯
     */

    /**
     * @param map 表示地图
     * @param i   从哪个位置开始找
     * @param j
     * @return 找到返回true
     */
    public static boolean getWay(int[][] map, int i, int j) {
        if (map[6][5] == 2) {
            return true;
        } else {
            if (map[i][j] == 0) {// 表示还没走过
                map[i][j] = 2;
                if (getWay(map, i + 1, j)) {// 向下走
                    return true;
                } else if (getWay(map, i, j + 1)) {
                    return true;
                } else if (getWay(map, i, j - 1)) {
                    return true;
                } else if (getWay(map, i - 1, j)) {
                    return true;
                } else {
                    // 说明该点走不通,死路
                    map[i][j] = 3;
                    return false;
                }
            } else {
                return false;
            }

        }
    }
}
sort
1.冒泡排序
public class BubbleSort {
    public static void main(String[] args) {
        int[] arr = {3, 9, -1, 20, 10};
    }

    /**
     * 原始冒泡排序
     *
     * @param arr
     * @return
     */
    public static int[] bubbleSortOrigin(int[] arr) {
        int temp = 0;// 临时变量
        // 每一趟确定末尾是最大的
        for (int i = 0; i < arr.length - 1; i++) {
            for (int j = 0; j < arr.length - 1 - i; j++) {
                if (arr[j] > arr[j + 1]) {
                    temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
            System.out.println("第" + (i + 1) + "趟排序的数组");
            System.out.println(Arrays.toString(arr));
        }
        return arr;
    }

    /**
     * 优化后的冒泡排序
     *
     * @param arr
     * @return
     */
    public static int[] bubbleSortOptimized(int[] arr) {
        int temp = 0;// 临时变量
        // 每一趟确定末尾是最大的
        boolean flag = false;// 标识变量,是否经过交换
        for (int i = 0; i < arr.length - 1; i++) {
            for (int j = 0; j < arr.length - 1 - i; j++) {
                if (arr[j] > arr[j + 1]) {
                    flag = true;
                    temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
            System.out.println("第" + (i + 1) + "趟排序的数组");
            System.out.println(Arrays.toString(arr));
            if (!flag) {// flag此时为false表示在本趟排序中未发生交换,则直接退出排序
                break;
            } else {
                flag = false;
            }
        }
        return arr;
    }
}
2.选择排序从小到大
public class SelectSort {
    public static void main(String[] args) {
//        int[] arr = {56, -31, 66, 49};
//        System.out.println("排序前---------");
//        System.out.println(Arrays.toString(arr));
//        System.out.println("排序后----------");
//        selectSort(arr);
//        System.out.println(Arrays.toString(arr));
        int[] arr = new int[200000];
        LocalDateTime time1 = LocalDateTime.now();
        for (int i = 0; i < arr.length; i++) {
            arr[i] = (int) (Math.random() * 10000);//[0,1)
        }
        Date date1 = new Date();
        SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String date1Str = simpleDateFormat1.format(date1);
        System.out.println("排序前的时间:" + date1Str);

        selectSort(arr);

        Date date2 = new Date();
        SimpleDateFormat simpleDateFormat2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String date2Str = simpleDateFormat2.format(date2);
        System.out.println("排序后的时间:" + date2Str);
    }

    // 选择排序
    public static void selectSort(int[] arr) {
        for (int i = 0; i < arr.length - 1; i++) {
            int min = arr[i];
            int minIndex = i;
            for (int j = i + 1; j < arr.length; j++) {
                if (min > arr[j]) {
                    min = arr[j];
                    minIndex = j;
                }
            }
            if (minIndex != i) {
                arr[minIndex] = arr[i];
                arr[i] = min;
            }

        }
    }
}
hashtable
1.HashtableDemo
/**
 * hash表操作雇员
 *
 * @author xiaoxiao
 * @create 2021-07-11 12:21
 */
public class HashtableDemo {
    public static void main(String[] args) {
        // 创建hash表
        HashTab hashTab = new HashTab(7);
        // 简单的菜单
        String key = "";
        Scanner scanner = new Scanner(System.in);
        while (true) {
            System.out.println("add:  添加雇员");
            System.out.println("list: 显示雇员");
            System.out.println("find: 查找雇员");
            System.out.println("exit: 退出系统");
            key = scanner.next();
            switch (key) {
                case "add":
                    System.out.print("输入id:");
                    int id = scanner.nextInt();
                    System.out.print("输入name:");
                    String name = scanner.next();
                    Employee employee = new Employee(id, name);
                    hashTab.add(employee);
                    break;
                case "list":
                    hashTab.list();
                    break;
                case "find":
                    System.out.print("请输入查找的id:");
                    id = scanner.nextInt();
                    hashTab.findEmpById(id);
                    break;
                case "exit":
                    scanner.close();
                    System.exit(0);
                    break;
                default:
                    break;
            }
        }

    }
}

// 创建HashTab管理多条链表
class HashTab {

    private int size;// 表示有多少条链表
    private EmployeeLinkedList[] empLinkedListArray;

    public HashTab(int size) {
        this.size = size;
        empLinkedListArray = new EmployeeLinkedList[size];
        // 分别初始化每个链表
        for (int i = 0; i < size; i++) {
            empLinkedListArray[i] = new EmployeeLinkedList();
        }
    }

    // 添加雇员
    public void add(Employee employee) {
        // 根据员工id,得到该员工应该添加到哪条链表
        int empLinkedListNo = hashFun(employee.getId());
        empLinkedListArray[empLinkedListNo].add(employee);

    }

    // 遍历所有的链表
    public void list() {
        for (int i = 0; i < size; i++) {
            empLinkedListArray[i].list(i);
        }
    }

    // 根据输入的id,查找雇员
    public void findEmpById(int id) {
        int empLinkedListNo = hashFun(id);
        Employee employee = empLinkedListArray[empLinkedListNo].findEmpById(id);
        if (employee != null) {
            System.out.printf("在第%d条链表找到雇员id=%d\n", empLinkedListNo, id);
        } else {
            System.out.println("没有找到雇员");
        }
    }


    // 编写散列函数,简单的取模法
    public int hashFun(int id) {
        return id % size;
    }

}

// 雇员
class Employee {
    private int id;
    private String name;
    // next默认为null
    Employee next;

    public Employee(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}

// 创建EmployeeLinkedList表示链表
class EmployeeLinkedList {

    private Employee head;

    // 添加员工
    public void add(Employee employee) {
        // 如果是第一个员工
        if (head == null) {
            head = employee;
            return;
        }

        Employee curEmp = head;// 辅助指针,定位到最后

        while (true) {
            if (curEmp.next == null) {
                break;
            }
            curEmp = curEmp.next;
        }
        curEmp.next = employee;
    }

    // 遍历员工信息
    public void list(int num) {
        if (head == null) {
            System.out.println("第" + num + "条链表无员工");
            return;
        }

        System.out.print("第" + num + "条链表员工信息");
        Employee curEmp = head;

        while (true) {
            // 打印当前员工信息
            System.out.printf("id=>%d,name=>%s\n", curEmp.getId(), curEmp.getName());
            if (curEmp.next == null) {
                break;
            }
            curEmp = curEmp.next;
        }
    }

    // 根据id查找雇员
    public Employee findEmpById(int id) {
        // 判断链表是否为空
        if (head == null) {
            return null;
        }
        Employee curEmp = head;
        while (true) {
            if (curEmp.getId() == id) {// 找到
                break;
            }
            // 退出
            if (curEmp.next == null) {// 已经遍历到最后,没有找到
                curEmp = null;
                break;
            }
            curEmp = curEmp.next;
        }
        return curEmp;
    }
}
tree
1.二叉树遍历
/**
 * 二叉树遍历(每个节点最多只能有两个子节点的为二叉树)
 *
 * @author xiaoxiao
 * @create 2021-09-05 20:44
 */
public class BinaryTreeDemo {
    public static void main(String[] args) {
        // 先创建一颗二叉树
        BinaryTree binaryTree = new BinaryTree();
        // 创建所需要的节点
        HeroNode root = new HeroNode(1, "宋江");
        HeroNode node2 = new HeroNode(2, "吴用");
        HeroNode node3 = new HeroNode(3, "卢俊义");
        HeroNode node4 = new HeroNode(4, "林冲");
        HeroNode node5 = new HeroNode(5, "鲁智深");
        // 设置关系,二叉树
        root.setLeft(node2);
        root.setRight(node3);
        node3.setLeft(node5);
        node3.setRight(node4);

        binaryTree.setRoot(root);
        // 测试
//        System.out.println("前序遍历");
//        binaryTree.preOrder();
//        System.out.println("中序遍历");
//        binaryTree.infixOrder();
//        System.out.println("后序遍历");
//        binaryTree.postOrder();
//        System.out.println("=====遍历查找========");
//        System.out.println("前序遍历查找:" + binaryTree.preOrderSearch(5));
//        System.out.println("中序遍历查找:" + binaryTree.infixOrderSearch(1));
//        System.out.println("后序遍历查找:" + binaryTree.postOrderSearch(2));
        System.out.println("删除前=========");
        binaryTree.preOrder();
        System.out.println("删除后");
        binaryTree.deleteHeroNode(5);
        binaryTree.preOrder();
    }
}

// 定义BinaryTree二叉树
class BinaryTree {

    private HeroNode root;

    public void setRoot(HeroNode root) {
        this.root = root;
    }

    // 删除节点
    public void deleteHeroNode(int no) {
        if (this.root != null) {
            if (this.root.getNo() == no) {
                this.root = null;
                return;
            }
            this.root.deleteHeroNode(no);
        } else {
            System.out.println("空树,无法删除!");
        }
    }

    // 前序遍历
    public void preOrder() {
        if (this.root != null) {
            this.root.preOrder();
        } else {
            System.out.println("二叉树为空,无法遍历");
        }
    }

    // 中序遍历
    public void infixOrder() {
        if (this.root != null) {
            this.root.infixOrder();
        } else {
            System.out.println("二叉树为空,无法遍历");
        }
    }

    // 后序遍历
    public void postOrder() {
        if (this.root != null) {
            this.root.postOrder();
        } else {
            System.out.println("二叉树为空,无法遍历");
        }
    }

    // 前序遍历查找
    public HeroNode preOrderSearch(int no) {
        if (this.root != null) {
            return this.root.preOrderSearch(no);
        } else {
            return null;
        }
    }

    // 中序遍历查找
    public HeroNode infixOrderSearch(int no) {
        if (this.root != null) {
            return this.root.infixOrderSearch(no);
        } else {
            return null;
        }
    }

    // 后序遍历查找
    public HeroNode postOrderSearch(int no) {
        if (this.root != null) {
            return this.root.postOrderSearch(no);
        } else {
            return null;
        }
    }
}

// 创建HeroNode节点
class HeroNode {
    private int no;
    private String name;
    private HeroNode left;
    private HeroNode right;

    public HeroNode(int no, String name) {
        this.no = no;
        this.name = name;
    }

    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 HeroNode getLeft() {
        return left;
    }

    public void setLeft(HeroNode left) {
        this.left = left;
    }

    public HeroNode getRight() {
        return right;
    }

    public void setRight(HeroNode right) {
        this.right = right;
    }

    @Override
    public String toString() {
        return "HeroNode{" +
                "no=" + no +
                ", name='" + name + '\'' +
                '}';
    }

    // 递归删除节点
    // 1.如果是叶子节点,则删除该节点
    // 2.如果删除的是非叶子节点,则删除该子树
    public void deleteHeroNode(int no) {
        if (this.left != null && this.left.no == no) {
            this.left = null;
            return;
        }
        if (this.right != null && this.right.no == no) {
            this.right = null;
            return;
        }
        if (this.left != null) {
            this.left.deleteHeroNode(no);
        }
        if (this.right != null) {
            this.right.deleteHeroNode(no);
        }
    }

    // 编写前序遍历的方法
    public void preOrder() {
        // 先输出父节点
        System.out.println(this);
        // 递归向左子树前序遍历
        if (this.left != null) {
            this.left.preOrder();
        }
        // 递归向右子树前序遍历
        if (this.right != null) {
            this.right.preOrder();
        }
    }

    // 中序遍历
    public void infixOrder() {
        // 递归向左子树中序遍历
        if (this.left != null) {
            this.left.infixOrder();
        }
        // 输出父节点
        System.out.println(this);
        // 递归向右子树中序遍历
        if (this.right != null) {
            this.right.infixOrder();
        }
    }

    // 后序遍历
    public void postOrder() {
        if (this.left != null) {
            this.left.postOrder();
        }

        if (this.right != null) {
            this.right.postOrder();
        }
        System.out.println(this);
    }

    // 前序遍历查找
    public HeroNode preOrderSearch(int no) {
        if (this.no == no) {
            return this;
        }
        HeroNode resultNode = null;
        // 判断左子节点不为空
        if (this.left != null) {
            resultNode = this.left.preOrderSearch(no);
        }
        if (resultNode != null) {// 说明在左子节点已经找到
            return resultNode;
        }
        // 右子节点
        if (this.right != null) {
            resultNode = this.right.preOrderSearch(no);
        }
        return resultNode;
    }

    // 中序查找
    public HeroNode infixOrderSearch(int no) {
        HeroNode resultNode = null;
        if (this.left != null) {
            resultNode = this.left.infixOrderSearch(no);
        }
        if (resultNode != null) {
            return resultNode;
        }
        if (this.no == no) {
            return this;
        }
        if (this.right != null) {
            resultNode = this.right.infixOrderSearch(no);
        }
        return resultNode;
    }

    // 后序遍历查找
    public HeroNode postOrderSearch(int no) {
        HeroNode resultNode = null;
        if (this.left != null) {
            resultNode = this.left.postOrderSearch(no);
        }
        if (resultNode != null) {
            return resultNode;
        }
        if (this.right != null) {
            resultNode = this.right.postOrderSearch(no);
        }
        if (resultNode != null) {
            return resultNode;
        }
        if (this.no == no) {
            return this;
        }
        return resultNode;
    }

}
2.顺序存储二叉树
public class ArrayBinaryTreeDemo {
    public static void main(String[] args) {
        int[] arr = {1, 2, 3, 4, 5, 6, 7};
        ArrayBinaryTree tree = new ArrayBinaryTree(arr);
        tree.preOrder();
    }
}

/*
 * 顺序存储二叉树
 * 1.顺序存储二叉树通常只考虑完全二叉树
 * 2.第n个元素的左子节点为 2*n+1
 * 3.第n个元素的右子节点为 2*n+2
 * 4.第n个元素的父节点为 (n-1)/2
 * 注意:n从0开始,和数组的下标一样
 */
class ArrayBinaryTree {
    int[] arr;

    public ArrayBinaryTree(int[] arr) {
        this.arr = arr;
    }

    public void preOrder() {
        this.preOrder(0);
    }

    public void preOrder(int index) {
        // 如果数组为空,或者arr.length() = 0
        if (arr == null || arr.length == 0) {
            System.out.println("数组为空,不能按照二叉树前序遍历!");
            return;
        }
        // 输出当前元素
        System.out.println(arr[index]);
        // 递归向左遍历
        if ((index * 2 + 1) < arr.length) {
            preOrder(index * 2 + 1);
        }
        // 递归向右遍历
        if ((index * 2 + 2) < arr.length) {
            preOrder(index * 2 + 2);
        }

    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值