“栈”与“队列”呢点事(三)

292 阅读2分钟

本文主要分享了队列的实现原理,和基于队列的几种应用场景。队列和栈的实现原理,虽然很简单,但是万丈高楼平地起,盘龙卧虎高山齐。由简入繁,至臻化境,拈手即来。


所有源码均已上传至github: 链接

基于数组实现的顺序队列

1.首先需要初始化数组,申请一个大小为capacity的内存空间,并且初始化队头和队尾指针。

	public ArrayQueue(int capacity) {
		arrays = new int[capacity];
		size = capacity;
		head = 0;
		tail = 0;
	}

2.入队

	public boolean enqueuq(int num){
		if (tail == size)
			return false;
		arrays[tail++] = num;
		return true;
	}

问题:但是这里有个问题随着不停地进行入队、出队操作。head和tail一直在持续的向后移动,直到tail到达末端,无法移动,此时虽然有内存空间,但是却不能入队了。因为需要改造一下:如果没有空闲空间了,我们只需要在入队时,再集中触发一次数据的搬移操作即可

	public boolean enqueue(int num) {
		if (tail == size) {
			if(head == 0) return false;
			//数据搬移
			for (int i = head; i < tail; i++) {
				arrays[i-head] = arrays[i];
			}
			tail -= head;
			head = 0;
		}
		arrays[tail++] = num;
		return true;
	}

改造:再稍加改造就是一个循环队列的入队

 public boolean enqueue(int num) {
    if ((tail + 1) % size == head) 
		return false;
    arrays[tail] = num;
    tail = (tail + 1) % size;
    return true;
 }

3.出队

	public int dequeue() {
		if (head == tail)
			return -1;// 这里-1表示队空
		int res = arrays[head++];
		return res;
	}

改造:再稍加改造就是一个循环队列的出队

 public String dequeue() {
    if (head == tail) 
		return -1;
    int ret = arrays[head];
    head = (head + 1) % size;
    return ret;
 }

4.测试结果


注意:循环队列一定要确定好队空和队满的判定条件;并且循环队列还有占用一个数组的存储空间。判断队满(tail+1)%n=head(想不明白,画一画就知道了)

基于链表实现的链式队列

1.入队

	public void enqueue(int num) {
		if (tail == null) {
			Node node = new Node(num, null);
			head = node;
			tail = node;
		}else {
			tail.next = new Node(num, null);
			tail = tail.next;
		}
	}

2.出队

	public int dequeue() {
		if(head == null) return -1;//-1表示队空
		int res = head.data;
		head = head.next;
		if (head == null) {
			tail = null;
		}
		return res;
	}

3.测试结果


扩展

下一篇将分享走进不一样的斐波那契数列。

end


您的点赞和关注是对我最大的支持,谢谢!