Queue (quene)The feature is"First-in-first-out", The queue limits all operations"It can only be at either end of a linear structure", More specifically: adding elements must be in a linear tableTailWhile deleting elements can only be performed in linear tables.Header.
First abstract interface iquene <t>
namespace stack and queue {public interface iquene
{///
// get the number of actual queue elements /// //
Public int count (); ///
/// determine whether the queue is empty /// ///
Public bool isempty (); ///
/// clear the queue /// Public void clear (); ///
/// enter the queue (that is, add an element to the end of the queue) /// ///
Public void enquene (T item ); ///
/// leaves the queue (that is, deletes an element from the queue header) /// ///
Public t dequene (); ///
/// obtain the first element of the queue header /// ///
Public t PEEK ();}}
The following is an array-based implementation:
Implementation idea: store all elements in an array, and set two key variables front and rear to record the element subscript of the queue "Header" and "tail, when an element is added to the column, rear adds 1. When an element leaves the queue, front + 1. Rear-front represents the total number of actual elements in the queue.
But there is"Queue full"Pay attention to the special circumstances of, such:
In this figure, the rear has already pointed to the maximum subscript value of the array after the rear team has been involved and the front point is in the middle (that is, the elements between the front are already out of the queue, it is equivalent to the memory area before the front subscript). If there is another element in the column, rear + 1 will exceed the maximum value of the array's lower mark, but it can be seen from the figure at a glance, in fact, there is still a pile of positions in front of the front that can be reused, And the queue is not really "full"-this situation is calledPseudo fullTo solve this problem, we can think of the array as the loop structure at the beginning and end, that is, the following part in the figure. At this time, we can re-point the rear to 0, so that we can reuse the idle position.
Therefore:The rear ++ operation during column input should be slightly corrected. When rear reaches the maximum value of the array subscript, set it to 0 so that it can be recycled (see the following sectionCode)
There is another problem: At the beginning, both front and rear are-1, that is, when front = rear, it indicates that the queue is empty and changed to a loop, there may be a situation where the rear encounters the front in the loop process, that is, the real "full" status, and the rear is also equal to the front, in this way, we cannot simply use rear = front to determine whether it is full or empty? In this case, the location of an element can be wasted. The queue is full when Rear + 1 = front. Although the space of an element is sacrificed, the logic is correct, it is worth it.
The complete implementation is as follows:
Using system; using system. text; namespace stack and queue {// <summary> /// cyclically ordered queue // </Summary> /// <typeparam name = "T"> </typeparam> Public class cseqqueue <t>: iqueue <t> {private int maxsize; private T [] data; private int front; private int rear; Public cseqqueue (INT size) {DATA = new T [size]; maxsize = size; front = rear =-1;} public int count () {If (Rear> front) {return rear-front;} else {return (Rear-front + maxsize) % maxsize ;}} public void clear () {front = rear =-1;} public bool isempty () {return front = rear ;} public bool isfull () {If (front! =-1) // If an element already exists {return (Rear + 1) % maxsize = front; // to distinguish it from isempty, only one point is wasted to keep the logic correct .} else {return rear = maxsize-1 ;}} public void enqueue (T item) {If (isfull () {console. writeline ("queue is full"); return;} If (Rear = maxsize-1) // If the rear is in the header, repeat it again (to solve the problem of pseudo-full) {rear = 0;} else {rear ++;} data [rear] = item;} public t dequeue () {If (isempty () {console. writeline ("Que UE is empty "); Return default (t);} If (front = maxsize-1) // if the front ends, reset 0 {front = 0 ;} else {front ++;} return data [Front];} public t PEEK () {If (isempty () {console. writeline ("queue is empty! "); Return default (t);} return data [(front + 1) % maxsize];} public override string tostring () {If (isempty ()) {return "queue is empty. ";}stringbuilder sb = new stringbuilder (); If (Rear> front) {for (INT I = front + 1; I <= rear; I ++) {sb. append (this. data [I]. tostring () + ",") ;}} else {for (INT I = front + 1; I <maxsize; I ++) {sb. append (this. data [I]. tostring () + ",") ;}for (INT I = 0; I <= rear; I ++) {sb. append (this. data [I]. tostring () + ",") ;}} return "front =" + this. front + "\ t rear =" + this. rear + "\ t count =" + this. count () + "\ t data =" + sb. tostring (). trim (',');}}}
test code snippet:
Cseqqueue <int> queue = new cseqqueue <int> (5); queue. enqueue (1); queue. enqueue (2); queue. enqueue (3); queue. enqueue (4); console. writeline (Queue); // front =-1 rear = 3 COUNT = 4 Data = 1, 2, 3, 4 queue. dequeue (); console. writeline (Queue); // front = 0 rear = 3 COUNT = 3 data = 2, 3, 4 queue. dequeue (); console. writeline (Queue); // front = 1 rear = 3 COUNT = 2 Data = 3, 4 queue. enqueue (5); console. writeline (Queue); // front = 1 rear = 4 COUNT = 3 data = 3, 4, 5 queue. enqueue (6); console. writeline (Queue); // front = 1 rear = 0 count = 4 Data = 3,4, 5, 6 queue. enqueue (7); // queue is full console. writeline (Queue); // front = 1 rear = 0 count = 4 Data = 3,4, 5, 6 queue. dequeue (); queue. enqueue (7); console. writeline (Queue); // front = 2 rear = 1 COUNT = 4 Data = 4,5, 6,7 queue. clear (); console. writeline (Queue); // queue is empty. queue. enqueue (1); queue. enqueue (2); queue. enqueue (3); queue. enqueue (4); console. writeline (Queue); // front =-1 rear = 3 COUNT = 4 Data = 1, 2, 3, 4 queue. enqueue (5); console. writeline (Queue); // front =-1 rear = 4 COUNT = 5 Data = 1, 2, 4, 5 queue. enqueue (6); // queue is full console. writeline (Queue); // front =-1 rear = 4 COUNT = 5 Data = 1, 2, 4, 5 queue. dequeue (); queue. dequeue (); queue. dequeue (); queue. dequeue (); console. writeline (Queue); // front = 3 rear = 4 COUNT = 1 DATA = 5 queue. dequeue (); console. writeline (Queue); // queue is empty. queue. enqueue (0); queue. enqueue (1); queue. enqueue (2); queue. enqueue (3); queue. enqueue (4); // queue is full console. writeline (Queue); // front = 4 rear = 3 COUNT = 4 Data = 0, 1, 2, 3 console. writeline (queue. peek (); // 0 queue. dequeue (); console. writeline (Queue); // front = 0 rear = 3 COUNT = 3 data = 1, 2, 3 queue. dequeue (); console. writeline (Queue); // front = 1 rear = 3 COUNT = 2 Data = 2, 3 queue. dequeue (); console. writeline (Queue); // front = 2 rear = 3 COUNT = 1 DATA = 3 queue. dequeue (); console. writeline (Queue); // queue is empty. queue. enqueue (9); console. writeline (Queue); // front = 3 rear = 4 COUNT = 1 DATA = 9 console. readline ();
Of course, queues can also be implemented using linked lists, which is much easier.
First define node. Cs in the linked list
Namespace stack and queue {public class node <t> {private t data; private node <t> next; Public node (t data, node <t> next) {This. data = data; this. next = next;} public node (node <t> next) {This. next = next; this. data = default (t);} public node (t data) {This. data = data; this. next = NULL;} public node () {This. data = default (t); this. next = NULL;} public t data {get {return this. data;} set {This. data = value ;}} public node <t> next {get {return next;} set {next = value ;}}}}
For convenience, we have defined a number of overloaded versions of constructor functions. Of course, these are just floating clouds. The focus is to understand the structure: data is used to store data, and next points out who is the next node.
Complete implementation of chain queue linkqueue. CS
Using system; using system. text; namespace stack and queue {public class linkqueue: iqueue {private node front; // queue header private node rear; // queue end private int num; // Number of queue elements ///// constructor // public linkqueue () {// set front and rear to null at the initial time, num sets 0 front = rear = NULL; num = 0;} public int count () {return this. num;} public void clear () {front = rear = NULL; num = 0;} public bool isempty () {return (front = rear & num = 0 );} // Enter the public void enqueue (T item) {node q = new node (item); If (Rear = NULL) // when the first element is in the column {front = rear = Q;} else {// mount the new element to the end of the chain rear. next = Q; // modify rear to point to the last element rear = Q;} // total number of elements + 1 num ++;} // team out public t dequeue () {If (isempty () {console. writeline ("queue is empty! "); Return default (t);} // node P = front, the first element of the chain to be taken; // The chain head points to the back of a front = front. next; // If the linked list is empty at this time, the rear if (front = NULL) {rear = NULL;} num --; // number-1 return p. data;} public t PEEK () {If (isempty () {console. writeline ("queue is empty! "); Return default (t);} return front. Data;} public override string tostring () {If (isempty () {console. writeline (" queue is empty! ");} Stringbuilder sb = new stringbuilder (); node = front; sb. append (node. Data. tostring (); While (node. Next! = NULL) {sb. append ("," + node. next. data. tostring (); node = node. next;} return sb. tostring (). trim (',');}}}