Java面试宝典——栈与队列

栈与队列是在程序设计中被广泛使用的两种重要的线性数据结构,都是在一个特定范围的存储单元中存储的数据。

这些数据都可以重新被取出使用,与线性表相比,他们的插入和删除都受到更多的约束和限制,因此又称为“限定性的线性表结构”。

栈:后进先出LIFO

队列:先进先出FIFO

栈的两种实现方式

①用数组的方式实现栈

package stack;

import java.util.Arrays;

/** 
 * @author wyl
 * @time 2018年7月6日上午8:55:19
 */
public class MyStack<E> {

	private Object[] stack;
	private int size;//数组中存储元素个数
	public MyStack() {
		// TODO Auto-generated constructor stub
		stack=new Object[10];//初始长度为10
	}
	
	/**
	 * 判栈空
	 * @return
	 */
	public boolean isEmpty(){
		return size==0;
	}
	
	/**
	 * 返回栈顶元素~peek()方法不改变栈的值,不删除栈顶的值
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public E peek(){
		if (isEmpty()) {
			return null;
		}
		return (E) stack[size-1];
	}
	
	/**
	 * 出栈
	 * @return
	 */
	public E pop(){
		E e=peek();//获取栈顶元素
		stack[size-1]=null;
		size--;
		return e;
	}
	
	/**
	 * 入栈;入栈前需检查容量
	 * @return
	 */
	public E push(E item){
		ensureCapacity(size+1);//检查容量
		stack[size++]=item;
		return item;
	}
	
	/**
	 * 判断数组器是否已满,若已满,则扩充数组空间
	 * @param size
	 */
	private void ensureCapacity(int size){
		int len=stack.length;
		if (size>len) {//数组已满
			int newLen=10;//每次数组扩充的容量
			stack=Arrays.copyOf(stack, newLen);
		}
	}
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		MyStack<Integer> stack=new MyStack<>();
		stack.push(1);
		stack.push(3);
		stack.push(4);
		stack.push(2);
		System.out.println("栈中元素个数:"+stack.size);
		System.out.println("栈顶元素:"+stack.peek());
		System.out.println("出栈:"+stack.pop());
		System.out.println("栈中元素个数:"+stack.size);
	}

}

②用链表的方式实现栈

package stack;
/** 
 * @author wyl
 * @time 2018年7月6日上午9:22:16
 * 该操作不是线程安全的、若要实现线程安全的栈,需要对入栈和出栈等操作进行同步
 */
public class Stack<E> {

	Node<E> top=null;
	
	/**
	 *判栈空
	 */
	public boolean isEmpty(){
		return top==null;
	}
	/**
	 *入栈
	 */
	public void push(E data){
		Node<E> newNode=new Node<E>(data);
		newNode.data=data;
		top=newNode;
	}
	/**
	 *获取栈顶元素 peek
	 */
	public E peek(){
		if (isEmpty()) {
			return null;
		}
		return top.data;
	}
	/**
	 *出栈
	 */	
	public E pop(){
		if (this.isEmpty()) {
			return null;
		}
		E data=top.data;
		top=top.next;
		return data;
		
	}
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub

		Stack<Integer> s=new Stack<>();
		s.push(2);
		s.push(5);
		s.push(10);
		System.out.println("peek:"+s.peek());
		System.out.println("pop:"+s.pop());
	}

}
package stack;
/** 
 * @author wyl
 * @time 2018年7月6日上午9:23:37
 */
public class Node<E> {

	Node<E> next=null;
	E data;
	public Node(E data) {
		this.data = data;
	}
	
}

队列的两种实现方式

①用数组的方式实现队列

package queue;

import java.util.LinkedList;

/** 
 * @author wyl
 * @param <E>
 * @time 2018年7月6日上午10:12:52
 * 数组实现队列、为了实现多线程安全、增加了对队列操作的同步
 */
public class MyQueue1<E> {

	private LinkedList<E> list=new LinkedList<>();
	private int size=0;
	public synchronized void put(E e){
		list.add(e);
		size++;
	}
	public synchronized E pop(){
		size--;
		return list.removeFirst();
	}
	
	public synchronized boolean isEmpty(){
		return size==0;
	}
	
	public synchronized int size(){
		return size;
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		MyQueue1<Integer> queue1=new MyQueue1<>();
		queue1.put(1);
		queue1.put(2);
		queue1.put(3);
		System.out.println("size:"+queue1.size);
		System.out.println("队首元素:"+queue1.pop());
		System.out.println("队首元素:"+queue1.pop());
	}

}

②用链表的方式实现队列

package queue;
/** 
 * @author wyl
 * @param <E>
 * @time 2018年7月6日上午9:52:51
 */
public class MyQueue<E> {

	private Node<E> head=null;
	private Node<E> tail=null;
	
	/**
	 * 判空:head==tail
	 */
	public boolean isEmpty(){
		return head==tail;
	}
	/**
	 * 入队
	 */
	public void put(E data){
		Node<E> newNode=new Node<E>(data);
		if (head==null && tail ==null) { //队列为空
			head=tail=newNode;
		}else {
			tail.next=newNode;
			tail=newNode;
		}
	}
	/**
	 * 出队
	 */
	public E pop(){
		if (isEmpty()) {
			return null;
		}
		E data=head.data;
		head=head.next;
		return data;
	}
	/**
	 * 获取队列长度
	 */
	public int size(){
		Node<E> tmp=head;
		int n=0;
		while(tmp!=null){
			n++;
			tmp=tmp.next;
		}
		return n;
	}
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub

		MyQueue<Integer> queue=new MyQueue<>();
		queue.put(31);
		queue.put(9);
		queue.put(12);
		System.out.println("队列长度:"+queue.size());
		System.out.println("队列首元素:"+queue.pop());
	}

}

package queue;
/** 
 * @author wyl
 * @time 2018年7月6日上午9:52:58
 */
public class Node<E> {

	Node<E> next=null;
	E data;
	public Node(E data) {
		this.data = data;
	}
	
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Baymax_wyl

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值