Java语言实现栈

什么是栈:

栈(stack)是限定仅在表尾进行插入和删除操作的线性表。我们把允许插入和删除的一端称为栈顶(top),另一端称为栈底(bottom),不含任何元素的栈称为空栈。栈又被称为后进先出(last in first out)的线性表,简称LIFO。

栈的基本操作:

push(Object obj):入栈操作

pop():出栈操作

peek():获得栈顶元素

顺序栈:

栈的结构图如下所示:

Java语言实现栈_第1张图片


顺序栈的代码实现实例如下:

数组实现栈方式一 :数组长度固定

优点:入栈出栈速度快均为O(1)

缺点:栈的大小是一定的

package stack;
/**
 * 用数组来实现栈的操作一
 * 优点:入栈和出栈的速度快
 * 缺点:栈的长度是有限的
 *
 */
public class Stack {
	private int top = -1;
	private static Object[] objs;
	public Stack(int capacity) throws Exception{
		if(capacity < 0)
			throw new Exception("初始值不正确:"+capacity);
			objs = new Object[capacity];
	}
	//栈的大小
	public int size(){
		return top;
	}
	//判断栈是否为空
	public boolean isEmpty(){
		if(top == -1){
			return true;
		}else{
			return false;
		}
	}
	//入栈
	public void push(Object obj) throws Exception{
		if(top == objs.length - 1)
			throw new Exception("栈已经满了!");
			top ++;
			objs[top] = obj;
	}
	//出栈
	public Object pop() throws Exception{
		if(this.isEmpty())
			throw new Exception("栈为空!");
		Object result = objs[top];
		objs[top] = null;
		top --;
		return result;
	}
	//获取栈顶元素
	public Object peek() throws Exception{
		if(this.isEmpty()){
			throw new Exception("栈为空!");
		}
		Object result = objs[top];
		return result;
	}
	public void display(){
		System.out.print("从栈底到栈顶的元素依次为:");
		for(int i=0; i<=top; i++){
			System.out.print(objs[i]+" ");
		}
		System.out.println("\n");
	}
	
	public static void main(String[] args) throws Exception {
		Stack s = new Stack(5);
		s.push("A");
		s.push("B");
		s.push("C");
		s.display();
		System.out.println("删除的元素为:"+s.pop());
		System.out.println("栈顶的元素为:"+s.peek());
		s.display();
	}
}
数组实现方式二:数组的长度可以扩展

优点:没有长度限制

缺点:入栈出栈的时候速度比较慢出栈的时间并没有影响为O(1),而入栈的时间由于需要数组的扩容,再要将原数组的元素考入新数组,所以时间有可能为O(n)。

package stack;

import java.util.Arrays;

/**
 * 数组实现栈的操作二:
 * 优点:无长度限制
 * 缺点:入栈和出栈的速度慢
 *
 */
public class UnboundedStack {
	private int top = -1;
	private Object[] objs;
	public UnboundedStack() throws Exception{
		this(10);
	}
	
	public UnboundedStack(int capacity) throws Exception{
		if(capacity < 0)
			throw new Exception("Illeagal capacity:"+capacity);
		objs = new Object[capacity];
	}
	
	public int size(){
		return top;
	}
	
	public boolean isEmpty(){
		if(top == -1){
			return true;
		}else{
			return false;
		}
	}
	
	public void push(Object obj){
		if(top == objs.length-1){
			this.enlarge();
		}
		top ++;
		objs[top] = obj;
	}
	public Object pop() throws Exception{
		if(this.isEmpty())
			throw new Exception("Stack is Empty!");
		Object result = objs[top];
		objs[top] = null;
		top --;
		return result;
	}
	
	private void enlarge(){
		int num = objs.length/3;
		if(num == 0)
			num = 1;
			objs = Arrays.copyOf(objs, objs.length+num);
	}
	public Object peek() throws Exception{
		if(this.isEmpty()){
			throw new Exception("栈为空!");
		}
		Object result = objs[top];
		return result;
	}
	public void display(){
		System.out.print("从栈底到栈顶的元素依次为:");
		for(int i=0; i<=top; i++){
			System.out.print(objs[i]+" ");
		}
	}
	public static void main(String[] args) throws Exception {
		UnboundedStack us = new UnboundedStack(2);
		us.push("A");
		us.push("B");
		System.out.println("栈顶元素为:"+us.peek());
		us.display();
		System.out.println("删除的元素为:"+us.pop());
		us.display();
		us.push("C");
		us.push("D");
		System.out.println("栈顶元素为:"+us.peek());
		us.display();
	}
}

栈的链式存储结构:

入栈与出栈的结构图:

入栈:把当前元素赋值给新节点的直接后继,将新节点赋值为栈顶元素。data.next = top;  top = data;

出栈:将栈顶指针向下移动以为即可。Data temp = top;  top = first.next;

具体代码示例如下:

链表的方式实现栈:无长度的限制,插入和删除的时间复杂度均为O(1)

package stack;
/**
 * 单链表的形式实现栈:
 * 优点:长度不固定,插入删除的速度都为O(1)
 *
 */
public class LinkListStack {
	private class Data{
		private Object obj;
		private Data next = null;
		Data(Object obj){
			this.obj = obj;
		}
	}

	private Data top = null;
	//使用头插法进栈
	public void push(Object obj){
		Data data = new Data(obj);
		data.next = top;
		top = data;
	}
	public Object pop() throws Exception{
		if(top == null)
			throw new Exception("empty!");
		Data temp = top;
		top = top.next;
		return temp.obj;
	}
	public Object peek() throws Exception{
		if(top == null){
			throw new Exception("empty!");
		}
		return top.obj;
	}
	public void display(){
		if(top == null)
			System.out.println("empty");
		System.out.print("从栈顶到栈底的元素依次为:");
		Data data = top;
		while(data != null){
			System.out.print(data.obj.toString()+" ");
			data = data.next;
		}
		System.out.println("\n");
	}
	public static void main(String[] args) throws Exception {
		LinkListStack ll = new LinkListStack();
		ll.push("A");
		ll.push("B");
		ll.push("C");
		System.out.println("栈顶的元素为:"+ll.peek());
		ll.display();
		System.out.println("删除的元素为:"+ll.pop());
		ll.display();
	}
}


如果栈的使用过程中元素变化不可预料,有时候很小,有时候很大,就建议使用链栈。反之,如果栈的变化范围是可控的,建议使用顺序栈会好一些。

你可能感兴趣的:(Java语言实现栈)