Java实现栈和队列

一、  栈

 

1、概念

         栈是一种特殊的线性表,它只能在栈顶(top)进行插入(push)和删除(pop)操作。

 




栈的常用操作:

入栈(push):向栈顶插入元素

出栈(pop):从栈顶删除元素

访问栈顶元素(peek):访问栈顶元素

2、 栈的顺序结构的实现

public class SequenceStack<T> {

	private Object[] elementData; //数组用于承装元素 
	private int DEFAULT_SIZE = 20; //初始数组默认大小
	private int capacity;
	private int capacityIncrement = 5;
	private int size = 0; <span style="color:#009900;">//栈中当前容量
</span>	public SequenceStack(){
		capacity = DEFAULT_SIZE;
		elementData = new Object[capacity];
	}
	public SequenceStack(T element){
		this();
		elementData[0] = element;
		size++;
	}
	public int length(){     <span style="font-family: Arial, Helvetica, sans-serif;">//返回栈的长度</span></span>
		return this.size;
	}
	
	<span style="color:#009900;">//入栈操作</span>
	public void push(T element){
		this.ensureCapacity();
		elementData[size] = element;
		size++;
	}
	
	<span style="color:#009900;">//出栈操作</span>
	public T pop(){
		T popElement = (T)elementData[size-1];
		size--;
		return popElement;
	}
	
	<span style="color:#009900;">//访问栈顶元素</span>
	public T peek(){
		return (T)elementData[size-1];
	}
	
	<span style="color:#009900;">//判断是否为空</span>
	public boolean isEmpty(){
		boolean b = false;
		if(size == 0){
			b = true;
		}
		return b;
	}
	
	<span style="color:#009900;">//清空栈</span>
	public void clear(){
		for(Object o:elementData){
			o = null;
		}
		size = 0;
	}
	
	<span style="color:#009900;">//遍历栈</span>
	public void view(){
		System.out.print("当前栈中元素为:");
		for(int i = 0;i < size;i++){
			System.out.print(elementData[i] + " ");
		}
		System.out.println();
	}
	
	<span style="color:#009900;">//栈容量检测与扩充</span>
	public void ensureCapacity(){
		if(capacityIncrement > 0){
			while((size+1) > capacity){
				capacity+=capacityIncrement;
			}
		}
		else{
			while((size+1) > capacity){
				capacity = capacity * 2;
			}
		}
	}
	
	public static void main(String[] args) {
		SequenceStack<String> sequenceStack = new SequenceStack<> ();
		sequenceStack.push("hello");
		sequenceStack.push("world");
		sequenceStack.push("perfect");
		System.out.print("入栈操作后,");
		sequenceStack.view();
		sequenceStack.pop();
		System.out.print("出栈操作后,");
		sequenceStack.view();
		System.out.println("当前栈顶元素为:" + sequenceStack.peek());
		sequenceStack.clear();
		System.out.println("clear之后,栈是否为空:" + sequenceStack.isEmpty());
	}
}


3、栈的链式结构的实现

public class LinkedStack<T> {

	private class Node{
		private T data;
		private Node next;
		public Node(){
			
		}
		public Node(T element,Node next){
			this.data = element;
			this.next = next;
		}
	}
	
	private Node top;
	private int size = 0;
	
	public LinkedStack(){

	} 
	
	public LinkedStack(T element){
		top = new Node(element,null);
		size++;
	}
	//获取栈大小
	public int length(){
		return size;
	}
	//入栈操作
	public void push(T element){
		Node newNode;
		newNode = new Node(element, top);
		top = newNode;
		size++;
	}
	//出栈操作
	public T pop(){
		Node oldNode = top;
		top = top.next;
		oldNode.next = null;
		size--;
		return oldNode.data;
	}
	
	//获取栈顶元素
	public T peek(){
		return top.data;
	}
	
	//清空栈
	public void clear(){
		top = null;
		size = 0;
	}
	
	public boolean isEmpty(){
		if(size == 0){
			return true;
		}
		return false;
	}
	
	//遍历栈中元素
	public void view(){
		Node currentNode = top;
		System.out.print("栈中元素为:");
		while(currentNode != null){
			System.out.print(currentNode.data + " ");
			currentNode = currentNode.next;
		}
		System.out.println();
	}
	
	public static void main(String[] args) {
		LinkedStack<String> linkedStack = new LinkedStack<>();
		linkedStack.push("hello");
		linkedStack.push("world");
		linkedStack.push("perfect");
		System.out.print("入栈操作后,");
		linkedStack.view();
		linkedStack.pop();
		System.out.print("出栈操作后,");
		linkedStack.view();
		System.out.println("当前栈顶元素为:" + linkedStack.peek());
		linkedStack.clear();
		System.out.println("clear之后,栈是否为空:" + linkedStack.isEmpty());
	}
}


二、        队列 

1、概念

队列是一种被限制的线性表,它只允许在表的前端(front,即队尾)进行删除操作,只允许在表的后端(rear,即队头)进行插入操作

 

 

 

