1, Experimental purpose
1. Master the basic concept, operation and usage of queue.
2. Master the type definition and implementation method of circular queue.
3. Master the basic operations of circular queue: initialization, queue entry, queue exit, team empty judgment, and obtaining team head elements.
4. Master the implementation and simple application of circular queue.
5. Be able to clearly understand the reuse idea of space in circular queue.
2, Experimental content
1. Design and implement a queue data structure, and adopt the circular queue implementation method.
2. Realize various operations of circular queue, including initialization, entry and exit, emptying and release of circular queue.
3. Based on the realized circular queue, realize the simple application of circular queue: design and implement an improved Caesar encryption algorithm, and realize the encryption and decryption operations.
3, Experimental steps
- Establish the project of this experiment.
- Add a file CircularQueue.h to store the implementation of circular queue. In addition, add a file main.cpp to realize the application of this experiment, and reference the above files.
- The data structure of circular queue is designed, and the operation of circular queue is realized.
- Using cyclic queue, an improved Caesar encryption method is designed and implemented.
- The algorithm is implemented in the main function, and the input and output of the algorithm are realized to verify the correctness of the algorithm.
- Enter various keys and strings for testing.
- Sort out and submit the experimental report, and pay attention to the copy or screenshot of the code.
4, Experimental code
1, Definition of queue
#pragma once #define MAXSIZE 10 #define TypeElem char typedef struct CircularQueue { TypeElem * data; int head, tail; }CircularQueue; bool InitQueue(CircularQueue& q) { q.data = new TypeElem[MAXSIZE];//Open up space if (!q.data) return false; q.head = q.tail = 0; return false; } bool QueueEmpty(CircularQueue q) { return q.head == q.tail; } bool QueueFull(CircularQueue q) { return (q.tail + 1) % MAXSIZE == q.head; } bool InsertQueue(CircularQueue& q, TypeElem e) { if (QueueFull(q)) return false; //Take circular queue q.data[q.tail++] = e; q.tail %= MAXSIZE; return true; } bool DelQueue(CircularQueue& q,TypeElem &e) { //Dequeue and return the header element if (QueueEmpty(q)) return false; e = q.data[q.head++]; q.head %= MAXSIZE; return true; } bool GetFront(CircularQueue q, TypeElem& e) { if (QueueEmpty(q)) return false; e = q.data[q.head];//Assign header to element e return true; } void ClearQueue(CircularQueue& q) { q.head = q.tail = 0; } void DestortQueue(CircularQueue& q) { //Free up space delete[] q.data; q.head = q.tail = 0; }
2, Initialization and implementation of algorithm
#include<iostream> #include<string> #include"CircularQueue.h" using namespace std; int main() { //Improved modkaiser encryption method CircularQueue q; InitQueue(q);//initialization string s1, s2, s3, s4;//Store the key, plaintext, ciphertext and decrypted plaintext respectively cout << "Please enter the key:"; cin >> s1; getchar();//Eat a carriage return buffer //Unified to uppercase for (int i = 0; i < s1.length(); ++i) if (s1[i] >= 'a' && s1[i] <= 'z') s1[i] = s1[i] - 'a' + 'A'; cout << "Please enter a message to encrypt:"; getline(cin,s2);//Read a whole line until you read carriage return for (int i = 0; i < s2.length(); ++i) if (s2[i] >= 'a' && s2[i] <= 'z') s2[i] = s2[i] - 'a' + 'A'; for (int i = 0; i < s1.length(); ++i) InsertQueue(q, s1[i]);//Insert queue element s3.resize(s2.length()); //encryption for (int i = 0; i < s2.length(); ++i) { if (s2[i] > 'Z' || s2[i] < 'A') { s3[i] = s2[i]; continue;//If it is not an uppercase letter, it is assigned directly } char c; DelQueue(q, c);//Delete the header and take out the assignment to c s3[i] = s2[i] + c - 'A'; if (c > 'Z') s3[i] -= 26;//Prevent too small InsertQueue(q, c);//Enter the cycle again if (i == s2.length() - 1) s3[s2.length()] = '\0';//Finally, the end element flag is given } //decrypt s4.resize(s3.length()); ClearQueue(q);//Clear re-enter for (int i = 0; i < s1.length(); ++i) InsertQueue(q, s1[i]);//Insert queue element for (int i = 0; i < s3.length(); ++i) { if (s3[i] > 'Z' || s3[i] < 'A') { s4[i] = s3[i]; continue;//Direct assignment of other characters } char c; DelQueue(q, c);//Delete the header and take out the assignment to c s4[i] = s3[i] - (c - 'A'); if (s4[i] < 'A') s4 += 26;//Prevent too small InsertQueue(q, c);//Cycle again } cout << "Plaintext:" << s2 << endl; cout << "Ciphertext:" << s3 << endl; cout << "decrypt:" << s4 << endl; return 0; }
5, Summary
1. Queue is a linear table with operation constraints. Its function is: it can only be inserted at one end and deleted at the other end. It is characterized by first in first out, last in and then out.
2. Our most common queues are: sequential queue, cyclic queue, chain queue and two-way queue; In this experiment, a circular queue is used, and an empty element is used to cycle.
3. If chain queue is adopted, it can be defined as follows
struct Queue { TypeElem data; Queue* next; };
4. If the sequence is adopted, the queue can be defined as follows
struct Queue { TypeElem data; int head, tail; };