认识基础的数据结构

一. 单向链表

/**
 * @author zhang
 * 单链表节点
 */
public class Node {


    public int value;
    
    public Node next;

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

}

单链表的翻转

给定一个单链表的头节点,请将单链表翻转过来
例:a->b->c 翻转后 c->b->a

package com.zhang.study.chapter03;

import com.zhang.study.chapter03.node.Node;

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

import static com.zhang.util.NodeUtil.*;

/**
 * @author zhang
 * 翻转链表
 */
public class Code01_ReverseList {


    /**
     * 翻转链表
     *
     * @param head 头节点
     * @return 翻转后链表的头结点
     */
    public static Node reverseLinkedList(Node head) {
       if(head==null){
           return null;
       }
       Node pre = null;
       Node next = null;
       while (head!=null){
           next = head.next;
           head.next = pre;
           pre = head;
           head = next;
       }
        return pre;
    }

    /**
     * 测试
     * @param head 头结点
     * @return 翻转后链表的头结点
     */
    public static Node testReverseLinkedList(Node head) {
        if (head == null) {
            return null;
        }
        ArrayList<Node> list = new ArrayList<>();
        while (head != null) {
            list.add(head);
            head = head.next;
        }
        list.get(0).next = null;
        int N = list.size();
        for (int i = 1; i < N; i++) {
            list.get(i).next = list.get(i - 1);
        }
        return list.get(N - 1);
    }

    public static void main(String[] args) {
        int len = 50;
        int value = 100;
        int testTime = 100000;
        System.out.println("test begin!");
        for (int i = 0; i < testTime; i++) {
            // 生成链表头结点
            Node node1 = generateRandomLinkedList(len, value);
            // 链表头结点值 list
            List<Integer> list1 = getLinkedListOriginOrder(node1);
            // 翻转后的头结点
            node1 = reverseLinkedList(node1);
            if (!checkLinkedListReverse(list1, node1)) {
                System.out.println("Oops1!");
            }

            Node node2 = generateRandomLinkedList(len, value);
            List<Integer> list2 = getLinkedListOriginOrder(node2);
            node2 = testReverseLinkedList(node2);
            if (!checkLinkedListReverse(list2, node2)) {
                System.out.println("Oops2!");
            }

        }
        System.out.println("test finish!");
    }

}

删除链表中给定的值

例: 链表 1->2->3->2->4->6->7 删除链表中所有的 2

package com.zhang.study.chapter03;

import com.zhang.study.chapter03.node.Node;

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

import static com.zhang.util.NodeUtil.*;
import static com.zhang.util.NodeUtil.checkLinkedListReverse;

/**
 * 删除链表中给定的值
 */
public class Code03_RemoveNode {

    /**
     * 删除链表中给定的值
     *
     * @param head 给定的头节点
     * @param num  删除的值
     * @return 删除完成后的头节点
     */
    public static Node removeNode(Node head, int num) {
        while (head != null) {
            if (head.value != num) {
                break;
            }
            head = head.next;
        }
        Node cur = head;
        Node pre = head;
        while (cur != null) {
            if (cur.value == num) {
                pre.next = cur.next;
            } else {
                pre = cur;
            }
            cur = cur.next;
        }
        return head;
    }

    public static List<Node> testRemoveNode(Node head, int num) {
        List<Node> nodes = new ArrayList<>();
        if (head == null) {
            return nodes;
        }
        while (head != null) {
            if (head.value != num) {
                nodes.add(head);
            }
            head = head.next;
        }
        return nodes;
    }

    public static boolean checkRemoveList(List<Node> list, Node head) {
        boolean flag = true;
        if ((list == null || list.isEmpty()) && head == null) {
            return true;
        }
        if (list == null) {
            return false;
        }
        for (Node node : list) {
            if (node.value != head.value) {
                flag = false;
            }
            head = head.next;
        }
        return flag;
    }