常用操作:

加入元素:向队列rear端插入元素

删除元素:从队列的front端删除元素

访问队列front端元素:

2、队列的顺序存储结构及实现

public class SequenceQueue<T> {

	private int DEFAULT_SIZE = 20;
	private int capacity;
	private int front = 0; 
	private int rear = 0;
	private Object[] elementData;
	public SequenceQueue(){
		capacity = DEFAULT_SIZE;
		elementData = new Object[capacity];
	}
	public SequenceQueue(T element){
		this();
		elementData[0] = element;
		rear++;
	}
	<span style="color:#009900;">// 获取队列长度</span>
	public int length(){
		return rear-front;
	}
	
	<span style="color:#009900;">//向队列尾添加元素</span>
	public void add(T element){
		if(rear > capacity-1){
			throw new IndexOutOfBoundsException("队列已满");
		}
		elementData[rear++] = element;
	}
	
	<span style="color:#009900;">//删除队列头元素</span>
	public T remove(){
		if((rear-front) == 0){
			throw new IndexOutOfBoundsException("队列为空,不能删除");
		}
		T remove = (T)elementData[front];
		elementData[front++] = null;
		return remove;
	}
	
	<span style="color:#009900;">//获取队列头部元素</span>
	public T getElement(){
		return (T)elementData[front];
	}
	
	<span style="color:#009900;">//判断队列是否为空</span>
	public boolean isEmpty(){
		return (rear-front) == 0;
	}
	
	<span style="color:#009900;">//清空队列</span>
	public void clear(){
		Arrays.fill(elementData, null);
		front = 0;
		rear = 0;
	}
	
	<span style="color:#009900;">//遍历队列</span>
	public void view(){
		System.out.print("队列中元素为:");
		for(int i = front;i < rear; i++){
			System.out.print(elementData[i] + " ");
		}
		System.out.println();
	}
	
	public static void main(String[] args) {
		SequenceQueue<String> sequenceQueue = new SequenceQueue<> ();
		sequenceQueue.add("hello");
		sequenceQueue.add("world");
		sequenceQueue.add("perfect");
		sequenceQueue.view();
		System.out.println("执行remove删除的元素为:" + sequenceQueue.remove());
		System.out.println("队列头部元素为:" + sequenceQueue.getElement());
		sequenceQueue.clear();
		System.out.println("clear之后队列长度:" + sequenceQueue.length());
		
	}

}

3、顺序存储结构的循环队列

public class LoopSequenceQueue<T> {

	private int DEFAULT_SIZE = 5;
	private int capacity;
	private int front = 0;
	private int rear = 0;
	private Object[] elementData;
	
	public LoopSequenceQueue(){
		capacity = DEFAULT_SIZE;
		elementData = new Object[capacity];
	}
	
	public LoopSequenceQueue(T element){
		this();
		elementData[0] = element;
		rear++;
	}
	
	<span style="color:#009900;">//获取队列长度</span>
	public int length(){
		if(isEmpty()){
			return 0;
		}
		return rear > front?rear-front:(capacity-(front-rear));
	}
	
	<span style="color:#009900;">//向队列中插入元素</span>
	public void add(T element){
		if(rear == front && elementData[front] != null){
			throw new IndexOutOfBoundsException("队列已满");
		}
		elementData[rear] = element;
		rear = (rear+1) > (capacity-1)?0:(++rear);
	}
	
	<span style="color:#009900;">//从队列头删除元素</span>
	public T delete(){
		if(isEmpty()){
			throw new IndexOutOfBoundsException("队列为空");
		}
		T del = (T)elementData[front];
		elementData[front] = null;
		front = (front+1) > capacity?0:++front;
		return del;
	}
	
	<span style="color:#009900;">//清空队列</span>
	public void clear(){
		Arrays.fill(elementData, null);
		front = 0;
		rear = 0;
	}
	
	<span style="color:#009900;">//遍历队列</span>
	public void view(){
		System.out.print("队列中元素为:");
		if(front < rear){
			for(int i = front;i < rear;i++){
				System.out.print(elementData[i] + " ");
			}
		}
		else{	
			for(int i = front;i < capacity;i++)
				System.out.print(elementData[i] + " ");
			for(int i = 0;i < rear;i++)
				System.out.print(elementData[i] + " ");
		}
	}
	
	<span style="color:#009900;">//判断队列是否为空</span>
	public boolean isEmpty(){
		if(front == rear && elementData[front] == null){
			return true;
		}
		return false;
	}
	
	public static void main(String[] args) {
		LoopSequenceQueue<String> loopSequenceQueue = new LoopSequenceQueue<>();
		loopSequenceQueue.add("hello");
		loopSequenceQueue.add("world");
		loopSequenceQueue.add("perfect");
		loopSequenceQueue.add("3333333");
		loopSequenceQueue.delete();
		loopSequenceQueue.add("4444444444");
		loopSequenceQueue.add("555555555");
		loopSequenceQueue.view();
		System.out.println("当前队列长度为:" + loopSequenceQueue.length());
		
		
	}

}


