Java数组实现自定义栈

栈是一种“后进先出(LIFO)”的数据结构,最后压入的数据项总是位于栈顶的位置,下面是维基百科中对栈的定义:

堆栈英语:stack),也可直接称。台湾作堆叠,在计算机科学中,是一种特殊的串行形式的数据结构,它的特殊之处在于只能允许在链结串行或阵列的一端(称为堆叠顶端指标,英语:top)进行加入资料(英语:push)和输出资料(英语:pop)的运算。另外堆叠也可以用一维阵列连结串行的形式来完成。堆叠的另外一个相对的操作方式称为伫列

由于堆叠数据结构只允许在一端进行操作,因而按照后进先出(LIFO, Last In First Out)的原理运作。

堆叠数据结构使用两种基本操作:推入(push)和弹出(pop):

  • 推入:将数据放入堆叠的顶端(阵列形式或串行形式),堆叠顶端top指标加一。
  • 弹出:将顶端数据资料输出(回传),堆叠顶端资料减一。

实际应用:

a、在我们熟悉的图形化界面编程中,例如那种撤销操作,撤销最近一次执行的操作,大多数情况下就是使用栈这种特殊的数据结构来实现的,当然使用其他的方式也可以实现。

b、可以实现对一个字符串进行反转操作,当然这里是可以实现,但是并不推荐这样去做,实际上直接使用数组反序输出更加方便快捷,效率也更高。

1、首先我们先定义一个Stack Interface,我们把他定义成泛型的.

package com.stack;
/**
 * 栈接口
 * @author feizi
 * @time 2015-1-12下午3:23:32
 */
public interface StackInterface<E> {

	//获取堆栈长度
	public int size();

	//入栈
	public void push(E element) throws Exception;

	//出栈
	public E pop() throws Exception;

	//获取栈顶元素
	public E peek() throws Exception;

	//获取栈中元素个数
	public int getElementCount();

	//判断是否当前栈顶指针没有到达栈底
	public boolean hasMoreElement();

	//判断栈空
	public boolean isEmpty();

	//判断栈溢
	public boolean isFull();

	//清空栈
	public void clear();
}

2、然后,利用数组实现堆栈,

package com.stack;

import java.util.Arrays;

/**
 * 栈接口的具体实现类
 * @author feizi
 * @time 2015-1-12下午3:44:36
 */
public class ArrayStack<E> implements StackInterface<E> {

	private final int DEFAULT_SIZE = 3;//堆栈初始化时缺省大小
	private int maxSize;//堆栈的最大容量
	private E[] arrayObj;//数组

	private int top;//栈顶指针

	@SuppressWarnings("unchecked")
	public ArrayStack(){
		this.maxSize = DEFAULT_SIZE;
		this.arrayObj = (E[]) new Object[this.maxSize];
		top = -1;
	}

	@SuppressWarnings("unchecked")
	public ArrayStack(int size){
		this.maxSize = size;
		this.arrayObj = (E[]) new Object[this.maxSize];
		top = -1;
	}

	/**
	 * 获取堆栈长度
	 * @return
	 */
	public int size(){
		return this.maxSize;
	}

	/**
	 * 获取堆栈中元素个数
	 */
	public int getElementCount() {
		return this.top;
	}

	/**
	 * 入栈,
	 * @throws Exception
	 */
	public void push(E element) throws Exception {
		if(null == element){
			throw new Exception("入栈的元素不能为空!");
		}
		if(isFull()){
			//如果栈满,就扩容
			extendSize();

			//或者如果不想扩容的话,可以在此处抛出异常
			//throw new Exception("栈满不能入栈!");
		}
		this.arrayObj[++top] = element;
	}

	/**
	 * 出栈
	 * @throws Exception
	 */
	public E pop() throws Exception {
		if(isEmpty()){
			throw new Exception("栈空不能出栈");
		}

		//先保存栈顶元素
		E element = (E) arrayObj[top];
		//然后清空栈顶元素
		arrayObj[top] = null;
		//栈顶指针下移,栈中元素减少一个
		top--;
		return element;

		//或者
//		return (E) this.arrayObj[top--];
	}

