您的位置:首页 > 编程语言 > Java开发

堆栈和队列的java实现

2015-11-19 18:53 801 查看

1.堆栈

堆栈是一种后进先出(LIFO)的数据结构。主要要实现的方法有判断堆栈是否为空,输出堆栈的顶部元素,添加元素,删除元素,创建一个包含这几个方法的接口如下:

public interface Stack {

public boolean isEmpty();             //判断堆栈是否为空
public Object peek();                 //返回堆栈的顶部元素
public void push(Object theElement);   //从顶部添加元素
public Object pop();                  //删除顶部元素并返回被删除的元素

}


1.数组实现

import java.lang.reflect.Array;
import java.util.EmptyStackException;

public class ArrayStack implements Stack{

int top;            //current top of stack
Object element[];    //element array

/**create a stack with the given initial capacity
*@throws IlleagalArgumentException when initialCapacity<1*/
public ArrayStack(int initialCapacity){
if(initialCapacity<1){
throw new IllegalArgumentException ("initialCapacity must be >=1");
}
element=new Object[initialCapacity];
top=-1;
}

/**create a stack with initial capacity 10*/
public ArrayStack(){
this(10);
}

/** @return true iff stack is empty*/
@Override
public boolean isEmpty() {
// TODO Auto-generated method stub
return top==-1;
}

/** @return top element of stack
*  @throw EmptyStackException when the stack is empty*/
@Override
public Object peek() {
// TODO Auto-generated method stub
if(isEmpty()){
throw new EmptyStackException();
}
return element[top];
}

/** add the element to the top of stack*/
@Override
public void push(Object theElement) {
// TODO Auto-generated method stub

//increase array size if necessary
if(top==element.length-1){
element=changeArrayLength1D(element,2*element.length);
}
//put the element at the top of stack
element[++top]=theElement;
}

private Object[] changeArrayLength1D(Object[] element2, int i) {
// TODO Auto-generated method stub
if(element2.length>i){
throw new IllegalArgumentException("new length too small");
}
Object newArray[]=(Object[])Array.newInstance(element2.getClass().getComponentType(), i);
System.arraycopy(element2, 0, newArray, 0, element2.length);
return newArray;
}

/** @return top element of stack
*  remove top element of stack
*  @throw EmptyStackException when the stack is empty*/
@Override
public Object pop() {
// TODO Auto-generated method stub
if(isEmpty()){
throw new EmptyStackException();
}
Object topElement=element[top];
element[top--]=null;   //enable garbage collection
return topElement;
}

/** @return string converted from stack*/
public String toString(){
StringBuilder s=new StringBuilder("[");
for(int i=top;i>=0;i--){
s.append(element[i].toString()+",");
}
s.append("]");
return s.toString();
}

}


构造方法的复杂度是O(n),isEmpty(),peek(),pop方法的复杂度为O(1),push的复杂度是O(n)(当不需要增加容量时为O(1)),toString()方法的复杂度为O(n)。

2.链式实现

import java.util.EmptyStackException;

class ChainNode{
Object element;
ChainNode next;

ChainNode(){}

ChainNode(Object element){
this.element=element;
}

ChainNode(Object element,ChainNode next){
this.element=element;
this.next=next;
}
}

public class LinkedStack implements Stack{

protected ChainNode topNode;

public LinkedStack(int initialCapacity){}

public LinkedStack(){}

@Override
public boolean isEmpty() {
// TODO Auto-generated method stub
return topNode==null;
}

@Override
public Object peek() {
// TODO Auto-generated method stub
if(isEmpty()){
throw new EmptyStackException();
}
return topNode.element;
}

@Override
public void push(Object theElement) {
// TODO Auto-generated method stub
topNode=new ChainNode(theElement,topNode);
}

@Override
public Object pop() {
// TODO Auto-generated method stub
if(isEmpty()){
throw new EmptyStackException();
}
Object topElement=topNode.element;
topNode=topNode.next;
return topElement;
}

public String toString(){
StringBuilder s=new StringBuilder("[");
ChainNode p=topNode;
while(p!=null){
s.append(p.element.toString()+",");
p=p.next;
}
s.append("]");
return s.toString();
}
}


除了toString()方法复杂度为O(n)外,其余方法复杂度都为O(1)。

2.队列

队列是一种先进先出(FIFO)的数据结构。主要要实现的方法和堆栈是差不多的,创建一个队列接口如下:

public interface Queue {

public boolean isEmpty();
public Object getFrontElement();//得到队列前端元素
public Object getRearElement(); //得到队列末端元素
public void put(Object theElement);
public Object remove();
}


1.数组实现

import java.lang.reflect.Array;

