Data structure stack and queue summary

Posted by kat89 on Sun, 21 Jun 2020 09:32:40 +0200

Article catalog

Stack vs. queue

1. Stack

What is a stack? When we played with toy guns as children, we knew that the stack was like a gun's magazine. Every time a bullet was loaded, the bullet would go down to the bottom of the magazine. But when you hit the bullet, you found that it was from the last bullet you put into the magazine that you started shooting in turn. There are also web page back, word, ps "undo" operations are implemented using the stack.

  • Definition of stack

A stack is a linear table that can only be inserted and deleted at the end of a table. It has the characteristics of "first in, second out".

  • features

One end that can be inserted or deleted is called top, and the other end is called bottom. Insert call stack or push stack, delete call stack.

2. Queue

What is a queue? In life, it's similar to a station queuing for ticket checking. After checking the tickets, they leave, and others line up in turn. Another example is input of letters or numbers by keyboard and output in notepad of display.

  • Characteristics of the queue

Only insert operation is allowed at the end of the team, and delete operation is allowed at the head of the team. It has the characteristics of first in, first out. Insert call in, delete call out.

3. Stack and queue

  • Similarities

1. They are all linear structures with one-to-one logical relationship
2. The insertion is done at the end of the table
3. Same time and space cost

  • difference

Compare their characteristics
Add: the sequential stack can realize multi stack space sharing, but the sequential queue is different.

Storage structure of stack and queue

Storage structure of stack

1. Sequential storage structure of stack

The sequential storage structure of stack is realized by array, where top points to the next storage location of the element storage location at the top of stack.

  • Empty operation
	public boolean isElempty() {
		return top == 0;		
		//top can be defined in two ways:
		//1, Set the next storage location that points to the storage location of the top element of the stack. That is to say, when top points to array position 0, there is no data element. When data element is inserted, top will point to the next storage position of the stack top element, and the stack is not empty at this time.
		//2. It can also be defined that the stack is empty when top == -1
	}
  • Return to top of stack element operation
    Note: top points to the next position of the top stack element, so the position when returning the top stack element is: top-1 position.
	//Return to the top element of the stack: first, judge whether the stack is empty
	public Object peek() {
		if(!isElempty()) {
			return stackElem[top-1];
		}else {
			return null;
		}
		
	}
  • Push operation
    Stack operation: the stack is operated at the top end of the stack. The stack enters one data element at a time, top+1.
    For example:

    Code implementation:
	public void push(Object x) throws Exception {
		if(top == stackElem.length) {		//stackElem.length Define the length of the storage stack for
			throw new Exception("Stack full");
		}else {
			stackElem[top++] = x;	//x stack top plus 1
			
			//Equivalent to stackElem[top] = x; top = top+1;
		}
	}
  • Stack out operation
    Stack out operation: stack out is also operated at one end of the stack top element. Whenever a stack top element is out of the stack, top will first - 1.

    Code implementation:
	//Output stack top element
	public Object pop() {
		if(isElempty()) {
			return null;
		}else {
			return stackElem[--top];	//Top points to the next position of the stack top element, so - 1 is required for top, and only the stack top element is returned
		}
	}

2. Chain storage structure of stack

The top of the stack is placed at the head of the single chain table. You do not need to define the head node like a single chain table. The top of the stack pointer is the head pointer.


Note: Top refers to the top node of the stack. Insertion and deletion are carried out in the header (top of the stack).

  • Define a Node node class first
package stack;
/**
 * Create description of node class
 * @author Lazy little black
 *
 */
public class Node {
	//Define data, next node reference (pointer)
	public Object date;
	public Node next;
	
	//Define construction methods with and without parameters
	public Node() {
		 this.date = null;
		 this.next = null;
	}
	public Node(Object date) {
		this.date = date;
		this.next = null;
	}
	public Node(Object date,Node next) {
		this.date = date;
		this.next = next;
	}
	
}

  • Judge stack empty and empty operations
public class LinkStack implements IStack{
	public Node top;
	
	public void clear() {
		top = null;
	}
	public boolean isElempty() {
		return top == null;		//Equivalent to: return top==null?true:false;
	}
  • Return stack length operation
    Just like single chain table, each node can be traversed.
	//length
	public int length() {
		Node p = top;
		int length = 0; 
		while(p!=null) {
			p = p.next;		//Pointer backward
			++length;		//Length + 1
		}
		return length;
	}
  • Top of stack element
	//Top of stack element
	public Object peek() {
		if(isElempty()) {
			return null;
		}else {
			return top.date;
		}
	}
  • Push operation

    Note: define the new node P, assign the top of stack pointer (top) to the direct successor (p.next) of the new node, and then assign the new node p to the top of stack pointer.

    Code implementation:

	//Stack pressing
	public void push(Object x) {
		Node p = new Node(x);
		p.next = top;
		top = p;
		
	}
  • Stack out operation

    Note: a p node is used to store the stack node, and then the top pointer of the stack points to the next node.

Code implementation:

