【数据结构】用java实现栈

栈(Stack)是一种基本的数据结构,它遵循“后进先出”(Last In First Out,LIFO)的原则。在栈中,最后插入的元素首先被弹出。

在这里插入图片描述

栈的常见操作

  1. 压栈(Push):将一个元素添加到栈的顶部。
  2. 出栈(Pop):从栈的顶部移除一个元素,并返回该元素。
  3. 获取栈顶元素(Peek):返回栈顶部的元素,但不对栈进行修改。
  4. 判断栈是否为空(isEmpty):检查栈是否为空,若为空则返回 true,否则返回 false。

栈可以使用数组或链表来实现,也可以使用其他数据结构。不同的实现方式会导致不同的性能特征,如时间复杂度和空间复杂度。。在底层,栈通过数组或链表来存储元素。每当进行压栈操作时,元素被添加到数组或链表的顶部。而出栈操作则是从顶部移除元素。

使用数组模拟栈

使用数组实现栈时,可以使用一个指针(通常称为 top)指向栈顶。需要注意的是,数组的大小需要提前确定。

  • 压栈操作:将元素添加到 top + 1 的位置,并将 top 增加 1。
  • 出栈操作:返回 top 位置的元素,并将 top 减少 1。
  • 获取栈顶元素:返回 top 位置的元素。
  • 判断栈是否为空:如果 top 等于 -1,则栈为空。
public class SqStack<E> {
    //默认的初始化数组大小 为10
    private static final int DEFAULT_CAPACITY = 10;
    private E[] stack;
    private int size;

    public SqStack() {
        this.stack = (E[]) new Object[DEFAULT_CAPACITY];
        this.size = 0;
    }
    public SqStack(int length) {
        this.stack = (E[]) new Object[length];
        this.size = 0;
    }
    
    public void display(){
        if(isEmpty()){
            System.out.println("栈空");
            return;
        }
        for (E e : stack) {
            System.out.println(e+" ");
        }
        System.out.println();
    }
    
    public boolean isEmpty() {
        return size==0;
    }
    public boolean isFull(){
        return size==stack.length;
    }
    
    public int getSize() {
        return size;
    }
    public void reSize(){
        E[] newArrSqList = (E[]) new Object[stack.length+(stack.length)>>1];
        System.arraycopy(stack,0,newArrSqList,0,size);
        stack = newArrSqList;
    }
    
    public void push(E e) {
        if(this.isFull()){
            this.reSize();
        }
        size++;
        stack[size-1] = e;
    }
    public E pop() {
        E popElement = stack[size-1];
        stack[size-1] = null;
        size--;
        return popElement;
    }
    public E peek() {
        E peekElement = stack[size-1];
        return peekElement;
    }
}

使用链表模拟栈

使用链表实现栈时,可以将链表的头部作为栈顶。链表节点除了包含存储元素的值,还需要包含指向下一个节点的指针。

  • 压栈操作:将元素添加到链表的头部,更新栈顶指针。
  • 出栈操作:删除链表的头部节点,并返回其值,更新栈顶指针。
  • 获取栈顶元素:返回链表的头部节点的值。
  • 判断栈是否为空:如果栈顶指针为空,则栈为空。
// 单链表节点类
public class Node<E> {
    public E data;
    public Node next;
    public Node(E data) {
        this.data = data;
        this.next = null;
    }
    public Node() {
        this.data = null;
        this.next = null;
    }
}
public class LinkListStack<E> implements Stack<E> {
    public Node head;
    private int size;

    public LinkListStack() {
        this.head = new Node<E>();
        this.size = 0;
    }

    public LinkListStack(Node head) {
        this.head = head;
        this.size = 0;
    }

    public void push(E e) {
        Node temp = head;
        Node p = new Node(e);
        if(isEmpty()){
            head.next = p;
            size++;
            return;
        }
        while (temp.next!=null){
            temp = temp.next;
        }
        temp.next = p;
        size++;
    }
    
    public E pop() {
        if(isEmpty()){
            System.out.println("空栈");
            return null;
        }
        Node temp = head;
        while (temp.next.next!=null){
            temp = temp.next;
        }
        Node p = temp.next;
        temp.next = null;
        size--;
        return (E) p.data;
    }

    public E peek() {
        if(isEmpty()){
            System.out.println("空栈");
            return null;
        }
        Node temp = head;
        while (temp.next!=null){
            temp = temp.next;
        }
        return (E)temp.data;
    }

    public int getSize() {
        return size;
    }

    public boolean isEmpty() {
        return size==0;
    }

    public void display(){
        if(isEmpty()){
            System.out.println("空栈");
            return;
        }
        Node temp = head.next;
        System.out.print("{");
        while (temp.next!=null){
            System.out.print(temp.data+" ");
            temp = temp.next;
        }
        System.out.println(temp.data+"}");
    }
}

栈的测试代码

public class test {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
//        SqStack<String> stack = new SqStack<String>(10);
        LinkListStack<String> stack = new LinkListStack<String>();
        boolean flag = true;
        String c = null;
        String e = null;
        while (flag){
            System.out.print("请输入要进行的操作:");
            c = sc.next();
            switch (c){
                case "push":
                    System.out.println("请输入要插入的元素");
                    e = sc.next();
                    stack.push(e);
                    break;
                case "pop":
                    e = stack.pop();
                    if(e!=null){
                        System.out.println("出栈元素为:"+e);
                    }
                    break;
                case "peek":
                    e = stack.peek();
                    if(e!=null){
                        System.out.println("栈顶元素为:"+e);
                    }
                    break;
                case "display":
                    stack.display();
                    break;
                default:
                    flag = false;
                    break;
            }
        }
    }
}

Java封装好的栈

Java中提供了一个封装好的栈类,即 java.util.Stack 类。使用这个类,可以更方便地实现栈的操作。

以下是 java.util.Stack 类中一些常用的方法:

  • push(E item):将元素压入栈顶。
  • pop():移除并返回栈顶元素。
  • peek():返回栈顶元素,但不对栈进行修改。
  • empty():判断栈是否为空,为空返回 true,否则返回 false。
  • search(Object o):查找元素在栈中的位置,如果存在则返回相对于栈顶的位置(最顶部元素为 1),如果不存在则返回 -1。
```java
import java.util.Stack;

public class StackExample {
    public static void main(String[] args) {
        Stack<Integer> stack = new Stack<>();
        
        // 压栈
        stack.push(1);
        stack.push(2);
        stack.push(3);
        
        // 出栈
        int top = stack.pop();
        System.out.println("出栈元素:" + top);
        
        // 获取栈顶元素
        int peek = stack.peek();
        System.out.println("栈顶元素:" + peek);
        
        // 判断栈是否为空
        boolean empty = stack.empty();
        System.out.println("栈是否为空:" + empty);
        
        // 查找元素位置
        int position = stack.search(2);
        System.out.println("元素 2 在栈中的位置:" + position);
    }
}

## 栈的实际应用

1. **函数调用栈**:在计算机的程序执行过程中,函数调用会形成一个由栈组成的调用栈。
2. **递归算法**:递归算法使用栈来保存每个递归步骤的状态。
3. **表达式求值**:在编译器中,栈可以用于解析和计算表达式(后缀表达式)。
4. **撤销操作**:在文本编辑器或图形编辑器中,栈可以用于实现撤销操作。
5. **浏览器历史记录**:浏览器使用栈来记录用户浏览网页的历史记录。

通过栈的特性和常见操作,我们可以在不同的领域中应用栈来解决问题,并提高程序的效率和性能。
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值