	/**
	 * 获取栈顶元素,先判空
	 * @throws Exception
	 */
	public E peek() throws Exception {
		if(isEmpty()){
			throw new Exception("栈为空!");
		}
		return (E) this.arrayObj[getElementCount()];
	}

	/**
	 * 判断是否当前栈顶指针没有到达栈底
	 */
	public boolean hasMoreElement() {
		return getElementCount() >= 0 ? true : false;
	}

	/**
	 * 扩容,通常是在栈满以后才会扩充
	 */
	@SuppressWarnings("unchecked")
	public void extendSize(){
		this.maxSize = this.maxSize + this.DEFAULT_SIZE;
		Object[] newArray = new Object[this.maxSize];

		//使用java.lang包中提供的system.arrcopy()方法复制数组
		System.arraycopy(arrayObj, 0, newArray, 0, arrayObj.length);
		//将原数组置空
		Arrays.fill(arrayObj, null);

		this.arrayObj = (E[]) newArray;
	}

	/**
	 * 判断栈空
	 */
	public boolean isEmpty() {
		return this.top == -1;
	}

	/**
	 * 判断栈溢
	 */
	public boolean isFull() {
		return this.top + 1 == this.maxSize;
	}

	/**
	 * 清空栈
	 */
	@SuppressWarnings("unchecked")
	public void clear() {
		//将数组置空
		Arrays.fill(arrayObj, null);
		//栈顶指针重置
		this.top = -1;
		this.maxSize = this.DEFAULT_SIZE;
		this.arrayObj = (E[]) new Object[this.maxSize];
	}

	public static void main(String[] args) throws Exception {
		StackInterface<Object> myStack = new ArrayStack<Object>();
		System.out.println("==栈的总容量:"+myStack.size());
		System.out.println("==堆栈的元素个数:"+myStack.getElementCount());

		myStack.push(1);
		myStack.push("root");
		myStack.push(2);
		myStack.push(3);
		myStack.push("admin");
		myStack.push(4);
		myStack.push("feizi");

		System.out.println("==栈的总容量:"+myStack.size());
		System.out.println("==堆栈的元素个数:"+myStack.getElementCount());
		System.out.println("栈顶元素为:"+myStack.peek());

		while (myStack.hasMoreElement()) {
			System.out.println("栈指针:"+myStack.getElementCount()+",栈元素:"+myStack.pop());
		}

		//清空栈
		myStack.clear();
		System.out.println("==栈的总容量:"+myStack.size());
		System.out.println("==堆栈的元素个数:"+myStack.getElementCount());

		while (myStack.hasMoreElement()) {
			System.out.println("================栈顶元素为:"+myStack.peek());
			System.out.println("栈指针:"+myStack.getElementCount()+",栈元素:"+myStack.pop());
		}
	}
}
时间: 2024-10-28 14:09:49

Java数组实现自定义栈的相关文章

使用JAVA数组实现顺序栈

1,首先总结一下线性表(分为顺序表和链接表,[即顺序存储结构和链式存储结构的区别])和栈(顺序栈和链接栈)还有队列(顺序队列和链接队列)的JAVA类库中的实现: java.util.ArrayList 实现了顺序表,java.util.LinkedList 实现了链接表的功能. java.util.ArrayDeque实现了顺序栈和顺序队列(该类中即定义了与栈操作有关的方法,也定义了与队列操作有关的方法).java.util.LinkedList实现了链接栈和链接队列. 2,定义了一个Stack

Java数组与内存控制

一.Java数组初始化 Java数组是静态的,即当数组被初始化之后,该数组的长度是不可变的.Java数组使用之前必须先对数组对象进行初始化,所谓初始化,就是为数组的所有元素分配内存空间,并为每个数组元素指定初始值.(文章来源于李刚老师的<突破java程序员的16课>) 1:基本类型数组的两种初始化方式 静态初始化:初始化时由程序员显式指定每个数组元素的初始值,由系统决定数组长度. 动态初始化:初始化时程序员只指定数组长度,由系统为数组元素分配初始值. 不要同时使用静态初始化和动态初始化,也就是

