数据结构--栈和队列

一、栈(stack)

1、定义

栈也是一种线性的数据结构

规定的是只能从栈顶添加元素、也只能从栈顶去除元素

·栈是一种后进先出的数据结构

·Last In First Out (LIFO)

2、栈的具体实现

public interface Stack_I<T> {
    //入栈
    void push(T ele);

    //出栈
    T pop();

    //查看栈顶元素
    T peek();

    //判断栈是否为空
    boolean isEmpty();

    //判断栈中元素的个数
    int getSize();
}

3、时间复杂度分析

4、数组栈

以数组作为栈的底层结构实现一个私有的栈结构

//  以数组作为栈的底层数据结构
public class ArrStack<T> implements Stack_I<T> {

    private MyArr<T> data;//容器
    int size; //栈中实际存放元素的个数

    public ArrStack() {
        this.data = new MyArr<>(100);
        this.size = 0;
    }

    @Override
    public void push(T ele) {
        this.data.add(ele);
        this.size++;
    }

    @Override
    public T pop() {
        if (isEmpty()){
            return null;
        }
        this.size--;
        return this.data.removeFromLast();
    }

    @Override
    public T peek() {
        return this.data.getLastValue();
    }

    @Override
    public boolean isEmpty() {
        return this.size == 0;
    }

    @Override
    public int getSize() {
        return this.size;
    }
}

5、测试

public class StackTest<T> {

    public void test(Stack_I<T> stack, List<T> list) {
        //开始时间
        long startTime = System.nanoTime();
        //入栈
        for (int i = 0; i < list.size(); i++) {
            stack.push(list.get(i));
        }
        System.out.println("栈中元素的个数:" + stack.getSize());
        //出栈操作
        while (!stack.isEmpty()) {
            T ele = stack.pop();
            System.out.print(ele + "---->");
        }

        //结束时间
        long endTime = System.nanoTime();
        System.out.println("总耗时:" + (endTime - startTime) / 1000000000.0 + "s");
    }

    public static void main(String[] args) {
        StackTest<Integer> stackTest = new StackTest<>();
        Stack_I<Integer> stack = new LinkedStack<>();
        List<Integer> list = new ArrayList<>();
        Random random = new Random();
        for (int i = 0; i < 100; i++) {
            int val = random.nextInt(1000);
            System.out.print(val + "---->");
            list.add(val);
        }

        stackTest.test(stack, list);
    }
}

二、队列

1、定义

队列也是一种线性的数据结构

规定只能从一端的队尾添加元素,从另一端的队首取出元素

        

·队列是一种先进先出的数据结构

2、队列的实现

public interface Queue_I<T> {

    //入队
    void offer(T ele);

    //出队
    T poll();

    //查看队首元素
    T peek();

    //队列中元素的个数
    int getSize();

    //队列是否为空
    boolean isEmpty();
}

3、数组队列的问题

        其中dequeue()操作的时间复杂度为O(n),原因时在出队时,数组后面的元素都要进行前移。

删除队首元素a后,

为了解决前移的问题,可以使用front记录队首位置,使用tail记录队尾位置,这就是循环队列。

情况1:

情况2:

情况3:

 

4、循环队列的复杂度分析

5、数组队列结构的实现

public class ArrQueue<T> implements Queue_I<T> {

    //队列的容器
    private MyArr<T> data;

    public ArrQueue() {
        this.data = new MyArr<>(100);
    }

    @Override
    public void offer(T ele) {
        this.data.add(ele);
    }

    @Override
    public T poll() {
        if (isEmpty()) {
            return null;
        }
        return this.data.removeByIndex(0);
    }

    @Override
    public T peek() {
        if (isEmpty()) {
            return null;
        }
        return this.data.getValueByIndex(0);
    }

    @Override
    public int getSize() {
        return this.data.getSize();
    }

    @Override
    public boolean isEmpty() {
        return this.data.isEmpty();
    }
}

6、测试

public class QueueTest<T> {

    public void test(Queue_I<T> queue, List<T> list) {
        //开始时间
        long startTime = System.nanoTime();
        //入队列
        for (int i = 0; i < list.size(); i++) {
            T temp = list.get(i);
            System.out.print(temp+"---");
            queue.offer(list.get(i));
        }
        System.out.println("\n队列中元素的个数:" + queue.getSize());
        //出队操作
        while (!queue.isEmpty()) {
            T ele = queue.poll();
            System.out.print(ele + "--->");
        }

        //结束时间
        long endTime = System.nanoTime();
        System.out.println("总耗时:" + (endTime - startTime) / 1000000000.0 + "s");
    }

    public static void main(String[] args) {
        QueueTest<Integer> queueTest = new QueueTest<>();
        //Queue_I<Integer> queue = new LoopQueue<>();
        Queue_I<Integer> queue = new LinkedQueue<>();
        List<Integer> list = new ArrayList<>();
        Random random = new Random();
        for (int i = 0; i < 100; i++) {
            int val = random.nextInt(1000);
            System.out.print(val + "---->");
            list.add(val);
        }

        queueTest.test(queue, list);
    }
}

7、补充

使用Stream的方式遍历

1、将数组转换为stream,有两种方式:

Stream.of(arr),Arrays.stream(arr)

2、使用Arrays.stream()转换时,如果是包装类,转换后的类型为Stream,基础类型,转换后为IntStream

3、使用Stream.of()转换时,如果是包装类,转换后的类型为Stream,基础类型,转换后为

Stream<int[ ]>

三、单调栈

单调栈实际上还是栈,只是利用了一些巧妙的逻辑,使得每次新元素入栈后,栈内元素都保持单调。

相关推荐

  1. 数据结构---队列

    2024-03-14 19:42:06       40 阅读
  2. 数据结构:队列

    2024-03-14 19:42:06       38 阅读
  3. 数据结构队列

    2024-03-14 19:42:06       22 阅读
  4. 数据结构队列

    2024-03-14 19:42:06       23 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-03-14 19:42:06       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-03-14 19:42:06       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-03-14 19:42:06       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-03-14 19:42:06       20 阅读

热门阅读

  1. 探索信号处理:低通滤波器的原理与应用

    2024-03-14 19:42:06       17 阅读
  2. ts中高阶类型的理解

    2024-03-14 19:42:06       17 阅读
  3. 最少刷题数

    2024-03-14 19:42:06       16 阅读
  4. 工作随记:oracle重建一张1T数据量的大表

    2024-03-14 19:42:06       16 阅读
  5. c#计算闰年

    2024-03-14 19:42:06       20 阅读
  6. 基于ElasticSearch的海量AIS数据存储方法

    2024-03-14 19:42:06       23 阅读
  7. 【Python】-闲聊:如何系统的自学Ptyhon

    2024-03-14 19:42:06       23 阅读
  8. PHP序列化基础知识储备

    2024-03-14 19:42:06       19 阅读
  9. Oracle——用户、角色、权限的创建、删除、修改

    2024-03-14 19:42:06       20 阅读
  10. day2-C++

    day2-C++

    2024-03-14 19:42:06      16 阅读
  11. 当代计算机语言占比分析

    2024-03-14 19:42:06       23 阅读
  12. 文件系统事件监听

    2024-03-14 19:42:06       22 阅读
  13. 【OpenGL经验谈01】Vertex 规范最佳实践

    2024-03-14 19:42:06       22 阅读
  14. SpringCloud中Gateway提示OPTIONS请求跨域问题

    2024-03-14 19:42:06       18 阅读