    public static void main(String[] args) {
        int len = 500000;
        int value = 1000;
        int testTime = 100;
        System.out.println("test begin!");
        for (int i = 0; i < testTime; i++) {
            // 生成链表头结点
            Node node1 = generateRandomLinkedList(len, value);
            int num = ((int) (Math.random() * value ));
            node1 = removeNode(node1, num);
            List<Node> nodes = testRemoveNode(node1, num);
            if (!checkRemoveList(nodes, node1)) {
                System.out.println("Oops!");
            }

        }
        System.out.println("test finish!");
    }


}

二. 双链表节点

/**
 * @author zhang
 * 双链表节点
 */
public class DoubleNode {

    public int value;

    public DoubleNode next;

    public DoubleNode previous;

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


}

翻转双链表

package com.zhang.study.chapter03;

import com.zhang.study.chapter03.node.DoubleNode;

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

import static com.zhang.util.NodeUtil.*;

/**
 * @author zhang
 * @description 双向链表反转
 */
public class Code02_DoubleNodeReverse {

    /**
     * 翻转双链表
     *
     * @param head 头结点
     * @return 翻转后的头结点
     */
    public static DoubleNode reverse(DoubleNode head) {
       if(head==null){
           return null;
       }
       DoubleNode pre = null;
       DoubleNode next = null;
       while (head!=null){
           next = head.next;
           head.next = pre;
           head.previous = next;
           pre = head;
           head = next;
       }

        return pre;
    }


    public static DoubleNode testReverseDoubleList(DoubleNode head) {
        if (head == null) {
            return null;
        }
        List<DoubleNode> list = new ArrayList<>();
        while (head != null) {
            list.add(head);
            head = head.next;
        }
        list.get(0).next = null;
        DoubleNode pre = list.get(0);
        for (int i = 1; i < list.size(); i++) {
            DoubleNode cur = list.get(i);
            cur.previous = null;
            cur.next = pre;
            pre.previous = cur;
            pre = cur;
        }
        return list.get(list.size() - 1);
    }
    

    public static void main(String[] args) {
        int len = 500;
        int value = 1001;
        int testTime = 100000;
        System.out.println("test begin!");
        for (int i = 0; i < testTime; i++) {

            DoubleNode node3 = generateRandomDoubleList(len, value);
            List<Integer> list3 = getDoubleListOriginOrder(node3);
            node3 = reverse(node3);
            if (!checkDoubleListReverse(list3, node3)) {
                System.out.println("Oops1!");
            }

            DoubleNode node4 = generateRandomDoubleList(len, value);
            List<Integer> list4 = getDoubleListOriginOrder(node4);
            node4 = testReverseDoubleList(node4);
            if (!checkDoubleListReverse(list4, node4)) {
                System.out.println("Oops2!");
            }

        }
        System.out.println("test finish!");


    }

}

  1. IntStream.of(ints)
    IntStream是Java 8中引入的用于处理基本类型int序列的流。IntStream.of(ints)方法接受一个int数组,并返回一个包含该数组所有元素的IntStream。
  2. .boxed()
    boxed()方法将IntStream中的基本类型int元素装箱为Integer对象。这是必要的,因为Java的集合框架(如List)不支持基本数据类型,只支持它们的包装类。
  3. .collect(Collectors.toList())
    collect方法是Stream API中的一个终端操作,用于将流中的元素收集到一个目标中,通常是一个集合或映射。在这里,它使用Collectors.toList()收集器来将流中的Integer对象收集到一个新的List中。

所以,整段代码的作用是:

  • 将int[] ints数组转换为一个IntStream。
  • 将这个IntStream中的基本类型int元素装箱为Integer对象。
  • 将这些Integer对象收集到一个新的List中。

这样就得到了一个包含与原始数组ints相同元素的List。

三、队列

使用双向链表实现队列

package com.zhang.study.chapter03;


import com.zhang.study.chapter03.node.Node;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import static com.zhang.util.NodeUtil.generateRandomLinkedList;
import static com.zhang.util.RandomArrayUtil.generateRandomArray;

/**
 * 使用双链表实现队列
 */
public class Code04_DoubleNodeMyQueue {

    // 双链表节点结构
    public static class DoubleNode<T> {
        public T value;

        public DoubleNode<T> next;

        public DoubleNode<T> previous;

        public DoubleNode(T value) {
            this.value = value;
        }

        public DoubleNode() {
        }
    }

    /**
     * 使用双链表实现的队列 队列:先进先出
     * 队列需要实现的方法:
     * 1. 从头部插入
     * 2. 从尾部插入
     * 3. 从头部取
     * 4. 从尾部取
     */
    public static class MyQueueByDoubleNode<T> {
        public DoubleNode<T> begin;
        public DoubleNode<T> end;

        public MyQueueByDoubleNode() {
        }

        public MyQueueByDoubleNode(Collection<T> collection) {
            if (collection == null) {
                throw new NullPointerException("collection is null");
            }
            if (collection.isEmpty()) {
                throw new RuntimeException("collection is empty");
            }

            for (T t : collection) {
                DoubleNode<T> node = new DoubleNode<>(t);
                if (begin == null) {
                    begin = node;
                } else {
                    node.previous = end;
                    end.next = node;
                }
                end = node;
            }
        }

        /**
         * 从头部加入元素
         *
         * @param data 元素
         */
        public void addFromHead(T data) {
            DoubleNode<T> node = new DoubleNode<>(data);
            if (begin == null) {
                begin = node;
                end = node;
            } else {
                node.next = begin;
                begin.previous = node;
                begin = node;
            }
        }

        /**
         * 从尾部加入元素
         *
         * @param data 元素
         */
        public void addFromEnd(T data) {
            DoubleNode<T> node = new DoubleNode<>(data);
            if (begin == null) {
                begin = node;
            } else {
                end.next = node;
                node.previous = end;
            }
            end = node;
        }

        /**
         * 从头部移除元素
         *
         * @return 移除的元素
         */
        public T removeFromHead() {
            if (begin == null) {
                return null;
            }
            DoubleNode<T> cur = begin;
            if (begin == end) {
                begin = null;
                end = null;
            } else {
                begin = cur.next;
                cur.next = null;
                begin.previous = null;
            }
            return cur.value;
        }

        /**
         * 从尾部删除元素
         *
         * @return 删除元素
         */
        public T removeFromEnd() {
            if (end == null) {
                return null;
            }
            DoubleNode<T> cur = end;
            if (begin == end) {
                begin = null;
                end = null;
            } else {
                end = cur.previous;
                cur.previous = null;
                end.next = null;
            }
            return cur.value;
        }


    }

    public static void main(String[] args) {
        int len = 5000;
        int value = 10000;
        int testTime = 10000;

        System.out.println("test begin!");
        for (int i = 0; i < testTime; i++) {
            // 生成链表头结点
            int[] intArr = generateRandomArray(len, value);
            List<Integer> collect = IntStream.of(intArr).boxed().collect(Collectors.toList());
            MyQueueByDoubleNode<Integer> myQueueByDoubleNode = new MyQueueByDoubleNode<>(collect);
            LinkedList<Integer> linkedList = new LinkedList<>(collect);
            if (!testQueue(myQueueByDoubleNode, linkedList)) {
                System.out.println("Oops!");
            }
        }
        System.out.println("test finish!");

    }

    private static boolean testQueue(MyQueueByDoubleNode<Integer> myQueueByDoubleNode, LinkedList<Integer> linkedList) {
        int times = linkedList.size() - 1;
        while (times >= 0) {
            double random = Math.random();
            int i = (int) (Math.random() * 100 - Math.random() * 10);
            if (random >= 0.75) {
                // 从头部加一个元素
                myQueueByDoubleNode.addFromHead(i);
                linkedList.addFirst(i);
            } else if (random >= 0.5) {
                // 从尾部加一个元素
                myQueueByDoubleNode.addFromEnd(i);
                linkedList.addLast(i);
            } else if (random >= 0.25) {
                // 从头部删除一个元素
                Integer integer = myQueueByDoubleNode.removeFromHead();
                Integer integer1 = linkedList.removeFirst();
                if (testValid(integer, integer1)) return false;
            } else {
                // 从尾部删除一个元素
                Integer integer = myQueueByDoubleNode.removeFromEnd();
                Integer integer1 = linkedList.removeLast();
                if (testValid(integer, integer1)) return false;
            }
            times--;
        }
        while (!linkedList.isEmpty()) {
            Integer integer = myQueueByDoubleNode.removeFromHead();
            Integer first = linkedList.removeFirst();
            if (!integer.equals(first)) {
                return false;
            }
        }
        return true;
    }

