Data Structures and Algorithms - Detailed queue

Foreword

  • 栈和队列A pair of brothers, we introduced earlier data structures and algorithms - Detailed stack , the stack mechanism is relatively simple, after first-out, is like entering a small cave, the cave is only one exit, can only last in first out (in outside first out) . The queue is like a tunnel, along with the people behind the front walk, in front of people get out (FIFO) . Everyday 排队is a description of the operation in the form of queue!
  • So the queue 核心理念is: First In First Out!
  • Concept queues : queue is a special 线性表, special is that it only allows the table 前端(front)delete operation, and the table 后端(rear)insertion operation, the stack and, as the queue is a 操作受限制linear form. Called terminal insertion operation 队尾, a delete operation is called end 队头.
  • At the same time, read the article is preferably biased to understand the basic operation of the sequence table and the data structure of the stack ! Learning better!
    Here Insert Picture Description

Queue Introduction

The basic properties

Head-front:

  • Delete one end of the data. For an array , 从后面插入更容易,前面插入较困难it is generally implemented using an array HOL queue earlier. (Delete direct index advances the cursor, you can not exceed the tail). As for the list . Insert delete 两头分别进行it 头部(前面)删除尾部插入is the most convenient option.

The tail rear:

  • One end of the inserted data, supra, and the linked list in the array 通常均在尾部位置. Of course, the list is actually an array of front and rear and there is a small difference, would later introduce specific.

enQueue (the team):

  • In the 队尾rear insert elements

deQueue (the team):

  • In 对头front Removing elements

Normal queue

According to the above description, it is easy to know an array of ways to achieve. With the 数组模拟express queue. To consider initialize, insert, problem.
Here Insert Picture Description

  • Initialization: front and rear array of point 0.
  • Enqueuing: 队不满, , 数组不越界first pass the value of the tail position, and then the tail index +1
  • A team: the team is not empty, the first team to take the head position of the element, the head +1 in the team,

But it is easy to find the problem , 每个空间域只能利用一次. Causing 空间extreme 浪费. And very easy 越界!
Here Insert Picture Description

Circular queue

In response to these problems. There is a better solution! It is to have applied for the (array) of memory 重复利用. This is what we call the circular queue.

The loop through the array queue is implemented in 逻辑上slightly modified. We 假设(the agreement) array of the last bit of the next index is the first . Since we only need to queue in front and tail two indicators. The actual data need not associated address location of the array. And it has nothing to do. So we only need to consider special to tail.

  • Initialization: front and rear array of point 0.
  • Into the team: dissatisfaction with the tail first position by value, thenrear=(rear + 1) % maxsize;
  • A team: the team is not empty, the first team to take the head position of the element,front=(front + 1)%maxsize;
  • It is empty:return rear == front;
  • size:return (rear+maxsize-front)%maxsize;

And there are a few we need to note is that adding indexes if they need to go to the head of the last words. The array can be determined whether the end position. It can also be directly +1 remainder. Which maxsizeis the actual size of the array.
Here Insert Picture Description

Chain to achieve

Queue link list for implementation, according to 先进先出the rules of the consideration of the position of the head and tail

我们知道队列是先进先出的,对于链表,我们能采用单链表尽量采用单链表,能方便尽量方便,同时还要兼顾效率

  • 方案一 如果队头设在链表尾,队尾设在链表头。那么队尾进队插入在链表头部插入没问题。容易实现,但是如果队头删除在尾部进行,如果不设置尾指针要遍历到队尾,但是设置尾指针删除需要将它指向前驱节点那么就需要双向链表。都挺麻烦的。

  • 方案二但是如果队头设在链表头,队尾设在链表尾部,那么队尾进队插入在链表尾部插入没问题(用尾指针可以直接指向next)。容易实现,如果队头删除在头部进行也很容易,就是我们前面常说的头节点删除节点

  • 所以我们最终采取的是方案2的带头节点,带尾指针的单链表!

主要操作为:

  • 初始化:
public class listQueue<T> {
	static class node<T> {
		T data;// 节点的结果
		node next;// 下一个连接的节点
		public node() {}
		public node(T data) {
			this.data = data;
		}
	}
	node front;//相当于head 带头节点的
	node rear;//相当于tail/end
	public listQueue() {
		front=new node<T>();
		rear=front;
	}
  • 入队:rear.next=va;rear=va;(va为被插入节点)
    Here Insert Picture Description
  • 出队:队不空,front.next=front.next.next;经典带头节点删除
    Here Insert Picture Description
  • 是否为空:return rear == front;
  • 大小:节点front遍历到rear的个数。

具体实现

数组实现

package 队栈;

public class seqQueue<T> {
	private T data[];// 数组容器
	private int front;// 头
	private int rear;// 尾
	private int maxsize;// 最大长度

	public seqQueue(int i)// 设置长为i的int 型队列
	{
		data = (T[]) new Object[i+1];
		front = 0;
		rear = 0;
		maxsize = i+1;
	}

	public int  lenth() {
		return (rear+maxsize-front)%maxsize;
	}
	public boolean isempty() {
		return rear == front;
	}

	public boolean isfull() {
		return (rear + 1) % maxsize == front;
	}

	public void enQueue(T i) throws Exception// 入队
	{
		if (isfull())
			throw new Exception("已满");
		else {
			data[rear] = i;
			rear=(rear + 1) % maxsize;
		}
	}

	public T deQueue() throws Exception// 出队
	{
		if (isempty())
			throw new Exception("已空");
		else {
			T va=data[front];
			front=(front+1)%maxsize;
			return va;
		}
	}

	public String toString()// 输出队
	{
		String va="队头: ";
		int lenth=lenth();
		for(int i=0;i<lenth;i++)
		{
			va+=data[(front+i)%maxsize]+" ";
		}
		return va;
	}

}

链式实现

package 队栈;

public class listQueue<T> {
	static class node<T> {
		T data;// 节点的结果
		node next;// 下一个连接的节点
		public node() {}
		public node(T data) {
			this.data = data;
		}
	}
	node front;//相当于head 带头节点的
	node rear;//相当于tail/end
	public listQueue() {
		front=new node<T>();
		rear=front;
	}
	public int  lenth() {
		int len=0;
		node team=front;
		while(team!=rear)
		{
			len++;team=team.next;
		}
		return len;
	}
	public boolean isempty() {
		return rear == front;
	}
	public void enQueue(T value) // 入队.尾部插入
	{
		node va=new node<T>(value);
		rear.next=va;
		rear=va;
	}

	public T deQueue() throws Exception// 出队
	{
		if (isempty())
			throw new Exception("已空");
		else {
			T va=(T) front.next.data;
			front.next=front.next.next;
			return va;
		}
	}
	public String toString()
	{
		node team=front.next;
		String va="队头: ";
		while(team!=null)
		{
			va+=team.data+" ";
			team=team.next;
		}
		return va;
	}
}

測試

Here Insert Picture Description

总结

  • 对于队列来说数据结构相比栈复杂一些,但是也不是很难,搞懂先进先出然后就用数组或者链表实现即可。
  • 对于数组,队尾tail指向的位置是空的,而链表的front(head一样)为头指针为空的,所以在不同结构实现相同效果的方法需要注意一下。
  • For two-way queue, you can inform themselves about, two-way queue can be inserted on both sides of deletion, can be achieved 堆栈公用and other results are more flexible call. (Refer to the java ArrayDeque). And now the middleware message queues, and many are based on queuing model extension application. So learn to queue very important!
  • Finally, the author is limited, if there is 纰漏和不足之处please also indicate . In addition, if you feel good you can point a praise, attention to individual public numbers : bigsaiMore often share with you, concerned about the reply data structure to obtain 精心data structures and algorithms of multiple copies of data preparation!
    Here Insert Picture Description
He published 185 original articles · won praise 1706 · Views 510,000 +

Guess you like

Origin blog.csdn.net/qq_40693171/article/details/99617776