4、队列的链式存储结构

public class LinkedQueue<T> {

	private class Node{
		private T data;
		private Node next;
		public Node(){
			
		}
		
		public Node(T element,Node next){
			this.data = element;
			this.next = next;
		}
	}
	
	private Node front;
	private Node rear;
	private int size = 0;
	public LinkedQueue(){
		this.front = null;
		this.rear = null;
	}
	
	public LinkedQueue(T element){
		rear = new Node(element,null);
		front = rear;
		size++;
	}
	<span style="color:#009900;">//获取队列长度</span>
	public int length(){
		return size;
	}
	
	<span style="color:#009900;">//从队尾插入元素</span>
	public void add(T element){
		Node newNode = new Node(element,null);
		if(rear == null){
			rear = newNode;
			front = rear;
		}
		else{
			rear.next = newNode;
			rear = newNode;
		}
		
		size++;
	}
	<span style="color:#009900;">//删除队头元素</span>
	public T remove(){
		if(size == 0){
			throw new IndexOutOfBoundsException("队列为空,不能删除");
		}
		Node delNode = front;
		front = front.next;
		delNode.next = null;
		size--;
		return delNode.data;
	}
	
	<span style="color:#009900;">//清空队列</span>
	public void clear(){
		front = null;
		rear = null;
		size = 0;
	}
	
	<span style="color:#009900;">//遍历队列元素</span>
	public void view(){
		System.out.print("队列中元素为:");
		Node currentNode = front;
		while(currentNode != null){
			System.out.print(currentNode.data + " ");
			currentNode = currentNode.next;
		}
		System.out.println();
	}
	
	
	public static void main(String[] args) {
		LinkedQueue<String> linkedQueue = new LinkedQueue<> ();
		linkedQueue.add("hello");
		linkedQueue.add("world");
		linkedQueue.add("perfect");
		linkedQueue.add("3333333");
		linkedQueue.remove();
		linkedQueue.add("4444444444");
		linkedQueue.add("555555555");
		linkedQueue.view();
		System.out.println("当前队列长度为:" + linkedQueue.length());
		
	}

}

三、二者之间的相互转换

1、用两个栈模拟一个队列

//用栈A和栈B模拟队列Q,A为插入栈,B为弹出栈。
//入队列:入栈A。
//出队列:(1)如果栈B不为空,直接弹出B数据.(2)如果B为空,依次弹出A的数据,放入栈B中,再弹出栈B的数据。
public class StacksToQueue<E>
{
	Stack<E> stack1 = new Stack<> ();
	Stack<E> stack2 = new Stack<> ();
	
	//向队列尾部添加元素
	public void add(E element)
	{
		stack1.add(element);
	}
	
	//从队列头删除元素
	public E poll()
	{
		if(stack2.isEmpty())	//先检查stack2是否为空
		{
			if(stack1.isEmpty())	//stack2为空时,检查stack1是否为空
			{
				System.out.println("队列为空,poll操作失败!");
				return null; 
			}
			while(!stack1.isEmpty())
				stack2.push(stack1.pop());
		}
		return stack2.pop();
	}
	
	public static void main(String[] args)
	{
		StacksToQueue<Integer> queue = new StacksToQueue<>();
		queue.add(2);
		queue.add(5);
		queue.add(3);
		queue.add(8);
		System.out.println(queue.poll());
		System.out.println(queue.poll());
		System.out.println(queue.poll());
		System.out.println(queue.poll());
	}
}

2、用两个队列模拟一个栈

//先入栈:所有元素进入queue1.出栈的时候判断栈元素个数是否为1,如果为1,则queue1出队;如果不为1,queue1所有
//元素出队列,入queue2,最后一个元素不入queue2,输出该元素,然后queue2所有元素入queue1.实现了先进后出。
public class QueuesToStack<E>
{
	LinkedList<E> queue1 = new LinkedList<> ();
	LinkedList<E> queue2 = new LinkedList<> ();
	
	public void push(E element)
	{
		queue1.add(element);
	}
	
	public E pop()
	{
		if(queue1.size() == 0)
		{
			System.out.println("栈为空,pop失败!");
			return null;
		}
		while(queue1.size() != 1)
		{
			queue2.offer(queue1.poll());
		}
		E element = queue1.poll();
		while(!queue2.isEmpty())
			queue1.offer(queue2.poll());
		return element;
	}
	
	public static void main(String[] args)
	{
		QueuesToStack<Integer> stack = new QueuesToStack<>();
		stack.push(5);
		stack.push(4);
		stack.push(3);
		stack.push(2);
		System.out.println(stack.pop());
		System.out.println(stack.pop());
		System.out.println(stack.pop());
		stack.push(1);
		System.out.println(stack.pop());
		System.out.println(stack.pop());	
	}
}


 

 注:本文部分内容参考自《疯狂Java程序员的基本修养》

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值