【数据结构】堆栈(顺序栈、链栈)的JAVA代码实现

时间:2021-08-20 10:27:04

堆栈(stack)是一种特殊的线性表,是一种只允许在表的一端进行插入或删除操作的线性表。表中允许进行插入和删除操作的一端称为栈顶,最下面的那一端称为栈底。栈顶是动态的,它由一个称为栈顶指针的位置指示器指示。当栈中没有数据元素时,为空栈。堆栈的插入操作称为进栈或入栈,堆栈的删除操作称为出栈或退栈。

栈的主要特点是“后进先出”,即后进栈的元素先被处理。因此,栈又被称为后进先出(last in first out,LIFO)表。它的实现方式主要有顺序栈、链栈两种。

堆栈的抽象数据类型

  1. 数据元素:可以为任意类型,只要同属于一种数据类型即可;
  2. 数据关系:数据元素之间呈线性关系;
  3. 数据操作:对堆栈的基本操作定义在IStack中,代码如下:
public interface IStack<E> {
	  E push(E item); //入栈
	  E pop(); //出栈
	  E peek(); //取栈顶元素
	  int size(); //返回栈中元素的个数
	  boolean empty(); //判断栈是否为空
}

顺序栈

用一片连续的存储空间来存储栈中的数据元素,这样的栈称为顺序栈。类似于顺序表,用一维数组来存放顺序栈中的数据元素。栈顶指示器top设在数组下标为最大的那一端,top随着插入或删除而变化。即当栈为空时,top=-1;其他时候,top为栈顶元素的索引号。

public class SeqStack<E> implements IStack<E> {
	private int maxsize; // 顺序栈的容量
	private E[] data; // 数组,用于存储顺序栈中的数据元素
	private int top; // 指示顺序栈的栈顶

	// 初始化栈
	@SuppressWarnings("unchecked")
	public SeqStack(Class<E> type, int size) {
		data = (E[]) Array.newInstance(type, size);
		maxsize = size;
		top = -1;
	}
	// 入栈操作
	public E push(E item) {
		if (!isFull()) {
			data[++top] = item;
			return item;
		}
       else
			return null;
	}
	// 出栈操作
	public E pop() {
		E item = null;
		if (!empty()) {
		item = data[top--];
		}
		return item;
	}

	// 获取栈顶数据元素
	public E peek() {
		E item = null;
		if (!empty()) {
			item = data[top];
		}
		return item;
	}
	//求栈的长度
		public int size() {
			return top+1;
		}
	// 判断顺序栈是否为空
	public boolean empty() {
		if (top == -1) {
			return true;
		} else {
			return false;
		}
	}
	// 判断顺序栈是否为满
	public boolean isFull() {
		if (top == maxsize - 1) {
			return true;
		} else {
			return false;
		}
	}
	
}

链栈

用链式存储结构存储的栈称为链栈,链栈通常用单链表来表示。它的结点结构与单链表的结构一样,都是由数据域data和引用域next两部分组成。由于链栈的操作只在一段进行(栈顶),为了操作方便,我们将栈顶设在链表的头部,即将栈顶指示器指向链表的头部,所有对栈的数据元素的增加和删除操作都在链表头部进行

public class StackNode<E> {
	private E data; // 数据域
	private StackNode<E> next; // 引用域
	 //构造函数
	public StackNode(){}
	public StackNode(E data) {
		this.data = data;	
	}
	public StackNode(E data, StackNode<E> next) {
		super();
		this.data = data;
		this.next = next;
	}
	//数据域get属性
	public E getData() {
		return data;
	}
	//数据域set属性
	public void setData(E data) {
		this.data = data;
	}
	//引用域get属性
	public StackNode<E> getNext() {
		return next;
	}
	//引用域get属性
	public void setNext(StackNode<E> next) {
		this.next = next;
	}
}
public class LinkStack<E> implements IStack<E> {
	private StackNode<E> top; // 栈顶指示器
	private int size; // 栈中结点的个数

	// 初始化链栈
	public LinkStack() {
		top = null;
		size = 0;
	}
	// 入栈操作
	public E push(E item) {
		StackNode<E> newnode = new StackNode<E>(item);
		if (!empty()) 
			newnode.setNext(top);
		top = newnode;
		++size;
		return item;
	}

	// 出栈操作
	public E pop() {
		E item=null;
		if (!empty())
	      {
	         item = top.getData();
		     top = top.getNext();
		     size--;
	      }    
	      return item;
	}
	// 获取栈顶数据元素
	public E peek() {
		E item=null;
		if (!empty())
	      {
	       item=top.getData();
	      }
	    return item;
	}

	// 求栈的长度
	public int size() {
		return size;
	}
	// 判断顺序栈是否为空
	public boolean empty() {
		 if ((top == null) && (size == 0))
	      {
	        return true;
	      }
	      else
	      {
	        return false;
	      }
	}
}

总结与分析

  • 位于java.util.Stack具有顺序栈的功能,LinkedList类提供了在列表开始与结尾添加、删除和显示数据元素的方法,使用这些方法把一个LinkedList当做链栈使用。