关于栈和队列

1.栈

1.1 什么是栈

:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。

压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶

出栈:栈的删除操作叫做出栈。出数据在栈顶

压栈(push):

出栈(pop):

栈的常用方法:

public static void main(String[] args) {
Stack<Integer> s = new Stack();
s.push(1);
s.push(2);
s.push(3);
s.push(4);
System.out.println(s.size()); // 获取栈中有效元素个数---> 4
System.out.println(s.peek()); // 获取栈顶元素---> 4
s.pop(); // 4出栈,栈中剩余1 2 3,栈顶元素为3
System.out.println(s.pop()); // 3出栈,栈中剩余1 2 栈顶元素为3
if(s.empty()){
System.out.println("栈空");
}else{
System.out.println(s.size());
}
}

1.2 如何自己实现栈

从上图中可以看到,Stack继承了Vector,Vector和ArrayList类似,都是动态的顺序表,不同的是Vector是线程安全的。

关于自己实现栈的代码:

public class MyStack {
int[] array;
int size;
public MyStack(){
array = new int[3];
}
public int push(int e){
ensureCapacity();
array[size++] = e;
return e;
}
public int pop(){
int e = peek();
size--;
return e;
}
public int peek(){
if(empty()){
throw new RuntimeException("栈为空,无法获取栈顶元素");
}
return array[size-1];
}
public int size(){
return size;
}
public boolean empty(){
return 0 == size;
}
private void ensureCapacity(){
if(size == array.length){
array = Arrays.copyOf(array, size*2);
}
}
}

1.3 栈的练习

栈的压入、弹出序列

public class Solution {
    public boolean IsPopOrder(int [] pushA,int [] popA) {
        Stack<Integer> stack = new Stack<>();
        int j = 0;
        for (int i = 0; i < pushA.length; i++){
            stack.push(pushA[i]);
            while (j < popA.length && !stack.empty() && stack.peek().equals(popA[j])){
                stack.pop();
                j++;
            }
        }
        return stack.empty();
    }
}

2. 队列

2.1 什么是队列

队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(FirstIn First Out) 入队列:进行插入操作的一端称为队尾(Tail/Rear) 出队列:进行删除操作的一端称为队头(Head/Front)。

2.2 队列的方法

Queue是个接口,底层是通过链表实现的。

public static void main(String[] args) {
Queue<Integer> q = new LinkedList<>();
q.offer(1);
q.offer(2);
q.offer(3);
q.offer(4);
q.offer(5); // 从队尾入队列
System.out.println(q.size());
System.out.println(q.peek()); // 获取队头元素
q.poll();
System.out.println(q.poll()); // 从队头出队列,并将删除的元素返回
if(q.isEmpty()){
System.out.println("队列空");
}else{
System.out.println(q.size());
}
}

2.3 如何自己实现一个队列



//由单链表创造队列
public class MyQueue {
    static class Node{
        public int val;
        public Node next;

        public Node(int val){
            this.val = val;
        }
    }
    public Node head;
    public Node last;
    public int  usedSize;

//    入队
    public void offer(int val){
        Node node = new Node(val);
        if (head == null){
            head = node;
            last = node;
        }else {
            last.next = node;
            last = node;
        }
        usedSize++;
    }

//    出队
    public int poll(){
        if (empty()){
            throw new EmptyException("队列为空!");
        }
        int ret = head.val;
        head = head.next;
        usedSize--;
        return ret;
    }

    public boolean empty(){
        return usedSize == 0;
    }

    public int peek(){
        if (empty()){
            throw new EmptyException("队列为空!");
        }
        return head.val;
    }

    public int getUsedSize(){
        return usedSize;
    }
}

3 栈和队列的应用

3.1 用栈实现队列

import java.util.Stack;
//用栈实现队列
public class MyQueue1 {
    private Stack<Integer> stack1;
    private Stack<Integer> stack2;

    public MyQueue1(){
        stack1 = new Stack<>();
        stack2 = new Stack<>();
    }

    public void push(int x){
        stack1.push(x);
    }

    public int pop(){
        if (empty()){
            return -1;
        }
        if (stack2.empty()){
            while (!stack1.empty()){
                stack2.push(stack1.pop());
            }
        }
        return stack2.pop();
    }

    public int peek(){
        if (empty()){
            return -1;
        }
        if (stack2.empty()){
            while (!stack1.empty()){
                stack2.push(stack1.pop());
            }
        }
        return stack2.peek();
    }

    public boolean empty(){
        return stack1.empty() && stack2.empty();
    }
}

3.2 用队列实现栈

import java.util.LinkedList;
import java.util.Queue;

//用队列实现栈
public class MyStack {
    private Queue<Integer> qu1;
    private Queue<Integer> qu2;

    public MyStack(){
        qu1 = new LinkedList<>();
        qu2 = new LinkedList<>();
    }

    public void push(int x){
        if (!qu1.isEmpty()){
            qu1.offer(x);
        }else if (!qu2.isEmpty()){
            qu2.offer(x);
        }else {
            qu1.offer(x);
        }
    }

    public int pop(){
        if (empty()){
            return -1;
        }
        if (!qu1.isEmpty()){
            int size = qu1.size();
            for (int i = 0; i < size-1; i++) {
                int val = qu1.poll();
                qu2.offer(val);
            }
            return qu1.poll();
        }else {
            int size = qu2.size();
            for (int i = 0; i < size-1; i++) {
                int val = qu2.poll();
                qu1.offer(val);
            }
            return qu2.poll();
        }
    }

    public int top(){
        if (empty()){
            return -1;
        }
        if (!qu1.isEmpty()){
            int size = qu1.size();
            int val = -1;
            for (int i = 0; i < size; i++) {
                val = qu1.poll();
                qu2.offer(val);
            }
            return val;
        }else {
            int size = qu2.size();
            int val = -1;
            for (int i = 0; i < size; i++) {
                val = qu2.poll();
                qu1.offer(val);
            }
            return val;
        }
    }

    public boolean empty(){
        return qu1.isEmpty() && qu2.isEmpty();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值