栈实现(通过数组和链表)

栈是一种只允许在一端进行插入或删除的线性表。
1、栈的操作端通常被称为栈顶,另一端被称为栈底。
2、栈的插入操作称为进栈(压栈|push);栈删除操作称为出栈(弹栈|pop)。

  • 定义一个栈接口:
/*
* 线性表的一种特殊情况
* */
public interface Stack<E> extends Iterable<E>{
    int getSize();
    boolean isEmpty();
    void push(E e);
    E pop();
    E peek();
    void clear();
}

  • 通过顺序表实现栈(顺序栈):
    private static int DEFAULT_SiZE=10;//默认容量
    private int top;//栈顶指针
    private int[] data;
    //创建一个栈使用默认容量
    public ArrayStack(){
        this(DEFAULT_SiZE);
    }
    //创建一个栈使用用户指定容量capacity
    public ArrayStack(int capacity){
        super();
        this.top=-1;
        this.data=new int[capacity];
    }
    //入栈一个元素
    public void push(int e){
        if(top==data.length-1){
            System.out.println("栈已满!无法入栈元素");
        }
        data[++top]=e;
    }
    //出栈一个元素
    public int pop(){
        if(isEmpty()){
            System.out.println("栈已空!无法出栈元素");
        }
        return data[top--];
    }
    //判断栈是否为空
    public boolean isEmpty(){
        return this.top==-1;
    }
    //获取有效元素的个数
    public int length(){
        return this.top+1;
    }
    public String toString(){
        StringBuilder sb=new StringBuilder();
        sb.append('[');
        for(int i=0;i<=top;i++){
            sb.append(data[i]);
            if(i==top)
                return sb.append(']').toString();
                sb.append(',');
                sb.append(' ');
        }
        return "[]";
    }
}
  • 双端顺序栈:
package DS01.动态数组;


import java.util.Iterator;
/*
* 双端栈*/
public class ArrayStackDoubleEnd<E> implements Stack<E> {
    private static final int DEFAULT_SIZE=10;
    private E[] data;
    private int leftTop;
    private int rightTop;
    public ArrayStackDoubleEnd(){
        this(DEFAULT_SIZE);
    }
    public ArrayStackDoubleEnd(int capacity){
        data=(E[])(new Object[capacity]);
        leftTop=-1;
        rightTop=data.length;
    }
    public int getLeftSize(){
        return leftTop+1;
    }
    public int getRightSize(){
        return data.length-rightTop;
    }
    @Override
    public int getSize() {
        return getLeftSize()+getRightSize();
    }
    public boolean isLeftEmpty(){
        return leftTop==-1;
    }
    public boolean isRightEmpty(){
        return rightTop==data.length;
    }
    @Override
    public boolean isEmpty() {
        return isLeftEmpty()&&isRightEmpty();
    }
    public void pushLeft(E e){
        if(leftTop+1==rightTop){
            resize(2*data.length);//扩容
        }
        leftTop++;
        data[leftTop]=e;
    }

    private void resize(int newLen) {
        E[] newData=(E[])(new Object[newLen]);
        for (int i = 0; i < leftTop; i++) {
            newData[i]=data[i];
        }
        //扩容时右边的复制
        if(newData.length>data.length){
            for (int i = rightTop; i < data.length; i++) {
                newData[i+data.length]=data[i];
            }
            rightTop=rightTop+data.length;
        }else {//缩容时右边的复制
            for (int i = rightTop; i < data.length; i++) {
                newData[i-newData.length]=data[i];
            }
            rightTop=rightTop-newData.length;
        }
        data=newData;
    }

    public void pushRight(E e){
        if(rightTop-1==leftTop){
            resize(2*data.length);//扩容
        }
        rightTop--;
        data[rightTop]=e;
    }
    @Override
    public void push(E e) {
        if(getLeftSize()<=getRightSize()){
            pushLeft(e);
        }else {
            pushRight(e);
        }
    }
    public E popLeft(){
        if(isLeftEmpty()){
            throw new IllegalArgumentException("左栈为空");
        }
        E ret=data[rightTop--];
        if(getSize()<=data.length/4&&data.length/2>=10){
            resize(data.length/2);
        }
        return ret;
    }
    public E popRight(){
        if(isRightEmpty()){
            throw new IllegalArgumentException("右栈为空");
        }
        E ret=data[rightTop++];
        if(getSize()<=data.length/4&&data.length/2>=10){
            resize(data.length/2);
        }
        return ret;
    }
    @Override
    public E pop() {
        if(getLeftSize()>=getRightSize()){
            return popLeft();
        }else {
            return popRight();
        }
    }
    public E peekLeft(){
        if(isLeftEmpty()){
            throw new IllegalArgumentException("左栈为空");
        }
        return data[leftTop];
    }
    public E peekRight(){
        if(isRightEmpty()){
            throw new IllegalArgumentException("右栈为空");
        }
        return data[rightTop];
    }
    @Override
    public E peek() {
        if(getLeftSize()>=getRightSize()){
            return peekLeft();
        }else {
            return peekRight();
        }
    }

