数据结构

算法

队列

public class ArrayQueue {
    private int head;
    private int tail;
    private final int[] nums;
    private final int maxSize;

    public ArrayQueue(int maxSize) {
        this.maxSize = maxSize + 1;
        nums = new int[this.maxSize];
    }

    public boolean isEmpty() {
        return head == tail;
    }

    public boolean isFull() {
        return (tail + 1) % maxSize == head;
    }

    public int size() {
        return (tail + maxSize - head) % maxSize;
    }

    public void add(int num) {
        if (!isFull()) {
            nums[tail] = num;
            tail = (tail + 1) % maxSize;
        } else {
            throw new RuntimeException("队列已满");
        }
    }

    public int pop() {
        if (!isEmpty()) {
            int result = nums[head];
            head = (head + 1) % maxSize;
            return result;
        }
        throw new RuntimeException("队列为空");
    }

    @Override
    public String toString() {
        int[] nums = new int[size()];
        for (int i = head; i < head + size(); i++) {
            nums[i - head] = this.nums[i % maxSize];
        }
        return Arrays.toString(nums);
    }
}

public class ArrayStack {
    private final int maxSize;
    private int top = -1;
    private final int[] nums;

    public ArrayStack(int maxSize) {
        this.maxSize = maxSize;
        nums = new int[maxSize];
    }

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

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

    public void push(int n) {
        if (isFull()) {
            throw new RuntimeException("栈已满");
        }
        nums[++top] = n;
    }

    public int pop() {
        if (isEmpty()) {
            throw new RuntimeException("栈已空");
        }
        return nums[top--];
    }

    @Override
    public String toString() {
        int[] nums = new int[top + 1];

        for (int i = top, j = 0; i >= 0; i--) {
            nums[j] = this.nums[i];
            j++;
        }
        return Arrays.toString(nums);
    }
}

实现计算器

public class IntCalculator {
    private static final Map<String, Integer> PRIORITY = new HashMap<>() {
        {
            put("+", 1);
            put("-", 1);
            put("*", 2);
            put("/", 2);
        }
    };

    //获得运算符的优先级
    private static int getPriority(String operator) {
        if (PRIORITY.containsKey(operator)) {
            return PRIORITY.get(operator);
        }
        return 0;
    }

    //将前缀表达式的字符拆分,便于遍历
    private static List<String> getInfixExpressionList(String expression) {
        List<String> list = new ArrayList<>();
        Pattern pattern = Pattern.compile("(\\d+)|(\\D)");
        Matcher matcher = pattern.matcher(expression);

        while (matcher.find()) {
            list.add(matcher.group());
        }
        return list;
    }

    private static List<String> transferToSuffixExpression(List<String> infixExpression) {

        //符号栈
        Stack<String> stack = new Stack<>();
        List<String> result = new ArrayList<>();

        for (String item : infixExpression) {
            if (item.matches("\\d+")) {
                result.add(item);

            } else if (item.equals("(")) {
                stack.push(item);

            } else if (item.equals(")")) {
                while (!stack.peek().equals("(")) {
                    result.add(stack.pop());
                }

                //弹出左括号
                stack.pop();

            } else {
                //如果是运算符

                while (!stack.empty() && getPriority(item) <= getPriority(stack.peek())) {
                    result.add(stack.pop());
                }
                stack.push(item);
            }
        }

        while (!stack.empty()) {
            result.add(stack.pop());
        }
        return result;
    }

    public static List<String> transferToSuffixExpression(String expression) {
        return transferToSuffixExpression(getInfixExpressionList(expression));
    }


    public static int calculate(String expression) {
        List<String> infixExpression = getInfixExpressionList(expression);
        List<String> suffixExpression = transferToSuffixExpression(infixExpression);

        Stack<Integer> stack = new Stack<>();

        for (String item : suffixExpression) {

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

                stack.push(Integer.parseInt(item));
            } else {
                int n1 = stack.pop();
                int n2 = stack.pop();
                stack.push(operate(n1, n2, item.charAt(0)));
            }
        }
        return stack.pop();
    }

    private static int operate(int n1, int n2, char operator) {
        switch (operator) {
            case '+':
                return n1 + n2;
            case '-':
                return n2 - n1;
            case '*':
                return n1 * n2;
            case '/':
                return n2 / n1;
        }
        throw new RuntimeException("运算符错误");
    }
}