public class ArrayQueue implements Queue{

private int front,rear;
private Object[] element;

public ArrayQueue(int initialCapacity){
front=0;
rear=0;
element=new Object[initialCapacity];
}

public ArrayQueue(){
this(10);
}

@Override
public boolean isEmpty() {
// TODO Auto-generated method stub
return rear==front;
}

@Override
public Object getFrontElement() {
// TODO Auto-generated method stub
if(isEmpty()){
throw new EmptyStackException();
}
return element[front];
}

@Override
public Object getRearElement() {
// TODO Auto-generated method stub
if(isEmpty()){
throw new EmptyStackException();
}
int r=0;
if(rear>0){
r=rear-1;
}
else
r=element.length-1;
return element[r];
}

@Override
public void put(Object theElement) {
// TODO Auto-generated method stub

if((rear+1)%element.length==front){
Object newQueue[]=(Object[])Array.newInstance(element.getClass().getComponentType(), 2*element.length);
if(front==0)
System.arraycopy(element, front, newQueue, front, element.length-1);
else{
System.arraycopy(element, front, newQueue, front, element.length-front);
System.arraycopy(element, 0, newQueue, element.length, front-1);
}
rear=front+element.length;
element=newQueue;
element[rear-1]=theElement;
}
else{
element[rear]=theElement;
rear=(rear+1)%element.length;
}
}

@Override
public Object remove() {
// TODO Auto-generated method stub
if(isEmpty()){
throw new EmptyStackException();
}
Object removedElement=element[front];
front=(front+1)%element.length;
return removedElement;
}

public String toString(){
StringBuilder s=new StringBuilder("[");
if(front<rear){
for(int i=front;i<rear;i++){
s.append(element[i].toString()+",");
}
}
else{
for(int i=front;i<element.length;i++){
s.append(element[i].toString()+",");
}
for(int i=0;i<rear;i++){
s.append(element[i].toString()+",");
}
}
s.append("]");
if(!isEmpty()){
s.delete(s.length()-2,s.length()-1);
}
return s.toString();
}
}


构造方法复杂度为O(n),put(),toString()方法复杂度为O(n),其余方法复杂度为O(1)。

2.链式实现

import java.util.EmptyStackException;

class ChainNode{
Object element;
ChainNode next;
ChainNode(){}
ChainNode(Object element){
this.element=element;
}
ChainNode(Object element,ChainNode next){
this.element=element;
this.next=next;
}
}

public class LinkedQueue implements Queue{

ChainNode front,rear;
public LinkedQueue(int initialCapacity){}
public LinkedQueue(){}

@Override
public boolean isEmpty() {
// TODO Auto-generated method stub
return front==null;
}

@Override
public Object getFrontElement() {
// TODO Auto-generated method stub
if(isEmpty()){
throw new EmptyStackException();
}
return front.element;
}

@Override
public Object getRearElement() {
// TODO Auto-generated method stub
if(isEmpty()){
throw new EmptyStackException();
}
return rear.element;
}

@Override
public void put(Object theElement) {
// TODO Auto-generated method stub
ChainNode p=new ChainNode(theElement,null);
if(front==null)
front=p;
else
rear.next=p;
rear=p;
}

@Override
public Object remove() {
// TODO Auto-generated method stub
if(isEmpty()){
throw new EmptyStackException();
}
Object removedElement=front.element;
front=front.next;
if(isEmpty())
rear=null;        //enable garbage collection
return removedElement;
}

public String toString(){
StringBuilder s=new StringBuilder("[");
ChainNode p=front;
while(p!=null){
s.append(p.element.toString()+",");
p=p.next;
}
s.append("]");
if(!isEmpty()){
s.delete(s.length()-2,s.length()-1);
}
return s.toString();
}
public static void main(String args[]){
LinkedQueue s=new LinkedQueue();
System.out.println(s.isEmpty());
for(int i=1;i<8;i++){
s.put(new Integer(i));
}
System.out.println(s.isEmpty());
System.out.println(s.toString());
for(int i=1;i<6;i++){
s.remove();
}
System.out.println(s.isEmpty());
System.out.println(s.toString());
for(int i=1;i<4;i++){
s.put(new Integer(i));
}
System.out.println(s.toString());
for(int i=1;i<5;i++){
s.put(new Integer(i));
}
System.out.println(s.toString());
for(int i=1;i<5;i++){
s.put(new Integer(i));
}
System.out.println(s.toString());
System.out.println(s.getFrontElement());
System.out.println(s.getRearElement());
}

}


toString()方法复杂度为O(n),其余方法复杂度为O(1)。

3.总结

用数组实现比链式实现的方法少用内存而且时间更快,但是如果存在多个堆栈或队列,而它们的长度总和是一定的,但每个数组的范围都差不多要到从0到它们的长度总和,这个时候使用链式实现方法要更好。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息