A good Doubly linked list functionality class with template.
Enjoy people !!
template <class T>
class node {
private:
T data;
node *prev, *next;
public:
node(T);
void setnext(node<T> *);
void setprev(node<T> *);
node<T>* getnext( );
node<T>* getprev( );
T showdata( );
};
template <class T>
node<T>::node(T in) {
data = in;
next = prev = NULL;
}
template <class T>
void node<T>::setnext(node<T> *n) { next = n; }
template <class T>
void node<T>::setprev(node<T> *p) { prev = p; }
template <class T>
node<T>* node<T>::getnext( ) { return next; }
template <class T>
node<T>* node<T>::getprev( ) { return prev; }
template <class T>
T node<T>::showdata( ) {
return data;
}
template <class L>
class lnklist {
private:
node<L> *start, *curr;
int node_count;
public:
lnklist( );
void insertnode(L);
bool gonext( );
bool goprev( );
void ins_at_front(node<L> *);
void between_post(node<L> *);
void between_pre(node<L> *);
void ins_at_end(node<L> *);
void removenode(L);
void dsplist( );
void sort( );
int numofnodes();
void writeinfile(FILE*& );
node<L>* top();
bool search(char*,node<L>*, bool);
~lnklist( );
void info(node<L> *);
};
template <class L>
int lnklist<L>::numofnodes( ){
return node_count;
}
template <class L>
void lnklist<L>::writeinfile(FILE*& f){
node<L>* temp = start;
while(temp){
strcat(temp->showdata(),"\n");
fputs(temp->showdata(),f);
temp = temp->getnext();
}
}
template <class L>
void lnklist<L>::sort(){ // quick sort
node<L>* left = start; // set left value to the start of the list
node<L>* temp = start; // maintaing a temp value to swap nodes
while(temp->getnext()) temp = temp->getnext(); // getting to end of the list
node<L>* right = temp; // set right value to the end of the list
int pivot = node_count / 2; // pivot value , exactly to the middle of the list
node<L>* pivot_n = start;
while(pivot >= 1){
pivot_n = pivot_n->getnext(); // setting pivot node as the middle node of the list
pivot--;
}
while(strcmp(left->showdata(),right->showdata()) <= 0 ){ // comparing the left node to be smaller then right node
while(strcmp(left->showdata(),pivot_n->showdata()) < 0) // reaching to the pivot value.
left = left->getnext();
while(strcmp(right->showdata(),pivot_n->showdata()) > 0)
right = right->getprev();
if(strcmp(left->showdata(),right->showdata()) <= 0){
temp = left;
left = right;
right = temp;
left = left->getnext();
right = right->getprev();
}
}
}
template <class L>
node<L>* lnklist<L>::top(){
return start;
}
template <class L>
lnklist<L>::lnklist( ) {
start = curr = NULL;
node_count = 0;
}
template <class L>
void lnklist<L>::insertnode(L in) {
bool oktogo = true;
node<L> *temp = new node<L>(in);
if(start == NULL) { // empty list (no nodes)
start = curr = temp; // temp's 'next' and 'prev' nodes set to NULL
// cout<<"At the first node:"<<in<<endl;
//cout << "inserting node in a brand new list (empty)" << endl;
} // in node constructor
else { // at least 1 node in list to which 'curr' is
// pointing to
//cout<<" Data : "<<match(in,curr->showdata())<<endl;
if(strcmp(in,curr->showdata()) < 0) {
while(oktogo && (strcmp(in,curr->showdata()) < 0)) {
oktogo = goprev();
}
}
else {
while(oktogo && (strcmp(in,curr->showdata()) > 0)) {
oktogo = gonext( );
}
}
// now check to see if the node to insert is the last, first, or
// somewhere in the middle
if( strcmp(in,curr->showdata()) < 0 ) {
if(curr == start) {
ins_at_front(temp);
//cout << "inserting node at top of the list" << endl;
}
else {
between_pre(temp);
//cout << "inserting node between pre" << endl;
}
}
else {
if(curr->getnext( ) == NULL) {
ins_at_end(temp);
//cout << "inserting node at end of the list" << endl;
}
else {
between_post(temp);
//cout << "inserting node between post" << endl;
}
}
}
// info(temp);
node_count++;
//dsplist( );
}
template <class L>
bool lnklist<L>::gonext( ) {
bool rc;
if(curr && curr->getnext( )) {
curr = curr->getnext( );
}
rc = (curr && curr->getnext( )) ? true : false;
// must first check 'curr' in the
return rc; // event of an empty list
}
template <class L>
bool lnklist<L>::goprev( ) {
bool rc;
if(curr && curr->getprev( )) {
curr = curr->getprev( );
}
rc = (curr && curr->getprev( )) ? true : false;
return rc;
}
template <class L>
void lnklist<L>::ins_at_front(node<L> *tmp) {
tmp->setnext(curr);
curr->setprev(tmp);
curr = start = tmp;
}
template <class L>
void lnklist<L>::between_pre(node<L> *tmp) {
tmp->setnext(curr);
tmp->setprev(curr->getprev( ));
curr->getprev( )->setnext(tmp);
curr->setprev(tmp);
curr = tmp;
}
template <class L>
void lnklist<L>::between_post(node<L> *tmp) {
tmp->setnext(curr->getnext( ));
tmp->setprev(curr);
curr->getnext( )->setprev(tmp);
curr->setnext(tmp);
curr = tmp;
}
template <class L>
void lnklist<L>::ins_at_end(node<L> *tmp) {
tmp->setprev(curr);
curr->setnext(tmp);
curr = tmp;
}
template <class L>
void lnklist<L>::dsplist( ) {
node<L> *temp = start;
while(temp) {
cout << "[" << temp->showdata( ) << "]"<<endl;
temp = temp->getnext( );
}
cout << "tnodes: "<< node_count << endl;
}
template <class L>
void lnklist<L>::removenode(L n) {
bool rc = true;
if(curr) { // at least 1 node in list to remove
if( strcmp( n,curr->showdata() ) < 0 )
while(rc && ( strcmp(n,curr->showdata() ) < 0 ) ) rc = goprev( );
else
while(rc && ( strcmp(n,curr->showdata() ) > 0 ) ) rc = gonext( );
if(strcmp(n,curr->showdata()) == 0) { // node to remove was found
node_count--;
node<L> *tmp = curr;
if(curr == start) { // node to remove is first node
if(curr->getnext( )) { // next node exists
curr->getnext( )->setprev(NULL);
}
start = curr = curr->getnext( );
}
else if(curr->getnext( ) == NULL) { // node to remove is last node
if(curr->getprev( )) { // previous node exists
curr->getprev( )->setnext(NULL);
}
curr = curr->getprev( );
}
else { // node to remove is between 2 nodes
curr->getprev( )->setnext(curr->getnext( ));
curr->getnext( )->setprev(curr->getprev( ));
curr = start;
}
delete tmp;
}
else {
cout << "Node: [" << n << "] not found in list!" << endl;
}
}
//dsplist( );
}
template <class L>
lnklist<L>::~lnklist( ) {
node<L> *temp;
while(start) { // proceed provided there is at least 1 node
temp = start;
//cout << "deleting node: [" << temp->showdata( ) << "]" << endl;
start = start->getnext( );
delete temp;
}
}
template <class L>
void lnklist<L>::info(node<L> *t) {
cout << "sn: [" << (void *) start << "] : [" << start->showdata( ) << "]\n";
cout << "curr: [" << (void *) curr << "] : [" << curr->showdata( ) << "]\n";
cout << "temp: [" << (void *) t << "] : [" << t->showdata( ) << "]\n";
}
template <class T>
bool lnklist<T>::search(char* data,node<T>* n,bool fnd){
//** recursive solution **
/*if(n && !fnd){
if(strcmp(n->showdata(), data) == 0) fnd = true;
search(data,n->getnext(),fnd);
}*/
node<T>* temp = n;
while(temp && !fnd){
if(strcmp(temp->showdata(), data) == 0) fnd = true;
temp = temp->getnext();
}
return fnd;
}
No comments:
Post a Comment