    private static boolean testValid(Integer integer, Integer integer1) {
        if ((integer == null && integer1 != null) || (integer1 == null && integer != null)) {
            return true;
        }
        if (!(integer == null)) {
            return !integer.equals(integer1);
        }
        return false;
    }


}

使用数组实现队列

使用 size 解耦 pushIndex 和 popIndex

package com.zhang.study.chapter03;

import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import static com.zhang.util.RandomArrayUtil.generateRandomArray;

/**
 * 使用数组实现队列
 */
public class Code05_ArrayMyQueue {

    /**
     * 使用数组实现队列
     *
     * @param <T>
     */
    public static class ArrayMyQueue<T> {
        public Object[] eleData;
        /**
         * 添加时元素的index
         */
        public int pushIndex;
        /**
         * 弹出元素时的index
         */
        public int popIndex;
        /**
         * 实际大小
         */
        public int fullSize;


        public ArrayMyQueue(int capacity) {
            this.fullSize = 0;
            this.pushIndex = 0;
            this.popIndex = 0;
            this.eleData = new Object[capacity];
        }

        /**
         * 队列尾部添加元素
         *
         * @param ele 添加元素
         */
        public void push(T ele) {
            if (eleData.length == fullSize) {
                throw new RuntimeException("queue is full!");
            }
            fullSize++;
            eleData[pushIndex] = ele;
            pushIndex = nextIndex(pushIndex);
        }

        public T pop() {
            if (fullSize == 0) {
                throw new RuntimeException("queue is empty!");
            }
            fullSize--;
            T ans = (T) (eleData[popIndex]);
            popIndex = nextIndex(popIndex);
            return ans;
        }


        public int nextIndex(int index) {
            // return index == eleData.length - 1 ? 0 : ++index;
            return (index + 1) % eleData.length;
        }

        public static void main(String[] args) {
            int len = 5000;
            int value = 10000;
            int testTime = 10000;

            System.out.println("test begin!");
            for (int i = 0; i < testTime; i++) {
                // 生成链表头结点
                int[] intArr = generateRandomArray(len, value);
                List<Integer> collect = IntStream.of(intArr).boxed().collect(Collectors.toList());
                LinkedList<Integer> linkedList = new LinkedList<>(collect);
                ArrayMyQueue<Integer> myQueue = new ArrayMyQueue<>(intArr.length + 1000);
                for (Integer integer : collect) {
                    myQueue.push(integer);
                }
                if (!testQueue(myQueue, linkedList)) {
                    System.out.println("Oops!");
                }
            }
            System.out.println("test finish!");
        }

        private static boolean testQueue(ArrayMyQueue<Integer> myQueue, LinkedList<Integer> linkedList) {
            int times = linkedList.size() - 1;
            while (times >= 0) {
                double random = Math.random();
                int i = (int) (Math.random() * 100 - Math.random() * 10);
                if (random >= 0.5) {
                    // 从尾部加一个元素
                    myQueue.push(i);
                    linkedList.addLast(i);
                } else {
                    // 从尾部删除一个元素
                    Integer integer = myQueue.pop();
                    Integer integer1 = linkedList.remove();
                    if (!Objects.equals(integer1, integer)) {
                        return false;
                    }
                }
                times--;
            }
            while (!linkedList.isEmpty()) {
                Integer integer = myQueue.pop();
                Integer first = linkedList.removeFirst();
                if (!integer.equals(first)) {
                    return false;
                }
            }
            return true;


        }

    }


}