java 数组比较,元素的比较,Comparable,Comparator比较的应用实现,排序,查找示例

java 数组比较,元素的比较,自定义Comparator的实现,排序,查找示例 package org.rui.array.compar; import java.util.Arrays; import java.util.Random; import org.rui.generics.anonymity.Generator; /** * 程序设计的基本目标是"将保持不变的事物与会发生改变的事物相分离" * 而这是,不变的是通用的排序算法,变化的是各种对象相互比较的方式, * 因此,

闭关修炼中 *** Java常用算法之 -- 栈结构

什么是栈结构: 栈结构从数据的运算来分类,栈结构具有特殊的运算规则. 从数据的逻辑结构来看,栈结构其实就是一种线性结构. but!!! 从数据的存储结构来划分,栈结构分为两类: 顺序表结构:即用一组地址连续的内存单元依次保存栈中的数据.在程序中,可以定义一个 指定大小的结构数组来作为栈,序号为0的元素就是栈底,在定义一个top保 存栈顶的序号. 链式栈结构:即使用链式形式保存栈中各元素的值.链表首部(head引用所指向元素)为栈顶, 链表尾部(指向地址为null)为栈底. 栈结构遵循:后进先出(

Java数组练习题小结

//2015/07/07 //Java数组小小练习题 /* 3. 写一个函数,计算一个整数数组的平均值 4. 自定义一个整数数组a,读入一个整数n,如果n 在数组中存在,则输出n 的下标:如果不存在,则输出-1. 5. 给定一个数组,输出数组中的最大值和最小值 6. *给定一个数组,把这个数组中所有元素顺序进行颠倒. 7. *完成数组的冒泡排序算法:给定一个数组:int[] a = {1,3,2,7,5},利用冒泡排序对其按照从小到大的顺序排序,然后输出结果. 8. *使用第二种算法对数组进行排

Java——数组

[数组] 注:C/C++中数组可以存储在栈中,但是Java中不可以(因为Java中是引用). [一维数组] 声明: type var[]; 或者 type[] var; Java语言生成数组时不能指定其长度(数组中元素的个数),例如int a[4]是非法的 (--因为Java中数据分配在堆中,是动态分配的:C语言可以). 数组对象的创建: 数组名 = new 数组元素的类型[数组元素的个数] [内存分配] 注:这表示在内存中new出5个对象,每个对象的初始化值为0(默认值). new int[5

java的堆,栈,静态代码区 详解

面试中,有家公司做数据库开发的,对内存要求比较高,考到了这个 一:在JAVA中,有六个不同的地方可以存储数据: 1. 寄存器(register). 这是最快的存储区,因为它位于不同于其他存储区的地方——处理器内部.但是寄存器的数量极其有限,所以寄存器由编译器根据需求进行分配.你不能直接控制,也不能在程序中感觉到寄存器存在的任何迹象. ------最快的存储区, 由编译器根据需求进行分配,我们在程序中无法控制. 2. 栈(stack).位于通用RAM中,但通过它的“栈指针”可以从处理器哪里获得支持

用数组写出栈(先进后出)

<pre name="code" class="java">//用数组写出栈(先进后出) import java.util.Collection; import java.util.NoSuchElementException; public class ArrayStack<E> { private int initalSize = 5; private Object[] stack; private int head; private i

java数组学习

1. java数组的静态特性:          java是静态语言,java中数组的长度是固定的.还有,数组元素的类型也是在定义时指定了的. 2. java数组里的关键词:          数组变量 : 引用变量 , 不过这个引用的类型是数组类型.数组类型很奇特,不需要程序员来设计类的属性和方法,只要在已知的引用类型(类,接口,还有数组)后加一个[], JVM就自动生成了这样的新类型.         作为一个变量,它是存在于栈空间中的.不过由于其是一个引用变量,其所指向的内容(保存的值)是