数据结构-栈和队列

学习目标:

掌握数据结构栈和队列

学习内容:

1、 栈 2、 队列 3、循环队列

学习时间:

2021年7月4日

学习产出:

1、 技术笔记 1 遍 2、CSDN 技术博客 1 篇

栈Stack

栈也是一种线性数据结构规定只能从栈顶添加元素,也只能从栈顶取出元素

栈

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

Last In First Out(LIFO)

栈的具体实现

Stack

	void push(T ele) //入栈
	T pop() //出栈并返回元素
	T peek() //返回栈顶元素但不删除
	boolean isEmpty() //判断是否为空
	int getSize() //获取栈内元素个数
public class MyStack<T> implements Stack<T> {
    //栈数据容器
    MySelfArray<T> myArray;

    public MyStack() {
        this(10);
    }

    public MyStack(int capacity) {
        myArray = new MySelfArray<>(capacity);
    }

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

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

    @Override
    public void push(T ele) {
        myArray.addTail(ele);
    }

    @Override
    public T pop() {
        return myArray.removeTail();
    }

    @Override
    public T peek() {
        return myArray.getlastElement();
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        if (this.isEmpty()){
            return null;
        }
        sb.append("初始容积是:" + myArray.getCapacity() + ",实际存放元素个数是:" + this.getSize() + ",内容如下");
        while (!this.isEmpty()) {
            sb.append(this.pop() + "<<<");
        }
        return sb.substring(0, sb.lastIndexOf("<") - 2);
    }
    
    public static void main(String[] args) {
        MyStack<Integer> myStack = new MyStack<>(20);
        for (int i = 0; i < 10; i++) {
            myStack.push(i + 10);
        }

        System.out.println("栈顶元素为" + myStack.peek());
        System.out.println(myStack);
    }
}

时间复杂度分析

	void push(T ele) //O(1)
	T pop() //O(1)
	T peek() //O(1)
	boolean isEmpty() //O(1)
	int getSize() //O(1)

队列Queue

队列也是一种线性数据结构 只能从一端(队尾)添加元素,从另一端(队首)取出元素。

队列

队列的实现

    Queue<E>
	void enqueue(T ele);//入队操作	O(1)
    T dequeue();//出队操作	O(n)原因时在出队时,数组后面的元素都要进行前移。
    T getFront();//获取队首元素	O(1)
    int getSize();//获取队列中元素个数	O(1)
    boolean isEmpty();//判断队列是否为空	O(1)
public class MyQueue<T> implements Queue<T> {
    private  MySelfArray<T> myArray;

    public MyQueue() {
        this(10);
    }
    public MyQueue(int capacity) {
        myArray = new MySelfArray<>(capacity);
    }

    @Override
    public void enqueue(T ele) {
        myArray.addTail(ele);
    }

    @Override
    public T dequeue() {
        return myArray.removeHead();
    }

    @Override
    public T getFront() {
        return myArray.getfirstElement();
    }

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

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

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("[队首");
        if (this.isEmpty()){
            return null;
        }
        while (!this.isEmpty()){
            sb.append(this.dequeue()+",");
        }
        //                切割    从0开始 到最后一个","(不包括)
        String res = sb.substring(0, sb.lastIndexOf(","));
        return res+"队尾]";
    }

    public static void main(String[] args) {
        Queue<Integer> queue = new MyQueue<>();
        for (int i = 0; i < 100; i++) {
            queue.enqueue(i + 10);
        }

        if (queue.isEmpty()) {
            return;
        } else {
            System.out.println("队首元素是:" + queue.getFront());
            System.out.println(queue);
        }
    }
}

循环队列

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

循环队列

循环队列的实现

    LoopQueue<E>
	void enqueue(T ele);//入队操作	O(1)
    T dequeue();//出队操作	O(1)
    T getFront();//获取队首元素	O(1)
    int getSize();//获取队列中元素个数	O(1)
    boolean isEmpty();//判断队列是否为空	O(1)
public class LoopQueue<T> {
    private T[] data; // 数据容器
    private int size; // 队列中元素个数
    private int front; // 队首指针
    private int tail; // 队尾指针

    public LoopQueue() {
        this(10);
    }

    public LoopQueue(int capacity) {
        this.data = (T[]) new Object[capacity + 1];
        this.size = 0;
        this.front = 0;
        this.tail = 0;
    }

    //容器容积
    public int getCapacity() {
        return data.length;
    }

    //实际存放元素个数
    public int getSize() {
        return this.size;
    }

    //判断队列是否为空
    public boolean isEmpty() {
        return this.size == 0;
        //return this.front == this.tail;
    }

    //更改容积
    public void resize(int newcapacity) {
        T[] newData = (T[]) new Object[newcapacity];
        for (int i = 0; i < this.size; i++) {
            newData[i] = this.data[(this.front + i) % this.getCapacity()];
        }
        this.data = newData;
        this.front = 0;
        this.tail = this.size;
    }

    //入队操作
    public void enqueue(T ele) {
        //判断队列是否已满
        if ((this.tail + 1) % this.getCapacity() == this.front) {
            //扩容操作
            resize(this.getCapacity() * 2 - 1);
        }

        this.data[this.tail] = ele;
        this.size++;
        this.tail = (this.tail + 1) % this.getCapacity();
    }

    //出队操作
    public T dequeue() {
        if (this.isEmpty()) {
            throw new IllegalArgumentException("this equeue is empty!");
        }
        T result = this.data[this.front];
        this.size--;
        this.front = (this.front + 1) % this.getCapacity();

        //缩容操作
        if (this.getSize() == this.getCapacity() / 4 && this.getCapacity() / 2 > 1) {
            resize((this.getCapacity() + 1) / 2);
        }
        return result;
    }

    //获取队首元素
    public T getFront() {
        if (this.isEmpty()) {
            throw new IllegalArgumentException("this equeue is empty!");
        }
        return this.data[this.front];
    }

    public static void main(String[] args) {
        LoopQueue<Integer> loopQueue = new LoopQueue<>(1000);
        for (int i = 0; i < 10000; i++) {
            loopQueue.enqueue(i);
            if (i % 3000 == 0) {

                while (!loopQueue.isEmpty()) {
                    System.out.println(loopQueue.dequeue());
                }
            }
        }
        while (!loopQueue.isEmpty()) {
            System.out.println(loopQueue.dequeue());
        }

    }

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值