使用数组实现双端队列

package com.zhang.study.chapter03;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import static com.zhang.util.RandomArrayUtil.generateRandomArray;

/**
 * 使用数组实现双端队列
 */
public class Code07_ArrayMyDeque {

    public static class ArrayMyDeque<T> {
        // 队列元素存储的数组
        private Object[] elements;
        // 队首位置,指向队列第一个元素的下一个位置
        private int head;
        // 队尾位置,指向队列最后一个元素的下一个位置
        private int tail;
        // 队列中的元素数量
        private int size;

        public ArrayMyDeque(int capacity) {
            elements = new Object[capacity]; // 创建一个指定容量的Object数组
            head = 0; // 初始化队首位置
            tail = 0; // 初始化队尾位置
            size = 0; // 初始化队列大小为0
        }

        // 在队尾添加元素
        public void addLast(T ele) {
            if (size == elements.length) {
                throw new RuntimeException("deque is Full!");
            }
            // 在队列尾部 当第一次进来时 直接在0位置放入元素 然后尾指针向后移动
            elements[tail] = ele;
            // 第一次 1 & elements.length - 1 == 1
            tail = (tail + 1) & (elements.length - 1);
            size++;
        }

        // 在队尾删除元素
        public T popLast() {
            if (size == 0) {
                throw new RuntimeException("deque is empty!");
            }
            // 由于我们在队尾添加元素时,都是先放入再指向下一个 所以取的时候需要 - 1
            int lastIndex = (tail - 1) & (elements.length - 1);
            Object item = elements[lastIndex]; // 获取队尾元素
            elements[lastIndex] = null; // 释放队尾元素的引用
            tail = lastIndex; // 更新队尾位置为最后一个元素的索引
            size--; // 队列大小减1
            return (T) item;
        }

        // 在队首添加元素
        public void addFirst(T ele) {
            if (ele == null) {
                throw new NullPointerException("Cannot add null element to deque");
            }
            if (size == elements.length) {
                // 这里可以添加扩容逻辑,如果不希望扩容,则抛出异常或返回false
                throw new IllegalStateException("Deque is full and cannot be expanded");
            }
            // 第一次进来时,默认在index 为0 前面加入元素 直接到数组最后
            head = (head - 1) & (elements.length - 1); // 循环回到数组开头
            elements[head] = ele;
            size++;
        }

        // 在队首删除元素
        public T popFirst() {
            if (size == 0) {
                throw new NoSuchElementException("Deque is empty");
            }
            // 在队首添加元素时,我们是先算好指针再放入元素,所以这里可以直接先取
            T result = (T) elements[head];
            elements[head] = null; // 清除旧元素引用
            head = (head + 1) & (elements.length - 1); // 移动到下一个位置
            size--;
            return result;
        }

    }

    public static void main(String[] args) {
        int len = 5;
        int value = 10;
        int testTime = 1;
        System.out.println("test begin!");
        for (int i = 0; i < testTime; i++) {
            // 生成链表头结点
            int[] intArr = generateRandomArray(len, value);
            List<Integer> collect = IntStream.of(intArr).boxed().collect(Collectors.toList());
            ArrayMyDeque<Integer> arrayMyDeque = new ArrayMyDeque<>(16);
            LinkedList<Integer> linkedList = new LinkedList<>();
            ArrayDeque<Integer> integers = new ArrayDeque<>();
            for (Integer integer : collect) {
                arrayMyDeque.addFirst(integer);
                integers.addFirst(integer);
                linkedList.addFirst(integer);
            }
            if (!testQueue(arrayMyDeque, linkedList)) {
                System.out.println("Oops!");
                System.out.println("arrayMyDeque");
                while (arrayMyDeque.size != 0) {
                    System.out.print(arrayMyDeque.popLast() + "\t");
                }
                System.out.println(" ");
                System.out.println("linkedList");
                while (!linkedList.isEmpty()) {
                    System.out.print(linkedList.removeLast() + "\t");
                }
                System.out.println(" ");
                System.out.println("ArrayDeque");
                while (!integers.isEmpty()) {
                    System.out.print(integers.removeLast() + "\t");
                }
                System.out.println(" ");

            }
        }
        System.out.println("test finish!");

    }


