Skip to content

Instantly share code, notes, and snippets.

@Ming-Tang
Created September 26, 2014 06:34
Show Gist options
  • Save Ming-Tang/0cdd280d9b5d5b28de03 to your computer and use it in GitHub Desktop.
Save Ming-Tang/0cdd280d9b5d5b28de03 to your computer and use it in GitHub Desktop.
Circular array queue demonstration
#include <iostream>
#include <iomanip>
using namespace std;
/*-
*
* 0 1 2 3 4 5
* a b c d
* ^ ^
* first last
*/
template<typename T>
class circ_queue {
private:
int size;
T* array;
int first, last;
int count;
// Create a new array of specified size, put the queue's contents
// into the new array.
void resize(int newSize) {
if (count > newSize) throw "size too small";
delete[] array;
T* newArray = new T[newSize];
// fill new array
int startIndex = 0;
for (int i = 0; i < count; i ++) {
newArray[(startIndex + i) % newSize] = array[(first + i) % size];
}
// update variables
last = (startIndex + count) % newSize;
first = startIndex;
size = newSize;
array = newArray;
}
public:
circ_queue(int sz) :
size(sz), array(new T[size]), first(0), last(0), count(0) { }
~circ_queue() { delete[] array; }
void enqueue(T val) {
// if queue is full, double array size
if (count == size) {
resize(size * 2);
}
// put new item to last
count ++;
array[last] = val;
last = (last + 1) % size;
}
T dequeue() {
if (count == 0) throw "queue is empty";
// move first forward
count --;
T val = array[first];
first = (first + 1) % size;
// shrink if count is less than 1/3 of total size
// (prevents shrinking immediately after expanding)
if (size > 10 && count * 3 < size)
resize(size / 2);
return val;
}
bool is_empty() { return count == 0; }
bool is_full() { return count == size; }
int get_size() { return size; }
int get_count() { return count; }
// Print out the contents and variables of this queue
void print_info() {
const int WIDTH = 8;
// array contents
cout << endl << "array:" << endl;
cout << setw(WIDTH + 2) << "index |";
for (int i = 0; i < size; i ++) {
cout << setw(WIDTH) << i;
}
cout << endl;
cout << setw(WIDTH + 2) << "value |";
for (int i = 0; i < size; i ++) {
cout << setw(WIDTH) << array[i];
}
cout << endl;
// first and last positions
cout << setw(WIDTH + 2) << " |";
for (int i = 0; i < size; i ++) {
const char* lbl = (i == first ? "first^" : (i == last ? "last^" : " "));
cout << setw(WIDTH) << lbl;
}
cout << endl;
if (first == last) {
cout << setw(WIDTH + 2) << " |";
for (int i = 0; i < size; i ++) {
cout << setw(WIDTH) << (i == last ? "last^" : " ");
}
cout << endl;
}
// contents
cout << endl << "contents: ";
for (int i = 0; i < count; i ++) {
cout << " " << array[(first + i) % size] << " ";
}
cout << endl;
// variables
cout << "size: " << size << endl;
cout << "count: " << count << endl;
cout << endl;
}
};
int main(int argc, char** argv) {
circ_queue<int>* q = new circ_queue<int>(4);
cout << "Enter a number to enqueue." << endl;
cout << "Enter 'd' to dequeue." << endl;
cout << "Enter 'x' to exit." << endl;
// interactive
while (true) {
try {
q->print_info();
cout << "> ";
string line;
getline(cin, line);
if (line.length() == 0) continue;
char act = line[0];
if (act == 'x') {
// exit
return 0;
} else if (act == 'd') {
// dequeue
short c = q->dequeue();
cout << "Got: " << c << endl;
} else {
try {
// enqueue
q->enqueue(stoi(line));
} catch (invalid_argument) {
cerr << "Not a number." << endl;
} catch (out_of_range) {
cerr << "Number out of range." << endl;
}
}
} catch (const char* msg) {
cerr << "Error: " << msg << endl;
}
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment