数组结构与算法

文章目录

  • 数据结构与算法
    • 稀疏数组sparse
    • 队列
    • 单向链表
    • 双向链表
    • 单向环形列表:CircleSingleLinkedList
    • 递归
    • 排序算法
      • 快速排序思路
      • 赫夫曼树 (HuffmanTree)
      • 二叉排序树(Binary sort tree)
        • 构建二叉树
        • 遍历二叉树
      • 平衡二叉树(AVL树)
      • 多路查找树
  • 算法
    • 二分查找算法
    • 动态规划
    • KMP
    • 贪心算法
    • 普利姆算法
    • 克鲁斯卡尔算法
    • 迪杰斯特拉算法
    • 弗洛伊德算法
    • 马踏棋盘

数据结构与算法

稀疏数组sparse

  • 二维数据转稀疏数组(chessToSparse)
  • 稀疏数组转二维数组(sparseToChess)
  • IO存盘

队列

  • 使用数组模拟循环队列(ArrayCircleQueue)
    元素个数:rear + maxsize + front % maxsize
    判断队列是否为空:
  • 使用链表模拟队列

单向链表

  • 链表新增
  • 链表删除
  • 链表修改
  • 链表反转

双向链表

  • 链表新增
  • 链表删除
  • 链表修改

单向环形列表:CircleSingleLinkedList

  • 约瑟夫问题

  • 实现计算器计算【722-5+1-5+3-4=?】的结果
  • 前缀表达式
  • 中缀表达式
  • 后缀表达式
  • 中缀转后缀
    数组结构与算法_第1张图片
package com.semanteme.demo.stack;

import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

public class CalcDemo {



    public static void main(String[] args) {

        String mathExpression = "2+3*4-(2*3+4)+5";
//        String mathExpression = "3*4-(3+4)+5";
//        String mathExpression = "1+((2+3)*4)-5";

        int result = CalcUtil.calc(mathExpression);
        System.out.println("计算结果:" + result);

    }

}

class CalcUtil{

    public static int calc(String mathExpression) {

        String inFixExpression = toInFixExpression(mathExpression);
        System.out.println("中缀表达式:" + inFixExpression);

        List<String> suffixExpressionList = inFixToSuffixExpressionList(inFixExpression);
        System.out.println("后缀表达式:" + suffixExpressionList.toString());

        // 操作符栈
        Stack<String> operatorStack = new Stack<>();

        // 数字栈
        Stack<Integer> numbersStack = new Stack<>();
        for (String expression : suffixExpressionList) {

            if(expression.matches("\\d+")){

                numbersStack.push(Integer.parseInt(expression));
            }else {
                Integer pop1 = numbersStack.pop();
                Integer pop2 = numbersStack.pop();
                if("+".equals(expression)){
                    numbersStack.push(pop2 + pop1);
                }else if("-".equals(expression)){
                    numbersStack.push(pop2 - pop1);
                }else if("*".equals(expression)){
                    numbersStack.push(pop2 * pop1);
                }else if("/".equals(expression)){
                    numbersStack.push(pop2 / pop1);
                }
            }
        }
        return numbersStack.pop();
    }

    /**
     * 将数学表达式转成中缀表达式
     * @param mathExpression
     * @return
     */
    private static String toInFixExpression(String mathExpression){

        StringBuffer stringBuffer = new StringBuffer();

        char[] charArray = mathExpression.toCharArray();

        StringBuffer temp = new StringBuffer();
        for (char c : charArray) {

            String expression = String.valueOf(c);
            if(expression.matches("\\d+")){
                temp.append(c);
            }else {

                if(temp.length() > 0){
                    stringBuffer.append(temp.toString() + " ");
                    temp = new StringBuffer();
                }

                stringBuffer.append(expression + " ");
            }
        }

        if(temp.length() > 0){
            stringBuffer.append(temp.toString());
        }

        return stringBuffer.toString();
    }

    /**
     * 将中缀表达式转成后缀表达式
     *
     * @param inFixExpression
     * @return
     */
    private static List<String> inFixToSuffixExpressionList(String inFixExpression) {

        // 操作符栈
        Stack<String> operatorStack = new Stack<>();

        // 数字栈
        Stack<Integer> numbersStack = new Stack<>();

        List<String> suffixExpressionList = new ArrayList<>();

        String[] expressions = inFixExpression.split(" ");

        for (String expression : expressions) {

            if(expression.matches("\\d+")){

                suffixExpressionList.add(expression);
            }else if(expression.equals("(")){

                operatorStack.push(expression);
            }else if(expression.equals(")")){

                while (!operatorStack.peek().equals("(")){
                    suffixExpressionList.add(operatorStack.pop());
                }

                operatorStack.pop();
            }else {

                while (operatorStack.size() != 0 && Operation.getValue(expression) <= Operation.getValue(operatorStack.peek())){
                    suffixExpressionList.add(operatorStack.pop());
                }

                operatorStack.push(expression);
            }
        }

        while (!operatorStack.isEmpty()){
            suffixExpressionList.add(operatorStack.pop());
        }

        return suffixExpressionList;
    }

}

class Operation{

    private static int ADD = 1;

    private static int SUB = 1;

    private static int MUL = 2;

    private static int DIV = 2;

    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:
                result = 0;
        }

        return result;
    }
}

递归

  • 打印阶乘
  • 找出口:最优路径方法:列出所有策略的方法,找出最短路径
  • 八皇后问题

排序算法

数组结构与算法_第2张图片

快速排序思路

数组结构与算法_第3张图片

赫夫曼树 (HuffmanTree)

  • 数组构建赫夫曼树
  • 赫夫曼编解码

二叉排序树(Binary sort tree)

  • 构建二叉排序树
  • 中序遍历
  • 删除指定节点值
构建二叉树
遍历二叉树
package com.semanteme.demo.tree;

import java.util.*;

public class TreeBase {

    public static void main(String[] args) {

        Node root = new Node(7);

        Node node2 = new Node(5);
        root.setLeft(node2);
        Node node1 = new Node(11);
        root.setRight(node1);

        Node node3 = new Node(6);
        node2.setRight(node3);
        Node node4 = new Node(2);
        node2.setLeft(node4);

        Node node5 = new Node(3);
        node4.setRight(node5);
        Node node6 = new Node(1);
        node4.setLeft(node6);

        Node node7 = new Node(13);
        node1.setRight(node7);
        Node node8 = new Node(9);
        node1.setLeft(node8);

        Node node9 = new Node(14);
        node7.setRight(node9);
        Node node10 = new Node(12);
        node7.setLeft(node10);

        NodeUtil nodeUtil = new NodeUtil();

        nodeUtil.preOrder(root);
        System.out.println("====================");
        nodeUtil.inOrder(root);
        System.out.println("====================");
        nodeUtil.sufOrder(root);
        System.out.println("====================");

        List<Node> list = new ArrayList<>();
        list.add(root);
        nodeUtil.levelOrder(list);
        nodeUtil.levelOrderTraversal(root);
    }

}

class NodeUtil{

    /**
     * 前序遍历
     * @param node
     */
    public void preOrder(Node node) {

        System.out.print(node.getValue() + " ");

        if(node.getLeft() != null){
            preOrder(node.getLeft());
        }

        if(node.getRight() != null){
            preOrder(node.getRight());
        }
    }

    /**
     * 中序遍历
     * @param node
     */
    public void inOrder(Node node) {

        if(node.getLeft() != null){
            inOrder(node.getLeft());
        }

        System.out.print(node.getValue() + " ");

        if(node.getRight() != null){
            inOrder(node.getRight());
        }
    }

    /**
     * 后续遍历
     * @param node
     */
    public void sufOrder(Node node){

        if(node.getLeft() != null){
            sufOrder(node.getLeft());
        }

        if(node.getRight() != null){
            sufOrder(node.getRight());
        }

        System.out.print(node.getValue() + " ");
    }

    /**
     * 层级遍历
     *
     * @param list
     */
    public void levelOrder(List<Node> list){

        ArrayList<Node> nextList = new ArrayList<>();

        for (Node node : list) {

            System.out.print(node.getValue() + " ");

            if(node.getLeft() != null){
                nextList.add(node.getLeft());
            }

            if(node.getRight() != null){
                nextList.add(node.getRight());
            }
        }
        System.out.println("====================");

        if(!nextList.isEmpty()){
            levelOrder(nextList);
        }
    }

    public void levelOrderTraversal(Node node){

        Queue<Node> queue = new LinkedList<>();
        queue.add(node);

        while (!queue.isEmpty()){

            Node poll = queue.poll();
            System.out.print(poll.getValue() + " ");

            if(poll.getLeft() != null){
                queue.add(poll.getLeft());
            }

            if(poll.getRight() != null){
                queue.add(poll.getRight());
            }

        }
    }
}

class Node{

    private int value;

    private Node root;

    private Node left;

    private Node right;

    public Node() {
    }

    public Node(int value) {
        this.value = value;
    }

    public Node(int value, Node left, Node right) {
        this.value = value;
        this.left = left;
        this.right = right;
    }

    public int getValue() {
        return value;
    }

    public void setValue(int value) {
        this.value = value;
    }

    public Node getLeft() {
        return left;
    }

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

    public Node getRight() {
        return right;
    }

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

    public Node getRoot() {
        return root;
    }

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



    @Override
    public String toString() {
        return "Node{" +
                "value=" + value +
                '}';
    }
}


平衡二叉树(AVL树)

  • 左旋
  • 右旋

多路查找树

  • 图的表示
  • 深度优先遍历(DFS)
  • 广度优先遍历(BFS)

算法

二分查找算法

  • 递归写法
  • 非递归写法
  • 汉诺塔游戏算法
package com.semanteme.demo.search;

public class BinarySearchDemo {

    public static void main(String[] args) {

        int[] searchArray = new int[]{1,4,6,7,8,10,34,45,67,89};

        int target = 2;

        int index = search(searchArray, target, 0, searchArray.length);
        System.out.println("二分法查找目标值结果:" + index);
    }

    public static int search(int[] searchArray, int target, int leftIndex, int rightIndex){

        int mid = (leftIndex + rightIndex) / 2;

        if(mid == rightIndex || mid == leftIndex){
            return -1;
        }

        if(searchArray[mid] > target){
            return search(searchArray, target, 0, mid);
        }else if(searchArray[mid] < target){
            return search(searchArray, target, mid, rightIndex);
        }else{
            return mid;
        }
    }
}

非递归方法

package com.semanteme.demo.search;

public class BinarySearchDemo2 {

    public static void main(String[] args) {

        int[] searchArray = new int[]{1,4,6,7,8,10,34,45,67,89};

        int target = 1;

        int index = search(searchArray, target);
        System.out.println("二分法查找目标值结果:" + index);
    }

    public static int search(int[] searchArray, int target){

        int leftIndex = 0;
        int rightIndex = searchArray.length;

        int mid = (leftIndex + rightIndex) / 2;
        while (searchArray[mid] != target){

            if(mid == leftIndex || mid == rightIndex){
                return -1;
            }

            if(searchArray[mid] > target){
                rightIndex = mid;
            }else if(searchArray[mid] < target){
                leftIndex = mid;
            }

            mid = (leftIndex + rightIndex) / 2;
        }

        return mid;
    }
}

动态规划

  • 背包
package com.semanteme.demo.dynamicprogram;

public class BagDemo {

    public static void main(String[] args) {

        int[] W = new int[]{1, 4, 3};

        int[] V = new int[]{1500, 3000, 2000};

        Bag bag = new Bag(W, V);

        int max = bag.peek(3, 4);
        System.out.println("背包可装的最大价值为:" + max);
    }

}

class Bag{

    private int[] W = new int[]{0, 1, 4, 3};

    private int[] V = new int[]{0, 1500, 3000, 2000};

    public Bag(int[] w, int[] v) {
        W = w;
        V = v;
    }

    public int peek(int maxN, int maxW) {

        int[][] sum = new int[maxN + 1][maxW + 1];

        for (int i = 1; i < sum.length; i++) {

            for (int j = 1; j < sum[i].length; j++) {

                if(j == W[i - 1]){
                    sum[i][j] = V[i - 1];
                }else if(j < W[i - 1]){
                    sum[i][j] = sum[i - 1][j];
                }else if(j > W[i - 1]){
                    sum[i][j] = Math.max(sum[i - 1][j], V[i - 1] + sum[i - 1][j - W[i - 1]]);
                }
            }
        }


        for (int i = 0; i < sum.length; i++) {
            for (int j = 0; j < sum[i].length; j++) {

                System.out.print(sum[i][j] + " ");
            }
            System.out.println();
        }

        return sum[maxN][maxW];
    }
}


KMP

贪心算法

普利姆算法

  • 修路最短

克鲁斯卡尔算法

迪杰斯特拉算法

弗洛伊德算法

数组结构与算法_第4张图片

马踏棋盘

数组结构与算法_第5张图片

package com.semanteme.demo.dst;


import java.util.ArrayList;
import java.util.List;