    private static boolean testQueue(ArrayMyDeque<Integer> arrayMyDeque, LinkedList<Integer> linkedList) {
        int times = linkedList.size() - 1;
        while (times >= 0) {
            double random = Math.random();
            int i = (int) (Math.random() * 100 - Math.random() * 10);
            if (random >= 0.75) {
                // 从头部加一个元素
                arrayMyDeque.addFirst(i);
                linkedList.addFirst(i);
            } else if (random >= 0.5) {
                // 从尾部加一个元素
                arrayMyDeque.addLast(i);
                linkedList.addLast(i);
            } else if (random >= 0.25) {
                // 从头部删除一个元素
                Integer integer = arrayMyDeque.popFirst();
                Integer integer1 = linkedList.removeFirst();
                if (testValid(integer, integer1)) return false;
            } else {
                // 从尾部删除一个元素
                Integer integer = arrayMyDeque.popLast();
                Integer integer1 = linkedList.removeLast();
                if (testValid(integer, integer1)) return false;
            }
            times--;
        }
        while (!linkedList.isEmpty()) {
            Integer integer = arrayMyDeque.popFirst();
            Integer first = linkedList.removeFirst();
            if (!Objects.equals(integer, first)) {
                return false;
            }
        }
        return true;
    }

    private static boolean testValid(Integer integer, Integer integer1) {
        if ((integer == null && integer1 != null) || (integer1 == null && integer != null)) {
            return true;
        }
        if (!(integer == null)) {
            return !integer.equals(integer1);
        }
        return false;
    }
}

四、栈

使用单向链表实现栈

因为栈这个结构是先进后出,我们只需要维护一个头节点,头节点指向向下的节点,每次出栈时维护头节点即可。

package com.zhang.study.chapter03;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import static com.zhang.util.RandomArrayUtil.generateRandomArray;

/**
 * 使用单链表实现栈结构
 */
public class Code04_NodeMyStack {

    public static class Node<T> {
        public T value;

        public Node<T> next;

        public Node() {
        }

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

    public static class NodeMyStack<T> {
        public Node<T> head;

        public NodeMyStack() {
        }

        public NodeMyStack(Collection<T> collection) {
            if (collection == null || collection.isEmpty()) {
                throw new RuntimeException("collection is empty");
            }
            for (T t : collection) {
                push(t);
            }
        }


        /**
         * 实现元素入栈出栈功能
         */

        public void push(T data) {
            Node<T> tNode = new Node<>(data);
            if (head != null) {
                tNode.next = head;
            }
            head = tNode;
        }


        public T pop() {
            if (head == null) {
                return null;
            }
            Node<T> cur = head;

            head = head.next;

            return cur.value;
        }


    }


    public static void main(String[] args) {
        int len = 5000;
        int value = 10000;
        int testTime = 10000;
        int sizeTime;
        System.out.println("test begin!");
        for (int i = 0; i < testTime; i++) {
            // 生成链表头结点
            int[] intArr = generateRandomArray(len, value);
            List<Integer> collect = IntStream.of(intArr).boxed().collect(Collectors.toList());
            NodeMyStack<Integer> nodeMyStack = new NodeMyStack<>(collect);
            Stack<Integer> stack = new Stack<>();
            for (Integer integer : collect) {
                stack.push(integer);
            }
            sizeTime = collect.size() - 1;
            if (!testMyStack(nodeMyStack, stack, sizeTime)) {
                System.out.println("Oops!");
            }
        }
        System.out.println("test finish!");
    }