链表

单链表

节点
public class Node {
    Integer id;
    Object data;
    Node next;
}
public class SingleLinkedList {
    private Node head = new Node();

    public void setHead(Node head) {
        this.head = head;
    }

    public int length() {
        int length = 0;
        Node current = head;

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

    public Node get(int index) {
        if (index < 0 || index > length()) {
            return null;
        }

        Node current = head.next;
        for (int i = 0; i < index; i++) {
            current = current.next;
        }
        return current;
    }

    public Node getReverse(int index) {
        return get(length() - index - 1);
    }

    public void add(Node node) {
        Node current = head;
        while (true) {
            if (current.next == null) {
                current.next = node;
                break;
            }
            current = current.next;
        }
    }

    public void addByOrderId(Node node) {
        Node current = head;

        while (true) {
            if (current.next == null) {
                break;
            }
            if (node.id < current.next.id) {
                break;
            }
            current = current.next;
        }
        node.next = current.next;
        current.next = node;
    }

    public void insert(int index, Node node) {
        Node current = head;

        for (int i = 0; i < index; i++) {
            current = current.next;
        }

        node.next = current.next;
        current.next = node;
    }

    public void update(int id, Object data) {
        Node current = head.next;

        while (true) {
            if (current == null) {
                break;
            } else if (current.id == id) {
                current.data = data;
                break;
            }
            current = current.next;
        }
    }

    public void delete(int index) {
        if (index < 0) {
            return;
        }

        Node current = head;

        for (int i = 0; i < index; i++) {
            if (current.next != null) {
                current = current.next;
            }
        }
        if (current.next != null) {
            current.next = current.next.next;
        }
    }

    public void reverse() {
        if (this.head.next == null || this.head.next.next == null) {
            return;
        }
        Node head = new Node();
        Node current = this.head.next;
        Node next;

        while (current != null) {
            next = current.next;
            current.next = head.next;
            head.next = current;
            current = next;
        }

        this.head = head;
    }

    public String reversedPrint() {
        List<Node> nodes = new ArrayList<>();
        Node current = head.next;

        while (current != null) {
            nodes.add(current);
            current = current.next;
        }

        Collections.reverse(nodes);
        return nodes.toString();
    }

    public CircularLinkedList getCircularLinkedList(int size) {
        if (size < 0) {
            return null;
        }

        Node last = null;

        for (int i = 0; i < size; i++) {
            Node node = new Node(i);
            this.add(node);

            if (i == size - 1) {
                last = node;
            }
        }
        Node first = head.next;
        head.next = null;
        last.next = first;

        return new CircularLinkedList(last, first);
    }

    @Override
    public String toString() {
        List<Node> nums = new ArrayList<>();
        Node current = head.next;

        while (current != null) {
            nums.add(current);
            current = current.next;
        }
        return String.valueOf(nums);
    }
}

循环链表

public class CircularLinkedList {
    Node previous;
    Node current;

    public CircularLinkedList(Node previous, Node current) {
        this.previous = previous;
        this.current = current;
    }

    public List<Integer> popList(int start, int step) {
        if (start < 0 || current == null) {
            return null;
        }

        for (int i = 0; i < start; i++) {
            previous = previous.next;
        }
        current = previous.next;
        List<Integer> list = new ArrayList<>();
        while (true) {
            if (previous == current) {
                break;
            }
            for (int i = 0; i < step - 1; i++) {
                previous = previous.next;
                current = current.next;
            }
            list.add(current.id);
            current = current.next;
            previous.next = current;
        }
        list.add(current.id);
        return list;
    }

    @Override
    public String toString() {
        return "CircularLinkedList{" +
                "previous=" + previous +
                ", current=" + current +
                '}';
    }
}

双向链表

节点
public class PnNode {
    Integer id;
    PnNode next;
    PnNode previous;
    Object data;
}
public class DoublyLinkedList {
    private PnNode head = new PnNode();

