Thanks Elad
Here is my final product. It uses head node insertion and deletion. The circle will hold 6 nodes.. New nodes can be added by deleting nodes at the tail. After the 6th node has been entered, the user is then prompted with the option to spin the wheel forward/backward, which is accomplished simply by re-assigning the head_ptr and tail_ptr. My goal for this program was mainly just to demonstrate the circularly double-linked list data structure. I would like critique from experienced programmers.
Code:
#include<iostream>
#include<cctype>
#include<string>
#include<iomanip>
#include<conio.h>
using namespace std;
template<class T>
struct node
{
T name;
node *next;
node *prev;
};
template<class T>
class Linkedlist
{
public:
Linkedlist();
void display_menu();
void display_graph();
T get_name(int);
void push_node();
void pop_node();
void spin_right();
void spin_left();
void exit_message();
~Linkedlist();
private:
int node_counter;
node<T> *head_ptr;
node<T> *tail_ptr;
};
int main()
{
Linkedlist<string> link;
char option;
do
{
clrscr();
link.display_menu();
link.display_graph();
option = toupper(getch());
switch(option)
{
case 'A': link.push_node();
break;
case 'R': link.pop_node();
break;
case 'B': link.spin_right();
break;
case 'F': link.spin_left();
break;
case 'E': link.exit_message();
break;
}
}while (option != 'E');
return 0;
}
////////////////////////
//Function Definitions//
////////////////////////
//i would like to use something like this to initialize my struct
//node::node : name(test) : next(NULL), prev(NULL) { }
template<class T>
Linkedlist<T>::Linkedlist()
{
node_counter = 0;
head_ptr = NULL;
tail_ptr = NULL;
}
template<class T>
void Linkedlist<T>::display_menu()
{
cout << "\n\n\t\t*************************************"
<< "\n\t\t* MENU *"
<< "\n\t\t*************************************"
<< "\n\t\t* Press 'A' to Add a name *"
<< "\n\t\t* Press 'R' to Remove from the list *"
<< "\n\t\t* Press 'E' to Exit *"
<< "\n\t\t*************************************";
if (node_counter < 6)
cout << "\n\t\t* There are currently " << node_counter << " nodes *";
else
cout << "\n\t\t* <- 'B' SPIN THE WHEEL! 'F' -> *";
cout << "\n\t\t*************************************"
<< endl << endl << endl << endl << endl << endl;
}
template<class T>
void Linkedlist<T>::display_graph()
{
cout << setw(36) << get_name(1) << endl << endl << endl << endl;
cout << setw(21) << get_name(6) << setw(30) << get_name(2) << endl << endl << endl << endl;
cout << endl;
cout << setw(21) << get_name(5) << setw(30) << get_name(3) << endl << endl << endl << endl;
cout << setw(36) << get_name(4) << endl << endl << endl;
}
template<class T>
T Linkedlist<T>::get_name(int iter)
{
if (iter > node_counter || head_ptr == NULL)
return "";
else
{
--iter;
node<T> *cursor = head_ptr;
for (int counter = 0; counter < iter; counter++)
cursor = cursor->next;
return cursor->name;
}
}
template<class T>
void Linkedlist<T>::push_node()
{
try
{
++node_counter;
node<T> *new_node;
new_node = new node<T>;
T entry;
cout << "\n\n\tEnter Name: ";
getline(cin,entry);
new_node->name = entry;
if (head_ptr != NULL) //This block will be the most frequent occurrance
{ //Perform the double-link.. the old head node will
head_ptr->prev = new_node; //point to the new temp node.. and the new temp
new_node->next = head_ptr; //node will point to the old head node.
new_node->prev = NULL;
}
else //(head_ptr == NULL) //This block is for the first node to be added to the
{ //linked list. This is a "special case" that will
new_node->next = NULL; //facilitate the "empty list". When adding the first
tail_ptr = new_node; //node to the list, *next should be set to NULL.. also assign
} //this node as the tail.
if (node_counter > 5) //This block is designed to perform the circular closure
{ //linking the 6th node to the head node
tail_ptr->next = new_node;
new_node->prev = tail_ptr;
}
if (node_counter > 6) //This block will delete any added extra nodes
{
node<T> *new_tail;
new_tail = tail_ptr->prev; //create a new tail (so we can delete the old one)
delete tail_ptr; //delete the extra 7th node
new_tail->next = new_node; //perform the circular closure by having the last node
//point to the new temporary head node
new_node->prev = new_tail; //and also have the new temp head node point to the tail
tail_ptr = new_tail; //tail_ptr now points to the 6th node
--node_counter; //node_counter max = 6
}
head_ptr = new_node; //after all is done, assign the new temp node
//as the head node.
}
catch (bad_alloc)
{
cout << "\t\aNo more usable memory, no new nodes can be added. ";
}
catch(...)
{
cout << "\t\aUnhandled Thrown Exception. ";
}
}
template<class T>
void Linkedlist<T>::pop_node()
{
if (head_ptr == NULL)
cout << "\t\t\t\aNo more nodes..!! ";
else
{
if (head_ptr->next != NULL)
{
node<T> *new_head;
new_head = head_ptr->next;
delete head_ptr;
head_ptr = new_head;
tail_ptr->next = NULL; //Break the Circle
head_ptr->prev = NULL; //
}
else
{
delete head_ptr;
head_ptr = NULL;
tail_ptr = NULL;
}
--node_counter;
if (node_counter < 0)
node_counter = 0; //node_counter min = 0
}
}
template<class T>
void Linkedlist<T>::spin_right()
{
if (node_counter > 5)
{
head_ptr = head_ptr->next;
tail_ptr = tail_ptr->next;
}
}
template<class T>
void Linkedlist<T>::spin_left()
{
if (node_counter > 5)
{
head_ptr = head_ptr->prev;
tail_ptr = tail_ptr->prev;
}
}
template<class T>
void Linkedlist<T>::exit_message()
{
clrscr();
cout << "\nProgram written in c++ by David Weirich"
<< "\[email protected]\n\n\n";
}
template<class T>
Linkedlist<T>::~Linkedlist()
{
while (node_counter)
pop_node();
}