	//Out of the stack
	public Object pop() {
		if(isElempty()) {
			return null;
		}else {
			Node p = top;		//Node p stores the nodes out of the stack
			top = top.next;		//Pointer backward
			return p.date;
		}
		
	}

Note:
The time complexity of sequence stack and chain stack is O (1).

Storage structure of queue

1. Sequential storage structure of queues

The sequential storage structure of queues is the same as that of linear tables. However, in the linear table sequential storage structure, if you want to delete the elements (that is, queue out), then the elements behind the queue will move forward, and the time complexity is O (n), which limits the condition that the queue must be stored in the first n cells of the array. Without this restriction, will the performance be greatly improved? So queues are stored in this way.

  • Sequential storage of queues

Two pointers are referenced. The front pointer points to the team head element and the rear pointer points to the next position of the team tail element.

  • "False overflow" problem

    As assumed above, the total number of this queue is no more than 5. However, in Figure d, if the queue is entered next, the end of the array element queue has been a5 In fact, we find that the subscripts 0 and 1 in the queue are still idle, but they cannot be queued. We call this overflow phenomenon "false overflow".

    If in a bus, you find that the seats in the back are full, and there are seats in the front, would you choose not to go and get off to wait for the next bus? It's not just a waste. I want to hammer you with a hammer! Therefore, in order to solve the problem of "false overflow", the best way is to regard the storage space used by the sequential queue as a logically end-to-end circular queue.

2. Loop queue

  • Judgment of team full and team empty

So the real at this time should point to array 0.

At this time, a6 and a7 are joining the team:

It is found that:
When the queue is empty,

front == rear;

When the team is full

front == rear;

How to judge?
There are many ways to solve this problem:
Method 1:

Set an identification variable flag:
Queue empty: when front == rear and flag = 0;
Queue full: when front == rear and flag = 1;

Method 2:

When the queue is empty: front = = rear;
When the queue is full: when the queue is full, the array reserves a space unit.
So when the team is full, there are two situations: front and rear may be one full circle or one position apart. If the maximum size of the defined queue is QueueSize,
The queue full condition is: (rear+1)% QueueSize == front

  • queue length

    The general formula for calculating queue length is:
    (rear - front + QueueSize)% QueueSize

    We can list all four kinds of situations when front > rear and front < rear (respectively, queue full and queue not full). Then we can analyze the queue length when front > rear and queue length when front < rear respectively, and get the queue length formula.

  • Read team head element operation

	//Read team leader element
	public Object peek() {
		if(front == rear) {				//Queue is empty
			return null;
		}else {
			return queueElem[front];
		}
	}
  • Entry operation

    Note: the rear always points to the next storage location for the tail element.

	public void offer(Object x) throws Exception {
		if((rear + 1)%queueElem.length == front	) {			//Team full
			throw new Exception("The team is full");
		}else {
			queueElem[rear] = x;							//Join the team
			rear = (rear +1)%queueElem.length;				//Modify end of queue pointer
		}
	}
  • Out of line operation

    Note: first take out the value of the team head element, and then cycle the front + 1.

	//Out of the team
	public Object poll() {
		if(front == rear) {									//Team space
			return null;
		}else {
			Object t = queueElem[front];
			front = (front + 1)%queueElem.length;			//front value cycle plus 1
			return t;
		}
	}

Time complexity analysis:
The algorithm time complexity of both entry and exit operations is O (1).

3. Chain storage of queues

The chained storage structure of queues is implemented by a single chained table without leading nodes.

front:: points to the team head element node
rear: point to the end of team element node

  • Node class
    Same as above, but here I encapsulate the properties and add get and set methods for later use.!

  • Empty judgment and empty operation

public class LinkQueue implements IQueue {
	private Node front;
	private Node rear;
	
	public LinkQueue() {
		front = rear = null;
	}
	public void clear() {
		front = rear = null;
	}
	public boolean isEmpty() {
		return front == null;
	}
  • Calculation length operation

    By traversing each node.

	public int length() {
		Node p = front;
		int length = 0;
		while(p != null) {
			p = p.getNext();	//Pointer down
			++length;
		}
		return length;
	}
  • Team leader element
	//Team leader element
	public Object peek() {
		if(front!=null) {
			return front.getDate();
		}else {
			return null;
		}
	}
  • Entry operation
    The basic idea is similar to the single chain table without leading nodes, except that the chain queue restricts the insertion at the end of the table.

    Code implementation:
	//Join the team
	public void offer(Object x) {
		Node p = new Node(x);			//Initialize new node
		if(front != null) {				//Queue is not empty
			rear.setNext(p);			//Assign the p node to the next field where the rear points to the node
			rear = p;					//Change the tail position and assign p to rear
		}else {
			front = rear = p;
		}
	}
  • Out of line operation
	//Out of the team
	public Object poll() {
		if(front != null) {
			Node p = front;				//p store the first node out of the queue
			front = front.getNext();	//Point the front to the next node
			return p.getDate();			//Return p-node data field
		}else {
			return null;
		}
	}

Reference books: datastructure of Dahua, data structure java language description (2nd Edition) - Tsinghua University Press

Topics: Java