    public void add(PnNode node) {
        PnNode current = head;
        while (true) {
            if (current.next == null) {
                current.next = node;
                node.previous = current;
                break;
            }
            current = current.next;
        }
    }

    public void addOrderById(PnNode node) {
        PnNode current = head;

        while (current.next != null) {
            current = current.next;

            if (node.id < current.id) {
                current.previous.next = node;
                node.previous = current.previous;
                node.next = current;
                current.previous = node;
                return;
            }
        }
        current.next = node;
        node.previous = current;
    }

    public void delete(int index) {
        if (index < 0) {
            return;
        }

        PnNode current = head.next;

        for (int i = 0; i < index; i++) {
            if (current.next == null) {
                return;
            }
            current = current.next;
        }
        current.previous.next = current.next;
        if (current.next != null) {
            current.next.previous = current.previous;
        }
    }

    public void update(int index, Object data) {
        if (index < 0) {
            return;
        }
        PnNode current = head.next;

        for (int i = 0; i < index; i++) {
            if (current.next == null) {
                return;
            }
            current = current.next;
        }
        current.data = data;
    }

    @Override
    public String toString() {
        List<PnNode> nums = new ArrayList<>();
        PnNode current = head.next;

        while (current != null) {
            nums.add(current);
            current = current.next;
        }
        return String.valueOf(nums);
    }
}

哈希表

节点
class Node {
    Integer id;
    Object data;
    Node next;

    public Node() {
    }

    public Node(int id, Object data) {
        this.id = id;
        this.data = data;
    }

    @Override
    public String toString() {
        return "Node{" +
                "id=" + id +
                ", data=" + data +
                '}';
    }
}
链表
public class LinkedList {
    Node head = new Node();
    Node tail = head;

    void setTail(Node tail) {
        this.tail.next = tail;
        this.tail = tail;
    }

    public Node get(int id) {
        Node current = head.next;

        while (current != tail.next) {
            if (id == current.id) {
                return current;
            }
            current = current.next;
        }
        return current;
    }

    @Override
    public String toString() {
        List<Node> nodes = new ArrayList<>();
        Node current = head.next;

        while (current != tail.next) {
            nodes.add(current);
            current = current.next;
        }

        return "长度为:" + nodes.size() + ',' + nodes;
    }
}
哈希表
public class Hashtable {

    private final int size;
    private final LinkedList[] table;

    public Hashtable(int size) {
        this.size = size;
        table = new LinkedList[size];

        for (int i = 0; i < size; i++) {
            table[i] = new LinkedList();
        }
    }

    public void add(int id, Object data) {
        table[getIndex(id)].setTail(new Node(id, data));
    }

    public Node get(int id) {
        return table[getIndex(id)].get(id);
    }

    private int getIndex(int id) {
        return id % size;
    }

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();

        for (int i = 0; i < size; i++) {
            builder.append(i);
            builder.append(',');
            builder.append(table[i]);
            builder.append('\n');
        }

        return "Hashtable{" +
                '\n' +
                builder +
                '}';
    }
}

平衡树

节点
public class Node {
    private Node left;
    private Node right;
    private int num;

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

    public void add(Node node) {
        if (node == null) {
            return;
        }

        //添加在左子树
        if (node.num < this.num) {
            if (left == null) {
                left = node;
            } else {
                left.add(node);
            }
            return;
        }

        //添加在右子树
        if (right == null) {
            right = node;
        } else {
            right.add(node);
        }


        //判断是否平衡

        if (rightHeight() - leftHeight() > 1) {
            if (right != null && right.leftHeight() > right.rightHeight()) {
                right.rightRotation();
            }
            leftRotation();
            return;
        }

        if (leftHeight() - rightHeight() > 1) {
            if (left != null && left.leftHeight() > left.rightHeight()) {
                left.leftRotation();
            }

            rightRotation();
        }
    }