    private static boolean testMyStack(NodeMyStack<Integer> nodeMyStack, Stack<Integer> stack, int sizeTime) {
        int times = sizeTime;
        while (times >= 0) {
            double random = Math.random();
            int i = (int) (Math.random() * 100 - Math.random() * 10);
            if (random >= 0.5) {
                // 入栈
                nodeMyStack.push(i);
                stack.push(i);
            } else {
                // 出栈
                Integer pop1 = nodeMyStack.pop();
                Integer pop2 = stack.pop();
                if (!Objects.equals(pop1, pop2)) {
                    return false;
                }
            }
            times--;
        }
        while (!stack.isEmpty()) {
            Integer pop1 = stack.pop();
            Integer pop2 = nodeMyStack.pop();
            if (!Objects.equals(pop1, pop2)) {
                return false;
            }
        }
        return true;
    }

}

使用数组实现栈

使用数组实现栈功能,我们可以使用一个数组或者动态数组,然后用一个变量(动态数组有 size()) 来记录当前栈总共有多少个元素,然后每次入栈记录一下,出栈时我们通过数组长度弹出最后一个值。

我们想通过构造函数传入数组长度,创建对应长度的数组。在Java中,泛型类不能直接创建泛型数组,因为泛型的类型信息在运行时会被擦除,导致编译器无法确定数组的确切类型。所以这里使用动态数组。

package com.zhang.study.chapter03;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Stack;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import static com.zhang.util.RandomArrayUtil.generateRandomArray;

/**
 * 使用数组实现栈
 */
public class Code06_ArrayMyStack {
    /**
     * 实现两个方法 一个入栈一个出栈
     * 最好再来一个peek方法 查看栈中弹出哪个元素 但不是真正弹出只是查看
     */
    public static class ArrayMyStack<T> {
        public ArrayList<T> stack;

        public ArrayMyStack(int size) {
            this.stack = new ArrayList<>(size);
        }

        public void push(T value) {
            stack.add(value);
        }

        public T pop() {
            if (stack.isEmpty()) {
                throw new RuntimeException("stack is empty!");
            }
            int index = stack.size() - 1;
            return stack.remove(index);
        }

        public T peek() {
            if (stack.isEmpty()) {
                return null;
            }
            int index = stack.size() - 1;
            return stack.get(index);
        }


    }


    public static void main(String[] args) {
        int len = 5;
        int value = 100;
        int testTime = 10000;
        int sizeTime;
        System.out.println("test begin!");
        for (int i = 0; i < testTime; i++) {
            // 生成链表头结点
            int[] intArr = generateRandomArray(len, value);
            List<Integer> collect = IntStream.of(intArr).boxed().collect(Collectors.toList());
            Code04_NodeMyStack.NodeMyStack<Integer> nodeMyStack = new Code04_NodeMyStack.NodeMyStack<>(collect);
            ArrayMyStack<Integer> stack = new ArrayMyStack<>(collect.size());
            for (Integer integer : collect) {
                stack.push(integer);
            }
            sizeTime = collect.size() - 1;
            if (!testMyStack(nodeMyStack, stack, sizeTime)) {
                System.out.println("Oops!");
            }
        }
        System.out.println("test finish!");
    }

    private static boolean testMyStack(Code04_NodeMyStack.NodeMyStack<Integer> nodeMyStack, ArrayMyStack<Integer> stack, int sizeTime) {
        int times = sizeTime;
        while (times >= 0) {
            double random = Math.random();
            int i = (int) (Math.random() * 100 - Math.random() * 10);
            if (random >= 0.5) {
                // 入栈
                nodeMyStack.push(i);
                stack.push(i);
            } else {
                // 出栈
                Integer pop1 = nodeMyStack.pop();
                Integer pop2 = stack.pop();
                if (!Objects.equals(pop1, pop2)) {
                    return false;
                }
            }
            times--;
        }
        while (stack.peek() != null) {
            Integer pop1 = stack.pop();
            Integer pop2 = nodeMyStack.pop();
            if (!Objects.equals(pop1, pop2)) {
                return false;
            }
        }
        return true;
    }


}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值