`

java 实现数据结构之栈

阅读更多
   在学数据结构课程时,对栈的最大特点是是后进先出(First In Last Out),对栈的操作主要是入栈和出栈,判断栈是否为空,计算栈的大小。
   栈是一种数据结构,它代表只能在某一端进行插入、删除操作的特殊线性表。对栈而言,允许插入删除的一端是栈顶,另一端则称为栈底。
1.栈的顺序存储实现:
public class Stack 
{
	//存放栈内元素的数组
	private Object[] elementData; 
	//记录栈内元素的个数
	private int size = 0;
	//以指定初始化容量创建一个Stack
	private int capacityIncrement;
	//以指定初始化容量创建一个Stack
	public Stack(int initialCapacity) 
	{
		elementData = new Object[initialCapacity];
	}
	public Stack(int initialCapacity , int capacityIncrement)
	{
		this(initialCapacity);
		this.capacityIncrement = capacityIncrement;
	}
	//向“栈”顶压入一个元素
	public void push(Object object)
	{
		ensureCapacity();
		elementData[size++] = object;
	}
	public Object pop()
	{
		if(size == 0)
		{
			throw new RuntimeException("空栈异常");
		}
		return elementData[--size];
	}
	public int size()
	{
		return size;
	}
	//保证底层数组能容纳栈内所有元素
	private void ensureCapacity()
	{ //增加堆栈的容量
		if(elementData.length==size)
		{
			Object[] oldElements = elementData;
			int newLength = 0;
			//已经设置capacityIncrement
			if (capacityIncrement > 0)
			{
				newLength = elementData.length + capacityIncrement;
			}
			else
			{
				//将长度扩充到原来的1.5倍
				newLength = (int)(elementData.length * 1.5);
			}
			elementData = new Object[newLength];
			//将原数组的元素复制到新数组中
			System.arraycopy(oldElements , 0 , elementData , 0 , size);
		}
	}
	public static void main(String[] args)
	{
		Stack stack = new Stack(10);
		//向栈顶压入10个元素
		for (int i = 0 ; i < 10 ; i++)
		{
			stack.push("元素" + i);
			System.out.println("元素" + i+"入栈");
		}
		//依次弹出10个元素
		for (int i = 0 ; i < 10 ; i++)
		{
			System.out.println(stack.pop()+"出栈");
		}
	}
}

运行结果:
元素0入栈
元素1入栈
元素2入栈
元素3入栈
元素4入栈
元素5入栈
元素6入栈
元素7入栈
元素8入栈
元素9入栈
元素9出栈
元素8出栈
元素7出栈
元素6出栈
元素5出栈
元素4出栈
元素3出栈
元素2出栈
元素1出栈
元素0出栈


2.栈的链式存储实现:
public class LinkStack<T>
{
	//定义一个内部类Node,Node实例代表链栈的节点。
	private class Node
	{
		//保存节点的数据
		private T data;
		//指向下个节点的引用
		private Node next;
		//无参数的构造器
		public Node()
		{
		}
		//初始化全部属性的构造器
		public Node(T data , Node next)
		{
			this.data = data;
			this.next = next;
		}
	}
	//保存该链栈的栈顶元素
	private Node top;
	//保存该链栈中已包含的节点数
	private int size;
	//创建空链栈
	public LinkStack()
	{
		//空链栈,top的值为null
		top = null;
	}
	//以指定数据元素来创建链栈,该链栈只有一个元素
	public LinkStack(T element)
	{
		top = new Node(element , null);
		size++;
	}
	//返回链栈的长度	
	public int length()
	{
		return size;
	}
	//进栈
	public void push(T element)
	{
		//让top指向新创建的元素,新元素的next引用指向原来的栈顶元素
		top = new Node(element , top);
		size++;
	}
	//出栈
    public T pop()
	{
		Node oldTop = top;
		//让top引用指向原栈顶元素的下一个元素
		top = top.next;
		//释放原栈顶元素的next引用
		oldTop.next = null;
		size--;
		return oldTop.data;
	}
	//访问栈顶元素,但不删除栈顶元素
	public T peek()
	{
		return top.data;
	}
	//判断链栈是否为空栈
	public boolean empty()
	{
		return size == 0;
	}
	//清空链栈
	public void clear()
	{
		//将底层数组所有元素赋为null
		top = null;
		size = 0;
	}
	public String toString()
	{
		//链栈为空链栈时
		if (empty())
		{
			return "[]";
		}
		else
		{
			StringBuilder sb = new StringBuilder("[");
			for (Node current = top ; current != null
				; current = current.next )
			{
				sb.append(current.data.toString() + ", ");
			}
			int len = sb.length();
			return sb.delete(len - 2 , len).append("]").toString();
		}
	}
}



java集合提供了两种栈供开发者使用:
java.util.Stack:一个普通的顺序栈,底层基于数组实现。这个Stack类是线程安全的。
java.util.LinkedList:是一个双向链表。线程不安全,可以当做栈来使用,提供了push(),pop(),peek()等方法。在多线程环境下使用,可以使用Collections类的工具方法将其改造成线程安全类。
1
2
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics