DS08-队列的实现方式之链表实现(使用尾指针)

链表的结构决定了再链表头进行添加/删除操作时时间复杂度仅为O(1),但是对链表尾部进行操作的时间复杂度为O(n),而队列是一种先进先出的数据结构,既要对队首进行操作,也要对队尾进行操作,所以必须对链表进行一点修改,才能实现时间复杂度为O(1)的队列.

修改的方式就是添加一个尾指针,指向链表的最后一个节点,这个操作只是针对实现队列时的优化,使得在链表尾部添加元素的时间复杂度从O(n)将为O(1),也就是不需要从头到尾遍历,但是在链表尾部删除元素的时间复杂度依然是O(n),因为删除时没有办法获取被删除节点的前一个结点(因为没有使用双向链表).

在链表中使用尾节点要注意链表为空的时候,head和tail都指向null,当链表中只有一个元素的时候,head和tail指向同一个节点.

实现时依然是先创建一个Queue接口类,用于定义队列的一些必要操作,然后创建一个LinkedListQueue类,实现Queue接口就可以了.

具体代码如下:
Queue接口类:

public interface Queue<E> {
	public void enqueue(E e);
	public E dequeue();
	public E getFront();
	public int getSize();
	public boolean isEmpty();
}

LinkedListQueue实现类:

/**
 * 使用带有尾指针的链表实现队列
 * @author ChenZhuJi
 *
 * @param <E>
 */
public class LinkedListQueue<E> implements Queue<E> {	
	private class Node {
		public E e;	//节点中存储的数据
		public Node next;	//下一个节点
		
		public Node(E e,Node next) {
			this.e = e;
			this.next = next;
		}
		
		public Node() {
			this(null,null);
		}
		
		public Node(E e) {
			this(e,null);
		}
		
		@Override
		public String toString() {
			return e.toString();
		}
	}
	
	private Node head;	//头指针
	private Node tail;	//尾指针
	private int size;		//节点个数
	
	public LinkedListQueue() {
		head = null;
		tail = null;
		size = 0;
	}
	
	/**
	 * 获取队列中元素个数
	 */
	@Override
	public int getSize() {
		return size;
	}
	
	/**
	 * 判断队列是否为空
	 */
	@Override
	public boolean isEmpty() {
		return size == 0;
	}
	
	/**
	 * 入队操作
	 */
	@Override
	public void enqueue(E e) {
		if(tail == null) {
			head = new Node(e);
			tail = head;
			size++;
		} else {
			tail.next = new Node(e);
			tail = tail.next;
			size ++;
		}
	}

	/**
	 * 出队操作
	 */
	@Override
	public E dequeue() {
		if( isEmpty() ) {
			throw new IllegalArgumentException("队列为空");
		}
		Node ret = head;
		head = head.next;
		ret.next = null;
		if(head == null) {
			tail = null;
		}
		size --;
		return ret.e;
	}

	/**
	 * 获取队头元素
	 */
	@Override
	public E getFront() {
		if( isEmpty() ) {
			throw new IllegalArgumentException("队列为空");
		} 
		return head.e;
	}
	
	@Override
	public String toString() {
		StringBuilder sb = new StringBuilder("LinkedListQueue : front  ");
		Node pre = head;
		while(pre != null) {
			sb.append(pre.e + "->");
			pre = pre.next;
		}
		sb.append("null  tail");
		return sb.toString();
	}
	
	public static void main(String[] args) {
		LinkedListQueue<Integer> llq = new LinkedListQueue<Integer>();
		for(int i = 0; i < 5; i++) {
			llq.enqueue(i);
			System.out.println(llq);
		}
		
		llq.dequeue();
		System.out.println(llq);
	}
	
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值