数据结构与算法(三)——栈的顺序存储结构

线性表List的延伸——栈(Stack)

栈的定义:

栈是限定在仅在表尾进行插入和删除操作的线性表。
我们把允许插入和删除的那一端称为栈顶(top),另一端称为栈底(boottom)。
不含有任何元素的栈称为空栈。
栈是后进先出的线性表,简称KIFO(后进先出)表。
栈就是一个特殊的线性表,其数据元素具有线性关系。
栈是在线性表表尾进行插入和删除操作,这里的表尾是指栈顶,不是栈底。
栈的插入:进栈,也称压栈、入栈。
栈的删除:出栈,也称弹栈。
!]()
在如下图所示,当你的邮件在桌上放成一叠时,使用的就是栈的方法。当有新邮件来时,你会将它们放在最上面,当你有空时你会一封一封地从上到下阅读它们。用栈的方式存放电子邮件——在收信时将邮件压入( push)最顶端,在取信时从最顶端将它们弹出( pop),且第一封一定是最新的邮件(后进, 先出)。这种方法的好处是我们能够及时看到最新的邮件,坏处是如果你不把栈清空,某些较早的邮件可能永远也不会被阅读。再比如你打开网页中的链接是,该页面会变成一个新的页面,但是当你点击“回退”的按钮时,他会返回都到刚刚的页面。栈的后进先出策略正好能够提供你所需要的行为。当使用foreach语句迭代遍历栈中的元素时,元素的处理顺序和它们被压人入的顺序正好相反。

]()

栈的接口Stack的定义:

+int getSize() 获取栈中元素的个数
+boolean isEmpty() 判断栈是否为空
+void push(E e) 将元素e压入栈顶
+E pop() 弹栈一个元素并返回,从栈顶删除元素
+E peek() 查看当前栈顶元素
+void clear() 清空栈

代码如下:
package DS01.动态数组;
/*
线性表的一种特殊情况 栈
ArrayStack extends ArrayList,实现子类
ArrayList当做是ArraySatck的一个成员变量,我们使用的是这种
*/
public interface Stack<E> extends Iterable<E>{		//可以被迭代,继承自Iterable
    //获取栈中元素的个数
    int getSize();
    //判断栈是否为空
    boolean isEmpty();
    //将元素e压入栈顶
    void push(E e);
    //弹栈一个元素并返回,从栈顶删除元素
    E pop();
    //查看当前栈顶元素
    E peek();
    //清空栈
    void clear();
}

栈的顺序结构ArrayStack的定义

在这里插入图片描述

代码如下:
package DS01.动态数组;

import java.util.Iterator;

public class ArrayStack<E> implements Stack<E> {
    private ArrayList<E> list;
    //
    public ArrayStack() {//默认无参构造函数,创建一个默认大小的栈
        list = new ArrayList<>();
    }
    //
    public ArrayStack(int capacity) {//传一个参的构造函数,创建一个容量由用户指定的顺序栈
        list = new ArrayList<>(capacity);
    }
    @Override
    public int getSize() {//存储栈的长度,栈顶位置Top必须小于该长度。
    //直接调用顺序表中的方法
        return list.getSize();
    }
	
    @Override
    public boolean isEmpty() {//判空
        return list.isEmpty();
    }

    @Override
    public void push(E e) {//进栈从表尾进,调用addLast
        list.addLast(e);
    }

    @Override
    public E pop() {//出栈元素从表尾出,调用removeLast
        return list.removeLast();
    }

    @Override
    public E peek() {//查看当前栈顶,相当于查看表尾元素
        return list.getLast();
    }

    @Override
    public void clear() { //清空栈和清空顺序表一样,直接调用
        list.clear();
    }

    @Override
    public Iterator<E> iterator() {//迭代器也是直接调用
        return list.iterator();
    }
//使用toString进行打印
    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append(String.format("ArrayStack: %d/%d\n",getSize(),list.getCapacity()));
        //用数组的形式输出
        sb.append('[');
        if(isEmpty()) {
            sb.append(']');
        }else{
            for (int i = 0; i < getSize(); i++) {
                sb.append(list.get(i));
                if(i==getSize()-1){
                    sb.append(']');//遍历到最后一个元素打印']'
                }else{
                    sb.append(','); //不然在每个元素中间打','
                }
            }
        }
          //调用对象的tostring方法返回对象
        return sb.toString();
    }
}

对ArrayStack类进行测试的代码:

package DS01.动态数组;

import java.util.Iterator;

public class TestArrayStack {
    public static void main(String[] args) {
        ArrayStack<Integer>stack = new ArrayStack<>();
        System.out.println(stack);
        for (int i = 1; i <=15 ; i++) {
            stack.push(i);
        }
        System.out.println(stack);
        for (int i = 1; i <=10; i++) {
            stack.pop();
        }
        System.out.println(stack);
        for(Integer i:stack) {
            System.out.print(i+" ");
        }
        Iterator<Integer> it = stack.iterator();
        while(it.hasNext()) {
            System.out.print(it.next()+" ");
        }
    }
}

发布了48 篇原创文章 · 获赞 47 · 访问量 5247

猜你喜欢

转载自blog.csdn.net/weixin_45160969/article/details/103569593
今日推荐