public class HorseChessBoard  {

    public static void main(String[] args) {
        int X = 8;
        int Y = 8;

        ChessBoard chessBoard = new ChessBoard(X, Y);
        System.out.println("周游前===========");
        chessBoard.show();

        long startTime = System.currentTimeMillis();
        chessBoard.travel(3, 2, 1);
        System.out.println("周游后===========;总共耗时:" + (System.currentTimeMillis() - startTime));
        chessBoard.show();

    }



}

class ChessBoard {

    private int X;
    private int Y;
    private int[][] chessBoard;

    private boolean[] visitChess;

    private boolean isFinished;

    public ChessBoard(int X, int Y){
        this.X = X;
        this.Y = Y;
        this.chessBoard = new int[X][Y];
        this.visitChess = new boolean[X * Y];
    }

    public void travel(int row, int col, int step){

        chessBoard[row][col] = step;
        visitChess[row * Y + col] = true;

        List<Coordinate> next = next(new Coordinate(row, col));
        sort(next);

        while (!next.isEmpty()){
            Coordinate remove = next.remove(0);

            // 未被访问过
            if(!visitChess[remove.getRow() * Y + remove.getCol()]){
                travel(remove.getRow(), remove.getCol(), step+1);
            }

        }

        if(step < X * Y && !isFinished){
            chessBoard[row][col] = 0;
            visitChess[row * Y + col] = false;
        }else {
            isFinished = true;
        }
    }

    private void sort(List<Coordinate> list){
        list.sort((o1, o2) -> {

            List<Coordinate> next1 = next(o1);
            List<Coordinate> next2 = next(o2);
            return next1.size() - next2.size();
        });
    }

    private List<Coordinate> next(Coordinate p){

        List<Coordinate> nextPoints = new ArrayList<>(8);

        // 添加0位置
        if(p.getRow() - 1 >= 0 && p.getCol() + 2 < Y){
            Coordinate point = new Coordinate(p.getRow() - 1, p.getCol() + 2);
            nextPoints.add(point);
        }

        // 添加1位置
        if(p.getRow() + 1 < X && p.getCol() + 2 < Y){
            Coordinate point = new Coordinate(p.getRow() + 1, p.getCol() + 2);
            nextPoints.add(point);
        }

        // 添加2位置
        if(p.getRow() + 2 < X && p.getCol() + 1 < Y){
            Coordinate point = new Coordinate(p.getRow() + 2, p.getCol() + 1);
            nextPoints.add(point);
        }

        // 添加3位置
        if(p.getRow() + 2 < X && p.getCol() - 1 >= 0){
            Coordinate point = new Coordinate(p.getRow() + 2, p.getCol() - 1);
            nextPoints.add(point);
        }

        // 添加4位置
        if(p.getRow() + 1 < X && p.getCol() - 2 >= 0){
            Coordinate point = new Coordinate(p.getRow() + 1, p.getCol() - 2);
            nextPoints.add(point);
        }

        // 添加5位置
        if(p.getRow() - 1 > 0 && p.getCol() - 2 >= 0){
            Coordinate point = new Coordinate(p.getRow() - 1, p.getCol() - 2);
            nextPoints.add(point);
        }

        // 添加6位置
        if(p.getRow() - 2 >= 0 && p.getCol() - 1 >= 0){
            Coordinate point = new Coordinate(p.getRow() - 2, p.getCol() - 1);
            nextPoints.add(point);
        }

        // 添加7位置
        if(p.getRow() - 2 >= 0 && p.getCol() + 1 < Y){
            Coordinate point = new Coordinate(p.getRow() - 2, p.getCol() + 1);
            nextPoints.add(point);
        }

        return nextPoints;
    }

    public void show() {
        for (int[] chess : chessBoard) {
            for (int i : chess) {
                System.out.print(i + " ");
            }
            System.out.println();
        }
    }
}

/**
 * 坐标
 */
class Coordinate{

    public int row;

    public int col;

    public Coordinate(int row, int col) {
        this.row = row;
        this.col = col;
    }

    public int getRow() {
        return row;
    }

    public void setRow(int row) {
        this.row = row;
    }

    public int getCol() {
        return col;
    }

    public void setCol(int col) {
        this.col = col;
    }

    @Override
    public String toString() {
        return "Coordinate{" +
                "row=" + row +
                ", col=" + col +
                '}';
    }
}

你可能感兴趣的:(算法,java,开发语言)