Created
September 26, 2014 06:34
-
-
Save Ming-Tang/0cdd280d9b5d5b28de03 to your computer and use it in GitHub Desktop.
Circular array queue demonstration
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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