您的位置 首页 java

算法入门之栈

算法入门之栈

前言

了解完算法的基本数据结构 链表 和数组后,我们就可以开始了解基于这些基本数据衍生出来的其它数据结构,如堆、栈、队列等,今天详细聊聊栈,其它文章参考

数组简介

链表简介

什么是栈

栈是一种线性结构,最常见的生活中的例子就是羽毛球筒

羽毛球筒只开放一端入口,那么先放入的球一定是在底部,最后放入的球在最顶部,拿球时先获取的就是靠近顶部的球,只有不停的获取才能将底部的球拿到。

栈也就是这样,只能从一端入栈和出栈,这种顺序我们称为FILO(First In Last Out)先进后出,最早进入的元素称为栈底,最后进入的元素我们称为栈顶,如下

栈是链表和数组的基本数据的衍生结构,所以可以采用链表或者数据实现,具体思路如下

数组实现栈

用数组来实现栈太简单,我们可以参考之前数组的相关文章

数组简介

入栈就是在数组的尾部插入元素不涉及到数组元素移动,出栈就是将数组尾部的元素清除,示意图如下

入栈

出栈

实现代码

 /**
 * 用数组实现栈
 */class MyStack1 {
    // 数组的实际大小
     private  int size;
    private Object[] arr;
    public MyStack1(int capacity){
        arr = new Object[capacity];
        size = 0;
    }
    // 入栈
    public  void  push(Object data){
        if (size == arr.length){
            throw new Runtime Exception ("超过栈的最大容量");
        }
        arr[size] = data;
        size++;
    }
    // 出栈
    public Object pull(){
        if (size == 0){
            throw new RuntimeException("栈为空!");
        }
        Object data = arr[size-1];
        // 恢复数组指定位置默认值
        arr[size-1] = null;
        size--;
        return data;
    }
    public void show(){
        System.out.println("打印栈存放数据:"+ Arrays.toString(arr));
    }
}
  

链表实现栈

链表实现栈同样是尾部指针的移动,如下是链表实现的示意图

入栈就是将原队尾的next指针指向新节点即可,而出栈就是将原队尾节点的上一个节点的next指针指向null。

入栈

出栈

实现代码如下

 /**
 * 用链表实现栈
 */class MyStack2 {
    // 链表元素个数
    private int size;
    // 头节点
    private Node head;
    // 尾节点
    private Node last;
    // 入栈
    public void push(Object data){
        Node node = new Node(data);
        if (size == 0){
            head = node;
            last = node;
        }else {
            last.next = node;
            last = node;
        }
        size++;
    }
    // 出栈
    public Object pull(){
        if (size == 0){
            throw new RuntimeException("栈数据为空");
        }
        Object data = last.data;
        if (size == 1){
            head = null;
            last = null;
        }else {
            // 获取倒数第二个节点
            Node index = getIndex(size - 2);
            index.next = null;
            last = index;
        }
        size--;
        return data;
    }
    // 获取指定下标的元素从0开始
    public Node getIndex(int index){
        if (index <0 || index>=size){
            throw  new RuntimeException("数组下标异常");
        }
        Node temp = head;
        for (int i = 0; i <index; i++) {
            temp = temp.next;
        }
        return temp;
    }
    public void show(){
        Node temp = head;
        while (temp!=null){
            System.out.println(temp);
            temp = temp.next;
        }
    }
}
class Node{
    // 数据
    Object data;
    // 下一个节点指针
    Node next;
    public Node(Object data){
        this.data = data;
        next = null;
    }
    @Override
    public String toString() {
        return "Node{" +
                "data=" + data +
                ", next=" + next +
                '}';
    }
}
  

总结

从操作代码可以看出,无论栈的实现方式是采用数组还是链表,入栈出栈都非常简单仅仅是一个元素的移动,所以入栈和出栈操作时间复杂度都为O(1)。

文章来源:智云一二三科技

文章标题:算法入门之栈

文章地址:https://www.zhihuclub.com/188972.shtml

关于作者: 智云科技

热门文章

网站地图