栈的三种实现——Java语言描述

对于数据结构中常用的栈结构,其实现方式通常分为三种:

一、基于简单数组的实现方式

二、基于动态数组的实现

三、基于链表的实现方式

1、简单数组实现方式

//最大空间必须事先声明
public class ArrayStack {
	private int top;
	private int capacity;
	private int[] array;
	public ArrayStack() {
		capacity = 3;//申明栈的最大空间
		array = new int [capacity];
		top = -1;
	}
	public boolean isEmpyt() {
		return top == -1;
	}
	public boolean isStackFull() {
		return top == capacity - 1;
	}
	public void push(int data) {
		if(isStackFull()) {
			System.out.println("Stack Overflow");
		}else {
			array[++top] = data;
		}
	}
	public int pop() {
		if (isEmpyt()) {
			System.out.println("Stack is empyt");
			return 0;
		}else {
			return array[ top--];
		}
	}
	public void deleteStack() {
		top = -1;
	}
	public static void main(String[] args) {
		ArrayStack ast= new ArrayStack();
		ast.push(3);
		ast.push(7);
		ast.push(6);
		System.out.println(ast.pop());
	}
}

局限性:栈的最大空间必须预先声明且不能改变。试图对一个满栈执行入操作将产生一个栈满异常。

2、动态数组实现方法

为了解决栈满情况下的入栈溢出的异常,需要采用动态数组实现。

方案一、当栈满时,每次将数组的大小增加1,这样执行n次入栈操作总的时间开销为:

1+2+...+n = O(n^2),时间复杂度为平方级别。

方案二、重复倍增。这样执行n次入栈操作的时间开销为:

1+2+4+8+...+n/4+n/2+n = n(1+1/2 + 1/4 + 1/8 +.... + 4/n +2/n + 1/n) = 2n = O(n).所以采用倍增的方式n次push的时间开销更小,实际上Java中栈的默认实现方式也是采用该方式。

// 倍增太多可能导致内存溢出
public class DynArrayStack {
	private int top;
	private int capacity;
	private int[] array;
	public DynArrayStack() {
		capacity = 1;
		array = new int[capacity];
		top = -1;
	}
	public boolean isEmpty() {
		return top == -1;
	}
	public boolean isStackFull() {
		return (top == capacity - 1);
	}
	public void push(int data) {
		if(isStackFull()) {
			doubleStack();
		}
		array[++ top] = data;
	}
	private void doubleStack() {
		// TODO Auto-generated method stub
		int[] newArray = new int[capacity * 2];
		System.arraycopy(array, 0, newArray, 0, capacity);
		capacity = capacity * 2;
		array = newArray;
	}
	public int pop() {
		if(isEmpty()) {
			System.out.println("Stack is Empty!");	
			return 0;
		}else {
			return array[top --];
		}
	}
	public void deleteStack(){
		top = -1;
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		DynArrayStack dysta = new DynArrayStack();
		dysta.push(3);
		dysta.push(7);
		dysta.push(9);
		System.out.println(dysta.pop());
		System.out.println(dysta.isEmpty());
		
	}

}

3、使用链表也可以实现栈。通过在链表的头部插入元素的方式实现push操作,删除链表的表头节点(栈顶节点)实现pop操作。

public class LLStack {
    private LLNode headNode;
    public LLStack() {
        this.headNode = new LLNode();
    }
    public void push(int data) {
        if(headNode == null) {
            headNode = new LLNode(data);
        }else {
            LLNode llNode = new LLNode(data);
            llNode.setNext(headNode);
            headNode = llNode;
        }
    }
    public int top() {
        if (headNode == null) {
            return 0;
        }else {
            return headNode.getData();
        }
    }
    public int pop() {
        if(headNode == null) {
            System.out.println("stack Empty!");
            return 0;
        }else {
            int data = headNode.getData();
            headNode = headNode.getNext();
            return data;
        }
    }
    public boolean isEmpty() {
        if(headNode == null)    return true;
        else return false;
    }
    public void deleteStack() {
        headNode = null;
    }
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        LLStack llst = new LLStack();
        llst.push(6);
        llst.push(7);
        System.out.println(llst.pop());
    }
    public class LLNode {
        private int data;
        private LLNode next;
        public LLNode() {
            
        }

        public LLNode(int data) {
            this.data = data;
        }
        public int getData() {
            return data;
        }
        public void setData(int data) {
            this.data = data;
        }
        public LLNode getNext() {
            return next;
        }
        public void setNext(LLNode next) {
            this.next = next;
        }
        
    }

}

采用该方法唯一麻烦的地方在于删除链表时如果采用c++实现的链表,则删除链表需要循环链表删除所有元素,其时间复杂度为O(n),采用Java由于其垃圾回收机制可以直接将链表的头节点置为空即可。

以上就是栈的三种实现机制,Java中默认采用第二种方式,栈的初始大小为5000.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值