数据结构--------栈最详细讲解

  • 关于栈就是建立在数组或者链表的一种逻辑结构,在接下来的内容中,我将通过顺序存储结构来为大家讲解栈和队列.
  • 首先栈的特点是先进后出.它所包含的方法分别由入栈 push(),出栈 pop(),查找栈中最后的一个元素 peek()与判断栈是否为空栈 isEmpty().首先我们需要创建一个栈,为了与编译器中自带的栈区分开,我选择为自己的栈重新定义一个接口为Stack_I,然后在这个接口中定义栈的方法,之后再创建一个类来实现这个接口,由此来获得我们自己的栈.
  • 创建栈的第一步就是在类中定义一个储存数据的容器,和容器中有多少个元素.而关于储存数据的容器类型我已经为大家定义好了一个完整的,如果大家有其他的需要可以去修改这个类
  • public class MyArray<T> {
        private T[] data;//保存数据
    
        int size;//数组中实际存放元素的个数
    
        int capacity;//容积
    
        public MyArray(int capacity){
            if(capacity<=0){
                this.capacity=10;
            }else {
                this.capacity = capacity;
            }
            this.size=0;
            this.data=(T[])(new Object[this.capacity]);
        }
    
        //获取数组中实际存放元素的个数
        public int getSize(){
            return this.size;
        }
    
        //获取数组的容积
        public int getCapacity(){
            return this.capacity;
        }
    
        //判断数组是否为空
        public boolean isEmpty(){
            return this.size==0;
        }
    
        // 向数组中添加元素
        public void add(T item){
            //this.size 指向的是待插入元素的位置
            addIndex(this.size,item);
        }
    
        // 向数组中指定位置添加元素
        public void addIndex(int index,T val){
            if(index<0||index>this.size){
                throw new IllegalArgumentException("index is invaild!");
            }
    
            if(this.capacity==this.size){
                resize(capacity*2);
            }
            //从index位置开始元素需要向后移动
            for (int i = this.size-1; i >=index ; i--) {
                this.data[i+1]=this.data[i];
            }
            this.data[index]=val;
            this.size++;
        }
    
    
        private void resize(int newCapacity){
            T[] newData=(T[])new Object[newCapacity];
            for (int i = 0; i < this.size; i++) {
                newData[i]=data[i];
            }
            this.data=newData;
            this.capacity=newCapacity;
        }
    
        // 向数组头部添加元素
        public void addHead(T val){
            addIndex(0,val);
        }
    
    
        //修改指向位置的值
        public void modifyValueByIndex(int index,T item){
            //入参一定判断
            if (index <0||index>=this.capacity) {
                throw new IllegalArgumentException("index is invaild!");
            }
            this.data[index]=item;
        }
    
        //获取指定索引位置的值
        public T getValueByIndex(int index){
            if (index <0||index>=this.capacity) {
                throw new IllegalArgumentException("index is invaild!");
            }
            return this.data[index];
        }
    
        //获取数组中最后一个位置的元素的值
        public T getValueFromLast(){
            return getValueByIndex(this.size-1);
        }
    
        //查找指定的值在数组中是否存在,存在获取索引,不存在返回-1
        public int containValue(T val){
            for (int i = 0; i < this.size; i++) {
                if(val.equals(this.data[i])){
                    return i;
                }
            }
            return -1;
        }
    
        //根据索引在数组中删除元素
        public T removeByIndex(int index){
            if (index <0||index>=this.capacity) {
                throw new IllegalArgumentException("index is invaild!");
            }
            //删除元素的核心
            T delValue = this.data[index];
            for (int i = index+1; i <this.size ; i++) {
                this.data[i-1]=this.data[i];
            }
            this.size--;
            if(this.size<=this.capacity/4&&this.capacity/2>0){
                resize(this.capacity/2);
            }
            return delValue;
        }
    
        //删除数组尾部的元素
        public T removeFromLast(){
            return removeByIndex(this.size-1);
        }
    
    
        @Override
        public String toString() {
            StringBuilder sb=new StringBuilder("{");
            for (int i = 0; i < this.size; i++) {
                sb.append(this.data[i]);
                if(i!=this.size-1){
                    sb.append(",");
                }
            }
            sb.append("}");
            return sb.toString();
        }

    将这个容器类型定义好之后,我们继续构造我们的栈

  • public class ArrStack<T> implements Stack_I<T> {
    
        private MyArray<T> data; //栈的容器
    
        int size;
    
        public ArrStack(){
            this.data=new MyArray<>(100);
            this.size=0;
        }
    }

    由于我们不确定容器内元素是什么数据类型的,所以用泛型来代替.之后我们来分别实现该类接口中的方法

  • 首先是入栈的方法
     public void push(T ele) {
            this.data.add(ele);
            this.size++;
        }

    接着是出栈的方法

  • public T pop() {
            if(isEmpty()){
                return null;
            }
            return this.data.removeFromLast();
        }

    再然后就是查找栈中最后一个元素的方法

  • public T peek() {
            if(isEmpty()){
                return null;
            }
            return this.data.getValueFromLast();
        }

    最后是判断栈是否为空的方法

  • public boolean isEmpty() {
            return this.data.getSize()==0;
        }
    

    最后我们将其卸载一个类中,就构建出了一个属于我们自己的最基本的栈(后面附有该栈接口类)

  • public class ArrStack<T> implements Stack_I<T> {
    
        private MyArray<T> data; //栈的容器
    
        int size;
    
        public ArrStack(){
            this.data=new MyArray<>(100);
            this.size=0;
        }
    
        @Override
        public void push(T ele) {
            this.data.add(ele);
            this.size++;
        }
    
        @Override
        public T pop() {
            if(isEmpty()){
                return null;
            }
            return this.data.removeFromLast();
        }
    
        @Override
        public T peek() {
            if(isEmpty()){
                return null;
            }
            return this.data.getValueFromLast();
        }
    
        @Override
        public boolean isEmpty() {
            return this.data.getSize()==0;
        }
    }

public interface Stack_I<T> {
    //入栈
    void push(T ele);

    //出栈
    T pop();

    //查栈
    T peek();

    //判断栈是否为空
    boolean isEmpty();
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值