Generic Double Linked List

/* These are generic Functions for a Generic List
 * Note:-Only Functions not including a Menu and an Interface
 * You could use these Functions for your own Benefit*/
#include <iostream>
using namespace std;
template <class X> struct node{   //Template Structure
	X data;
	node* next;
	node* prev;
};

template <class Y> void insert_first(node<Y>** l,Y elem) 
{
	node<Y>* Q=new node<Y>();
	Q->data=elem;
	Q->prev=NULL;
	Q->next=*l;
	*l=Q;
}
template <class Y> void print_l(node<Y>* l)//Print the List
{
	while(l!=NULL)
	{
		cout<<l->data<<"   ";
		l=l->next;
	}
}
template <class type> int count(node<type>* l)//Count the List
{
	int counter=0;
	while(l!=NULL)
	{
		counter++;
		l=l->next;
	}
	return counter;
}

template <class type> void append(node<type>** l,type elem)
{
	if(*l==NULL)
		insert_first(&*l,elem);
	else
	{
		node<type>*temp=*l;
		node<type> *Q=new node<type>;
		Q->data=elem;
		while(temp->next!=NULL)
		{
			temp=temp->next;
		}
		temp->next=Q;
		Q->prev=temp;
	}
}
template <class type> 
void insert_at_pos(node<type> **l,int pos,type elem)
{
	if(pos<=0||pos>count(*l))
	{
		cout<<"Invalid Position"<<endl;
		exit(1);
	}
	node<type>* Q=new node<type>;
	node<type>* temp=*l;
	int i=2;
	if(pos==1)
	{
		insert_first(&*l,elem);
	}
	else
	{
		while(temp!=NULL)
		{
			if(pos==i)
			{
				Q->data=elem;
				Q->next=temp->next;
				Q->prev=temp;
				temp->next=Q;
			}
			i++;
			temp=temp->next;
		}
	}
}

int main(int argc, char** argv)
{
	node<int>* q=NULL;//Create Empty Pointer that Will point to the Head of the List
	insert_first(&q,2);
	insert_at_pos(&q,2,2);
	return 0;
}

If there is any critique about this code plz tell me about it to be careful in the next time i write any code .

You wrote a bunch of C-style unsafe functions instead of a good C++ class List with comfortable and safe interface. Look at the class std::list as a model. Now these templates look like a steam-engine with microcontrolled whistle...

You wrote a bunch of C-style unsafe functions instead of a good C++ class List with comfortable and safe interface. Look at the class std::list as a model.

Mr ArkM I didn't intend using classes but i was intending to try to use the (Generic Functions ) Definition not a Generic Class or something like that and in addition to that i wrote this code as an extension to the course that i am taking at college which is (Data Structures and Algorithm Analysis in C (not C++).

BTW thanx for your advice.

I see. I think it's not the best problem area to try generic functions. You are trying to declare a family of related functions implemented some generic data structure. But it's exactly a class notion. Now your efforts demonstrated a disparity of a goal and tools.

When we need generic functions? We want a generic unit of functionality - for example, generic sort array operation...

Apropos, don't use by value parameters in program cases as in following code:

... append(node<type>** l,type elem) {
... Q->data=elem;

No need in argument copying, use references:

... append(node<type>** l,const type& elem) {

Yet another remark(s): print_l function requires operator << for template argument class. Why? There are lots of data classes without such operator but now you can't use them with your functions package. Avoid such names as print_l: simply look at print_l and print_1 (different;) ) names...

Mr ArkM i'm very thankful for your interaction with me .
Could u plz explain your purpose cuz i tried it and it went to infinite loop while displaying random numbers (or maybe the addresses) and why we pass the reference of the element while u know in the structure up there
contains a variable of type X not a pointer of type X to receive the address ?.
Plz Explain your point Mr.ArkM . :$

Mr ArkM i'm very thankful for your interaction with me .
Could u plz explain your purpose cuz i tried it and it went to infinite loop while displaying random numbers (or maybe the addresses) and why we pass the reference of the element while u know in the structure up there
contains a variable of type X not a pointer of type X to receive the address ?.
Plz Explain your point Mr.ArkM . :$

Please, present your modified code (with test main, of course).

This is the modified function

template <class type> void append(node<type>** l,const type& elem)
{
	if(*l==NULL)
		insert_first(&*l,elem);
	else
	{
		node<type>*temp=*l;
		node<type> *Q=new node<type>;
		Q->data=elem;
		while(temp->next!=NULL)
		{
			temp=temp->next;
		}
		temp->next=Q;
		Q->prev=temp;
	}
}

and this is the test in main

int main(int argc, char** argv)
{
	node<int>* q=NULL;//Create Empty Pointer that Will point to the Head of the List
	insert_first(&q,2);
	append(&q,5); //Here is the test
	print_l(q);
	system("PAUSE");
	return 0;
}

Well, this code prints "Invalid position" then exit (it's a very bad solution: after exit() automatic class variables destructors are not called). You don't use modified append function. Moreover, passed by reference data argument can't raise new problems at all...

I have no time to debug your code from the beginning. Please, make a proper test plan, prepare test cases then ask help with the serious problems brief and clear description.

It's so simply to destruct your list via improper calls of these low-level functions. May this package debugging troubles help you to understand that all these low level operations must be incapsulated in the well-designed class ;)...

This article has been dead for over six months. Start a new discussion instead.