    public Node[] search(int num, Node parent) {
        if (num == this.num) {
            return new Node[]{this, parent};
        }

        if (num < this.num) {
            if (left == null) {
                return null;
            }
            return left.search(num, this);
        }

        if (right == null) {
            return null;
        }
        return right.search(num, this);
    }

    public int height() {
        if (left == null && right == null) {
            return 0;
        }
        return Math.max(leftHeight(), rightHeight());
    }

    public int leftHeight() {
        if (left == null) {
            return 0;
        }

        return left.height() + 1;
    }


    public int rightHeight() {
        if (right == null) {
            return 0;
        }
        return right.height() + 1;
    }

    public void leftRotation() {

        //新节点保存根节点属性
        Node node = new Node(num);
        node.left = left;
        node.right = right.left;

        //新节点变为根节点的左子节点
        left = node;

        //根节点的右节点代替它的位置,属性覆盖
        num = right.num;
        right = right.right;

    }

    public void  rightRotation() {
        Node node = new Node(num);
        node.right = right;
        node.left = left.right;

        right = node;

        num = left.num;
        left = left.left;

    }


    public List<Node> inorderTraversal(List<Node> nodes) {
        if (left != null) {
            left.inorderTraversal(nodes);
        }

        nodes.add(this);

        if (right != null) {
            right.inorderTraversal(nodes);
        }
        return nodes;
    }

    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 int getNum() {
        return num;
    }

    public void setNum(int num) {
        this.num = num;
    }

    @Override
    public String toString() {
        return "Node{" +
                "num=" + num +
                '}';
    }
}
平衡树
public class BinarySortTree {
    private Node root;

    public BinarySortTree(int[] nums) {
        root = new Node(nums[0]);

        for (int i = 1; i < nums.length; i++) {
            add(new Node(nums[i]));
        }
    }

    public void add(Node node) {
        if (root == null) {
            root = node;
        } else {
            root.add(node);
        }
    }

    public void delete(int num) {
        Node[] nodes = root.search(num, null);

        //查找不到该节点
        if (nodes == null) {
            System.out.println("没有此节点");
            return;
        }

        Node node = nodes[0];
        Node parent = nodes[1];

        //只有一个节点
        if (root.getLeft() == null && root.getRight() == null) {
            root = null;
            return;
        }

        //node为叶子节点
        if (node.getLeft() == null && node.getRight() == null) {

            //判断node节点的位置
            if (parent.getLeft() == node) {
                parent.setLeft(null);

            } else
                parent.setRight(null);
            return;
        }


        //node有左右节点
        if (node.getLeft() != null && node.getRight() != null) {

            //找到目标节点右子树最小值代替目标的值,同时删除最小值节点
            int min = getMinNodeNum(node.getRight());
            delete(min);
            node.setNum(min);
            return;
        }


        /*
         * node只有一个子节点的情况
         *
         * node的子节点代替将node的位置
         *
         * node为parent的左子节点,则node子节点变为parent的左子节点
         * node为parent的右子节点,则node子节点变为parent的右子节点
         */

        //node的一个节点为左子节点
        if (node.getLeft() != null) {
            if (parent == null) {
                setRoot(node.getLeft());
                return;
            }

            if (parent.getLeft() == node) {
                parent.setLeft(node.getLeft());
            } else {
                parent.setRight(node.getLeft());
            }

        } else {

            //node的一个节点为右子节点
            if (parent == null) {
                setRoot(node.getRight());
                return;
            }

            if (parent.getLeft() == node) {
                parent.setLeft(node.getRight());
            } else {
                parent.setRight(node.getRight());
            }
        }

    }

    private int getMinNodeNum(Node node) {
        Node current = node;

        while (current.getLeft() != null) {
            current = current.getLeft();
        }

        return current.getNum();
    }

    public List<Node> inorderTraversal() {
        List<Node> nodes = new ArrayList<>();
        return root.inorderTraversal(nodes);
    }

    public int height() {
        return root.height();
    }

    public int leftHeight() {
        return root.getLeft().height();
    }


    public int rightHeight() {
        return root.getRight().height();
    }

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

参考

尚硅谷Java数据结构与java算法(Java数据结构与算法)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值