数据结构.栈和队列

栈Stack

栈是一种线性数据结构
先进后出First Out Last In 即只能从栈顶添加元素或取出元素
在这里插入图片描述
基于数组实现栈:(详细注解)

package com.ffyc.datastructure;

import java.util.Random;

//基以数组作为栈的底层数组结构 用来存放栈中元素  实现栈接口  重写方法
public class ArrayStack<T>implements MyStack<T> {//注意实现的是MyStack<T>而不只是MyStack

    MyArray<T> data;//栈中的数组容器 也可以写成T
    int size;//实际存放元素的个数 也写可不写 因为data里面也可以拿到

    //构造函数初始化 new一个数组

    public ArrayStack() {
        this.data = new MyArray<T>();
        this.size = 0;
    }

    @Override
    public void push(T ele) {
this.data.addTail(ele);//尾部添加  size永远指向待插入元素的位置  时间复杂度O(1)
        this.size++;
    }

    @Override
    public T pop() {
        T result= this.data.removeTail();
        if (result!=null){
            this.size--;
        }
        return result;
    }

    @Override
    public T peek() {
        if (this.isEmpty()){
            return null;
        }
        return this.data.getEleByIndex(this.size-1);
    }

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

    @Override
    public boolean isEmpty() {
        return this.size==0;//等于0返回 true是空的  不等于0返回false 不是空的
    }

    public static void main(String[] args) {
        ArrayStack<Integer> arrayStack=new ArrayStack<>();
        int count=10;
        Random random=new Random();
        for (int i=0;i<count;i++){
           int num=random.nextInt(10) ;
            System.out.print(num+",");
           arrayStack.push(num);//入栈
        }
        System.out.println("\n-------------");
while (!arrayStack.isEmpty()){
    System.out.println(arrayStack.pop());//出栈
}
    }
}

测试结果:
在这里插入图片描述
时间复杂度分析:
入栈、出栈、查看栈顶元素、判空和获取栈中元素的个数 都是O(1)

队列Queue

队列也是一种线性数据结
先进先出,从队尾添加元素,从队首取出元素
在这里插入图片描述基于数组实现队列:

package com.ffyc.datastructure;

import java.util.Queue;
import java.util.Random;

//以数组为底层数据结构 来存储队列中存放的元素
public class ArrayQueue<T> implements MyQueue<T> {
     MyArray<T> data;
     int size;
    public ArrayQueue() {
        this.data=new MyArray<T>();
        this.size=0;

    }

    @Override
    public void enqueue(T ele) {
        this.data.addTail(ele);//队尾添加时间复杂度O(1)
        this.size++;
    }

    @Override
    public T dequeue() {
         T result=this.data.removeHead();
        if (result!=null){
            this.size--;
        }
        return result;
    }

    @Override
    public T getFront() {
        return this.data.getEleByIndex(0);
    }

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

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

    public static void main(String[] args) {
        ArrayQueue<Integer> arrayQueue=new ArrayQueue<>();
        int count=10;
        Random random=new Random();
        for (int i=0;i<count;i++){
            int num=random.nextInt(10) ;
            System.out.print(num+",");
            arrayQueue.enqueue(num);//入队
        }
        System.out.println("\n--------------");

        while (!arrayQueue.isEmpty()){//出队
            System.out.println(arrayQueue.dequeue()+",");
        }
        System.out.println("队列是否为空:"+arrayQueue.isEmpty());
    }
}

测试结果:
在这里插入图片描述

循环队列

普通队列出队操作数组后面的元素都要往前移,时间复杂度就是O(n),为了解决前移问题,就升级出来了循环队列,front记录队首位置,tail记录队尾位置 ,每次出队就front往后移,浪费一个空间换取时间,时间复杂度O(1)
条件有所变化:
1.队列为空
在这里插入图片描述
2.队列满
在这里插入图片描述
代码实现:

package com.ffyc.datastructure;

import java.util.Random;

//循环队列  增加队首队尾指针
public class CycleQueue<T> implements MyQueue<T> {
 T[] data;
 int size;

//两个索引   front=tail时队列为空
    int front;//头指针(索引)
    int tail;//尾指针(索引)
    int capacity;//保存容器  方便后面对队列取余

    public CycleQueue() {
        this(10);
    }
    public CycleQueue(int capacity) {//初始化
        this.capacity=capacity;
        data= (T[]) new Object[capacity+1];//创建数组是有意无意浪费一个空间 多创建一个空间
        this.size=0;
        this.front=0;
        this.tail=0;
    }

    @Override
    public void enqueue(T ele) {//入队
        if ((this.tail+1)%(this.capacity+1)==this.front){
            //如果队满  扩容
           resize(2*capacity);
        }
            this.size+=1;
            this.data[this.tail]=ele;   //插入
            this.tail=(this.tail+1)%(this.capacity+1);//tail往后移
    }

//改变容积的方法  扩容或缩容
    private void resize(int newCapacity) {
        int oldCapacity = this.capacity;
        this.capacity = newCapacity;
        T[] temp = (T[]) new Object[this.capacity + 1];
        for (int i = 0; i < this.size; i++) {
            temp[i] = this.data[(this.front + i) % (oldCapacity + 1)];
        }
        this.data = temp;
        this.front = 0;
        this.tail = this.size;
    }

    @Override
    public T dequeue() {//出队
        if (isEmpty()) {
            return null;//如果队列为空  就不能出队
        }
        //否则出队
        T result = this.data[this.front];//保存出队元素  以便最后返回
        this.front = (this.front + 1) % (this.capacity + 1);//front后移一位
        this.size--;
        //缩容
        if (this.size == this.capacity / 4 && this.capacity / 2 > 1) {
            resize(this.capacity / 2);
    }
            return result;
    }

    @Override
    public T getFront() {
        if (isEmpty()){
            return null;//如果队列为空  返回null
        }
        return this.data[this.front];
    }

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

    @Override
    public boolean isEmpty() {
        return this.front==this.tail;
    }

    public static void main(String[] args) {
        CycleQueue<Integer> cycleQueue=new CycleQueue<>(5);
        int count =10;
        Random random=new Random();
        for (int i=0;i<count;i++){
           int num=random.nextInt(10) ;
            System.out.print(num+",");
            cycleQueue.enqueue(num);//入队
        }
        System.out.println();
        System.out.println("队首元素:"+cycleQueue.getFront());
        while (!cycleQueue.isEmpty()) {
            System.out.println(cycleQueue.dequeue());
        }
    }
}


测试结果:
在这里插入图片描述!
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

团团kobebryant

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值