Pages

May 7, 2011

Linked List in C++

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