    @Override
    public void clear() {
        data=(E[])(new Object[DEFAULT_SIZE]);
        leftTop=-1;
        rightTop=data.length;
    }

    @Override
    public String toString() {
        StringBuilder sb=new StringBuilder();
        sb.append(String.format("ArrayStackDoubleEnd:%d/%d\n",getSize(),data.length));
            if(isLeftEmpty()){
                sb.append("left:bottom [] top");
            }else {
                sb.append("left:bottom[");
                for (int i = 0; i < leftTop; i++) {
                    sb.append(data[i]);
                    if(i==leftTop){
                        sb.append("] top");
                    }else {
                        sb.append(',');
                    }
                }
            }
            sb.append('\n');
            if(isRightEmpty()){
                sb.append("right:top [] bottom\n");
            }else {
                sb.append("right:top [");
                for (int i = rightTop; i < data.length; i++) {
                    sb.append(data[i]);
                    if(i==data.length-1){
                        sb.append("] bottom");
                    }else {
                        sb.append(',');
                    }
                }
            }
            return sb.toString();
    }

    @Override
    public Iterator<E> iterator() {
        return null;
    }
    private class ArrayStackDoubleEndIterator implements Iterator{

        @Override
        public boolean hasNext() {
            return false;
        }

        @Override
        public Object next() {
            return null;
        }
    }
}

  • 通过链表实现栈(链栈):

import DS01.动态数组.Stack;
import DS02.动态链表.LinkedList;

import java.util.Iterator;

public class LinkedStack<E> implements Stack<E> {
    private LinkedList<E> list;
    public LinkedStack(){
        list=new LinkedList();
    }
    @Override
    public int getSize() {
        return list.getSize();
    }

    @Override
    public boolean isEmpty() {
        return list.isEmpty();
    }

    @Override
    public void push(E e) {
        list.addFirst(e);
    }

    @Override
    public E pop() {
        return list.removeFirst();
    }

    @Override
    public E peek() {
        return list.getFirst();
    }

    @Override
    public void clear() {
        list.clear();
    }

    @Override
    public Iterator<E> iterator() {
        return list.iterator();
    }
}

  • 双端链栈:
package DS02.动态链表;

import DS01.动态数组.Stack;

import java.util.Iterator;

public class LinkedStackDoubleEnd<E> implements Stack<E> {
    private Node left;
    private Node right;
    private int leftSize;
    private int rightSize;
    public LinkedStackDoubleEnd(){
        left=new Node();
        right=new Node();
        left.next=right;
        leftSize=0;
        rightSize=0;
    }
    private class Node{
        E data;
        Node next;
        Node(){
            this(null,null);
        }
        Node(E data,Node next){
            this.data=data;
            this.next=next;
        }
        public String toString(){
            return data.toString();
        }
    }
    public int getLeftSize(){
        return leftSize;
    }
    public int getRightSize(){
        return rightSize;
    }
    @Override
    public int getSize() {
        return leftSize+rightSize;
    }
    public boolean isLeftisEmpty(){
        return leftSize==0;
    }
    public boolean isRightisEmpty(){
        return rightSize==0;
    }
    @Override
    public boolean isEmpty() {
        return isLeftisEmpty()&&isRightisEmpty();
    }
    public void pushLeft(E e){
        left.next=new Node(e,left.next);
        leftSize++;
    }
    public void pushRight(E e){
        right.next=new Node(e,right.next);
        rightSize++;
    }
    @Override
    public void push(E e) {
        if(leftSize<=rightSize){
            pushLeft(e);
        }else {
            pushRight(e);
        }
    }
    public E popLeft(){
        if(isLeftisEmpty()){
            throw new IllegalArgumentException("左边为空");
        }
        E ret=left.next.data;
        left.next=left.next.next;
        leftSize--;
        return ret;
    }
    public E popRight(){
        if(isLeftisEmpty()){
            throw new IllegalArgumentException("右边为空");
        }
        E ret=right.next.data;
        right.next=right.next.next;
        rightSize--;
        return ret;
    }
    @Override
    public E pop() {
        if(leftSize>=rightSize){
            return popLeft();
        }else {
            return popRight();
        }
    }
    public E peekLeft(){
        if(isLeftisEmpty()){
            throw new IllegalArgumentException("左边为空");
        }
        return left.next.data;
    }
    public E peekRight(){
        if(isLeftisEmpty()){
            throw new IllegalArgumentException("右边为空");
        }
        return right.next.data;
    }
    @Override
    public E peek() {
        return leftSize>=rightSize?peekLeft():peekRight();
    }
    public void clearLeft(){
        left.next=right;
        leftSize=0;
    }
    public void clearRight(){
        right.next=null;
        rightSize=0;
    }
    @Override
    public void clear() {
        clearLeft();
        clearRight();
    }

    @Override
    public Iterator<E> iterator() {
        return null;
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值