So I have a piece of code, where I have to add a node to a BST. My struct is the following:
typedef struct _CC_TREE {
// Members
int Value;
struct _CC_TREE* LChild;
struct _CC_TREE* RChild;
} CC_TREE;
The insert function in the header file looks like this:
int TreeInsert(CC_TREE *Tree, int Value);
where I have to return the status of the insert.
I tried doing it with another function and add it to the Tree
CC_TREE* InsertNewNode(CC_TREE* Tree, int Value)
{
if (NULL == Tree)
{
Tree = (CC_TREE*)malloc(sizeof(CC_TREE));
Tree->LChild = NULL;
Tree->RChild = NULL;
Tree->Value = Value;
return Tree;
}
if (Value <= Tree->Value)
{
Tree->LChild = InsertNewNode(Tree->LChild, Value);
}
else if (Value >= Tree->Value)
{
Tree->RChild = InsertNewNode(Tree->RChild, Value);
}
return Tree;
}
int TreeInsert(CC_TREE *Tree, int Value)
{
CC_UNREFERENCED_PARAMETER(Tree);
CC_UNREFERENCED_PARAMETER(Value);
Tree = InsertNewNode(Tree, Value);
return 0;
}
I try and construct the tree in my main function:
int retVal = -1;
CC_TREE* usedTree = NULL;
retVal = TreeCreate(&usedTree);
if (0 != retVal)
{
printf("TreeCreate failed!\n");
goto cleanup;
}
retVal = TreeInsert(usedTree, 20);
if (0 != retVal)
{
printf("TreeInsert failed!\n");
}
but for some reason the usedTree remains null. I know that I should use CC_TREE** Tree in the insert function, but I am not allowed to.
The insert function in the header file looks like this:
int TreeInsert(CC_TREE *Tree, int Value);
If you cannot change the function signature or (ew!) use a global variable to return the root pointer to the caller, then your best alternative is probably to use a dummy tree root. That would look something like this:
int TreeInsert(CC_TREE *Tree, int Value) {
// Tree points to a dummy root node containing no data.
// Tree->LChild is the actual root pointer
CC_TREE *root = Tree->LChild;
int status = 0;
// ... perform insertion, possibly resulting in a different value for the
// root pointer ...
Tree->LChild = root;
return status;
}
That assumes that the first argument to TreeInsert() is always a valid pointer to a CC_TREE. If you do this, then all other tree functions should work analogously.
You would use that from main() like so:
int retVal;
CC_TREE dummy_tree_root = { 0 };
retVal = TreeInsert(&dummy_tree_root, 42);
Note that this approach in effect uses a double pointer via an indirect route (no pun intended). A CC_TREE * is not itself a double pointer, but there are still two levels of indirection between that pointer and either the left or the right child of the node to which it points.
Note also that a cleaner way of doing this would involve providing a wrapper structure representing the overall tree instead of using a bare tree node or tree node pointer for the purpose. The data structures would be something like this:
struct node {
int value;
struct node *left;
struct node *right;
};
struct tree {
struct node *root;
// optionally other data, such as size, height, etc.
};
I am making Binary Tree is C. I know how to make Binary trees, that's not the issue over here.
I was using void pointers for root and all the elements that will be added to the tree.
When the binary tree is empty(root is pointing to NULL) I was simply making the root point towards the element that will be becoming the first element of the tree. But root wasn't getting the address of the element it should be pointing to. It was just a simple re-assignment.
As I mentioned above, I was trying simple re-assignment for void pointers to assign a new address for the root.
But when I was assigning the individual values of the element to the root, everything seemed worked perfectly fine.
Represent all the elements for the binary tree.
struct node {
void * key;
void * value;
struct node * left;
struct node * right;
};
First approach: simple re-assignment which fails
void map_tree_put(struct node * root, struct node * ele){
if(root==NULL) {
root = ele;
}
else {
/* some other code*/
}
}
Second approach: individual value assignment works fine
void map_tree_put(struct node * root, struct node * ele){
if(root==NULL) {
root->key = ele.key;
root->value = ele.value;
root->left = NULL;
root->right = NULL;
}
else {
/* some other code*/
}
}
Test code
int main() {
struct node * r = NULL;
int key = 10;
int value = 100;
struct node ele = {&key, &value, NULL, NULL};
map_tree_put(r, &ele);
printf("%d\n", *(int*)r->key); /* I get segmentation fault over here with the first approach but work fine with the second approach */
return 0;
}
Try
void map_tree_put(struct node ** root, struct node * ele){
if((*root)==NULL) {
(*root) = ele;
}
else {
/* some other code*/
}
}
and call from main should be
map_tree_put(&r, &ele);
This is about passing by value and reference.
That's because in this code:
void map_tree_put(struct node * root, struct node * ele){
if(root==NULL) {
root = ele;
}
else {
/* some other code*/
}
}
the function receives a copy of the pointers. To make the root pointer remember the re-assignment when the function returns, you need to do it like this:
void map_tree_put(struct node **root, struct node *ele){
if (root) {
if(*root==NULL) {
*root = ele;
}
else {
/* some other code*/
}
}
}
I have done insert a node and delete a tree with a tutorial. I test it and it works fine. However I can't understand why I need to pass by reference the root in insert, but in deleteAll just the pointer. Because I think that passing just the pointer its a value reference and then every change is only seen in the function.
typedef struct node{
int element;
struct node *left;
struct node *right;
}*tTree;
void insert(tTree *myTree, int element){
if(*myTree == NULL){
myTree= (tTree)malloc(sizeof(*myTree));
myTree->element = element;
myTree->left = NULL;
myTree->right = NULL;
}
else{
int treeElement = (*myTree)->element;
if( treeElement > element){
insert(&(*myTree)->left, element);
}
else{
insert(&(*myTree)->right, element);
}
}
}
void deleteAll(tTree myTree){
if(myTree != NULL){
deleteAll(myTree->right);
deleteAll(myTree->left);
free(myTree);
}
}
int size(tTree myTree){
if (myTree != NULL){
return 1 + size(myTree->right) + size(myTree->left);
}
else
return 0;
}
int main(){
tTree root = NULL;
insert(&root,3);
insert(&root,2);
insert(&root,4);
insert(&root,1);
printf("Number of nodes: %d\n",size(root));
deleteAll(root);
root = NULL;
printf("Number of nodes: %d\n",size(root));
return 1;
}
The deletion needs only the pointer for the statements it executes. It is not passing any information back to the calling function. However, your insertion function allocates if needed, and in that case must pass back the allocated pointer to the caller.
I cannot figure out how to run this correctly, gives segmentation error. A piece of code is below. Can you look at head too , i am not sure if it is right way of initialising head to null in another file , it is run as follows :
Table tb ;
tb= initialise_table (table_size);
tb = insert(text_words,tb);
//these 3 typedef declarations are in a "some.h" file
typedef struct node * tree_ptr;
typedef char* Key_Type;
typedef struct table* Table;
struct node {
Key_Type element;
tree_ptr left;
tree_ptr right;
};
struct table {
tree_ptr head;
};
Table init_table() {
Table head = NULL;
}
Table insert(Key_Type key ,Table temp ) {
tree_ptr t = (tree_ptr)malloc(sizeof(tree_ptr));
t->element = key;
// t->left = t->right = NULL;
if (temp->head==NULL) {
temp = (Table)malloc (sizeof (Table));
temp->head = t;
printf("empty tree ");
}
else {
temp = insert(t->element,temp);
printf("inserted into ");
}
return temp;
printf("wowo!");
}
The primary issue is in the code which, you say, is used to invoke the functions:
Table tb;
tb = insert(text_words, tb);
You have an uninitialized pointer, tb, which you pass to the function. Inside the function, you have:
Table insert(Key_Type key, Table temp)
{
tree_ptr t = (tree_ptr)malloc(sizeof(*t)); // Fixed size
t->element = key;
// t->left = t->right = NULL;
if (temp->head==NULL)
{
You're therefore accessing (dereferencing) the undefined pointer, and your program is crashing.
You should, I assume, be initializing your table with table_init(), but that function is actually no help whatsoever. It defines and initializes a local variable, but doesn't return anything even though it promises to do so.
Please see Is it a good idea to typedef pointers? The short answer is 'No, it usually isn't a good idea'.
You still have problems even if you fix the calling code like this (a necessary but not sufficient step):
Table tb = NULL;
tb = insert(text_words, tb);
or maybe:
Table tb = init_table();
tb = insert(text_words, tb);
but you need a seriously upgraded version of init_table(), such as:
Table init_table(void)
{
Table root = malloc(sizeof(*head));
root->head = NULL;
return root;
}
Your code in insert() needs to ensure that it does not dereference a null pointer (instead of an indeterminate pointer).
Table insert(Key_Type key, Table root)
{
tree_ptr t = (tree_ptr)malloc(sizeof(*t)); // Fixed size
t->element = key;
t->left = t->right = NULL;
if (root == NULL)
{
root = init_table();
root->head = t;
}
else
{
…
}
return root;
}
Given the Key_Type is a char * in disguise, you may need to review how you save the keys in the tree structure; you may need to use strdup() to copy the data. It is impossible to say for sure without seeing how you are managing the strings that you pass to the insert() function. It could be OK to just save the pointer if the calling code ensures that a new pointer is passed each time. OTOH, if the same pointer is passed each time, you definitely need to copy the data, and using strdup() is a sensible way of doing that. Note that strdup() is standard on POSIX; it is not part of standard C.
Here's one major problem:
tree_ptr t = (tree_ptr) malloc(sizeof(tree_ptr));
should be:
tree_ptr t = (tree_ptr) malloc(sizeof(struct node));
Your code doesn't actually do any binary search. Indeed, it just infinitely recurses creating new nodes. Try something more like this:
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
typedef struct Node
{
char *element;
struct Node *left;
struct Node *right;
} Node;
typedef struct
{
Node *root;
size_t size;
} Tree;
void Tree_init(Tree *t);
Node *Tree_insert(Tree *t, const char *key);
void Tree_insert_r(Node *subtree, Node *n, size_t size);
void Tree_pre_order_r(Node *subtree);
void Tree_init(Tree *t)
{
t->root = NULL;
t->size = 0;
}
Node *Tree_insert(Tree *t, const char *key)
{
Node *ret = (Node*) malloc(sizeof(Node));
if (ret)
{
ret->left = ret->right = NULL;
if ((ret->element = strdup(key))) /* make a copy of key */
{
if (NULL != t->root)
Tree_insert_r(t->root, ret, t->size);
else
t->root = ret;
++t->size;
}
else
{
free(ret);
ret = NULL;
}
}
return ret;
}
void Tree_insert_r(Node *subtree, Node *n, size_t size)
{
int cmp = strcmp(n->element, subtree->element);
if (cmp < 0 || (cmp == 0 && size % 2 == 0))
{
if (NULL != subtree->left)
subtree = subtree->left;
else
{
subtree->left = n;
return;
}
}
else
{
if (NULL != subtree->right)
subtree = subtree->right;
else
{
subtree->right = n;
return;
}
}
Tree_insert_r(subtree, n, size);
}
void Tree_pre_order_r(Node *subtree)
{
if (NULL == subtree)
return;
fprintf(stdout, "'%s'\n", subtree->element);
Tree_pre_order_r(subtree->left);
Tree_pre_order_r(subtree->right);
}
int main()
{
Tree t;
Tree_init(&t);
Tree_insert(&t, "Hello");
Tree_insert(&t, "World!");
Tree_insert(&t, "etc.");
Tree_pre_order(t.root);
return 0;
}
This is just another interview question.
Can we have a linked list of different data types, i.e. each element in a linked list can have different structure or union elements? If it's possible can you please explain with an example?
Well in a linked list you don't HAVE to link like for like structs together. As long as they have the appropriate forward and/or backwards pointers you are fine. For example:
struct BaseLink
{
BaseLink* pNext;
BaseLink* pPrev;
int typeId;
};
struct StringLink
{
BaseLink baseLink;
char* pString;
};
struct IntLink
{
BaseLink baseLink;
int nInt;
};
This way you'd have a linked list that goes from BaseLink to BaseLink. The extra data is not a problem. You want to see it as a StringLink? Then cast the BaseLink to a StringLink.
Just remember that you need some form of typeid in there so you know what to cast it to when you arrive at it.
Use union to create the datatype
union u_tag{
char ch;
int d;
double dl;
};
struct node {
char type;
union u_tag u;
struct node *next;
};
Use struct node to create linked list. type decides what is the datatype of the data.
Harsha T, Bangalore
You can use a union type:
enum type_tag {INT_TYPE, DOUBLE_TYPE, STRING_TYPE, R1_TYPE, R2_TYPE, ...};
struct node {
union {
int ival;
double dval;
char *sval;
struct recordType1 r1val;
struct recordType2 r2val;
...
} data;
enum type_tag dataType;
struct node *prev;
struct node *next;
};
Another method I've explored is to use a void* for the data and attach pointers to functions that handle the type-aware stuff:
/**
* Define a key type for indexing and searching
*/
typedef ... key_t;
/**
* Define the list node type
*/
struct node {
void *data;
struct node *prev;
struct node *next;
void *(*cpy)(void *); // make a deep copy of the data
void (*del)(void *); // delete the data
char *(*dpy)(void *); // format the data for display as a string
int (*match)(void *, key_t); // match against a key value
};
/**
* Define functions for handling a specific data type
*/
void *copyARecordType(void *data)
{
struct aRecordType v = *(struct aRecordType *) data;
struct aRecordType *new = malloc(sizeof *new);
if (new)
{
// copy elements of v to new
}
return new;
}
void deleteARecordType(void *data) {...}
char *displayARecordType(void *data) {...}
int matchARecordType(void *data, key_t key) {...}
/**
* Define functions for handling a different type
*/
void *copyADifferentRecordType(void *data) {...}
void deleteADifferentRecordType(void *data) {...}
char *displayADifferentRecordType(void *data) {...}
int matchADifferentRecordType(void *data, key_t key) {...}
/**
* Function for creating new list nodes
*/
struct node *createNode(void *data, void *(*cpy)(void *), void (*del)(void *),
char *(*dpy)(void *), int (*match)(void *, key_t))
{
struct node *new = malloc(sizeof *new);
if (new)
{
new->cpy = cpy;
new->del = del;
new->dpy = dpy;
new->match = match;
new->data = new->cpy(data);
new->prev = new->next = NULL;
}
return new;
}
/**
* Function for deleting list nodes
*/
void deleteNode(struct node *p)
{
if (p)
p->del(p->data);
free(p);
}
/**
* Add new node to the list; for this example, we just add to the end
* as in a FIFO queue.
*/
void addNode(struct node *head, void *data, void *(*cpy)(void*),
void (*del)(void *), char *(*dpy)(void *), int (*match)(void*, key_t))
{
struct node *new = createNode(data, cpy, del, dpy, match);
if (!head->next)
head->next = new;
else
{
struct node *cur = head->next;
while (cur->next != NULL)
cur = cur->next;
cur->next = new;
new->prev = cur;
}
}
/**
* Examples of how all of this would be used.
*/
int main(void)
{
struct aRecordType r1 = {...};
struct aDifferentRecordType r2 = {...};
struct node list, *p;
addNode(&list, &r1, copyARecordType, deleteARecordType, displayARecordType,
matchARecordType);
addNode(&list, &r2, copyADifferentRecordType, deleteADifferentRecordType,
displayADifferentRecordType, matchADifferentRecordType);
p = list.next;
while (p)
{
printf("Data at node %p: %s\n", (void*) p, p->dpy(p->data));
p = p->next;
}
return 0;
}
Obviously, I've left out some error checking and handling code from this example, and I don't doubt there are a host of problems with it, but it should be illustrative.
You can have each node in a linked list have a void* that points to your data. It's up to you how you determine what type of data that pointer is pointing to.
If you don't want to have to specify the type of every node in the list via the union solution you can always just store the data in a char* and take type-specific function pointers as parameters to type-sensitive operations such as printing or sorting the list.
This way you don't have to worry about what node is what type and can just cast the data however you like.
/* data types */
typedef struct list_node list_node;
struct list_node {
char *data;
list_node *next;
list_node *prev;
};
typedef struct list list;
struct list {
list_node *head;
list_node *tail;
size_t size;
};
/* type sensitive functions */
int list_sort(list *l, int (*compar)(const void*, const void*));
int list_print(list *l, void (*print)(char *data));
Yes, I do this by defining the list's element's value as a void pointer void*.
In order to know the type stored in each element of the list I also have a .type field in there, so I know how to dereference what the pointer is pointing to for each element.
struct node {
struct node* next;
int type;
void* value;
};
Here's a full example of this:
//
// An exercise to play with a struct that stores anything using a void* field.
//
#include <stdio.h>
#define TRUE 1
int TYPE_INT = 0;
int TYPE_STRING = 1;
int TYPE_BOOLEAN = 2;
int TYPE_PERSON = 3;
struct node {
struct node* next;
int type;
void* value;
};
struct person {
char* name;
int age;
};
int main(int args, char **argv) {
struct person aPerson;
aPerson.name = "Angel";
aPerson.age = 35;
// Define a linked list of objects.
// We use that .type field to know what we're dealing
// with on every iteration. On .value we store our values.
struct node nodes[] = {
{ .next = &nodes[1], .type = TYPE_INT , .value=1 },
{ .next = &nodes[2], .type = TYPE_STRING , .value="anyfing, anyfing!" },
{ .next = &nodes[3], .type = TYPE_PERSON , .value=&aPerson },
{ .next = NULL , .type = TYPE_BOOLEAN, .value=TRUE }
};
// We iterate through the list
for ( struct node *currentNode = &nodes[0]; currentNode; currentNode = currentNode->next) {
int currentType = (*currentNode).type;
if (currentType == TYPE_INT) {
printf("%s: %d\n", "- INTEGER", (*currentNode).value); // just playing with syntax, same as currentNode->value
} else if (currentType == TYPE_STRING) {
printf("%s: %s\n", "- STRING", currentNode->value);
} else if (currentType == TYPE_BOOLEAN) {
printf("%s: %d\n", "- BOOLEAN (true:1, false:0)", currentNode->value);
} else if (currentType == TYPE_PERSON) {
// since we're using void*, we end up with a pointer to struct person, which we *dereference
// into a struct in the stack.
struct person currentPerson = *(struct person*) currentNode->value;
printf("%s: %s (%d)\n","- TYPE_PERSON", currentPerson.name, currentPerson.age);
}
}
return 0;
}
Expected output:
- INTEGER: 1
- STRING: anyfing, anyfing!
- TYPE_PERSON: Angel (35)
- BOOLEAN (true:1, false:0): 1
As said, you can have a node this questionwith a void*. I suggest using something to know about your type :
typedef struct
{
/* linked list stuff here */
char m_type;
void* m_data;
}
Node;
See this question.
Actually, you don't have to put the pointer first in the structure, you can put it anywhere and then find the beginning fo the struct with a containerof() macro. The linux kernel does this with its linked lists.
http://isis.poly.edu/kulesh/stuff/src/klist/
I use these macros I wrote to make general linked lists. You just create your own struct and use the macro list_link somewhere as a member of the struct. Give that macro one argument naming the struct (without the struct keyword). This implements a doubly linked list without a dummy node (e.g. last node links back around to first node). The anchor is a pointer to the first node which starts out initialized by list_init(anchor) by giving it the lvalue (a dereferenced pointer to it is an lvalue). Then you can use the other macros in the header. Read the source for comments about each available macro functions. This is implemented 100% in macros.
http://phil.ipal.org/pre-release/list-0.0.5.tar.bz2
Yes,Sure You can insert any data type values in the linked list I've designed and its very simple to do so.I have used different constructors of node and boolean variables to check that which type value is inserted and then I do operation and command according to that value in my program.
//IMPLEMENTATION OF SINGLY LINKED LISTS
#include"iostream"
#include"conio.h"
#include <typeinfo>
using namespace std;
class node //struct
{
public:
node* nextptr;
int data;
////////////////////////////////just to asure that user can insert any data type value in the linked list
string ss;
char cc;
double dd;
bool stringTrue=0;
bool intTrue = 0;
bool charTrue = 0;
bool doubleTrue = 0;
////////////////////////////////just to asure that user can insert any data type value in the linked list
node()
{
nextptr = NULL;
}
node(int d)
{
data = d;
nextptr = NULL;
intTrue = 1;
}
////////////////////////////////just to asure that user can insert any data type value in the linked list
node(string s)
{
stringTrue = 1;
ss = s;
nextptr = NULL;
}
node(char c)
{
charTrue = 1;
cc = c;
nextptr = NULL;
}
node(double d)
{
doubleTrue = 1;
dd = d;
nextptr = NULL;
}
////////////////////////////////just to asure that user can insert any data type value in the linked list
//TO Get the data
int getintData()
{
return data;
}
string getstringData()
{
return ss;
}
double getdoubleData()
{
return dd;
}
char getcharData()
{
return cc;
}
//TO Set the data
void setintData(int d)
{
data = d;
}
void setstringData(string s)
{
ss = s;
}
void setdoubleData(double d)
{
dd = d;
}
void setcharData(char c)
{
cc = c;
}
char checkWhichInput()
{
if (intTrue == 1)
{
return 'i';
}
else if (stringTrue == 1)
{
return 's';
}
else if (doubleTrue == 1)
{
return 'd';
}
else if (charTrue == 1)
{
return 'c';
}
}
//////////////////////////////Just for the sake of implementing for any data type//////////////////////////////
node* getNextptr()
{
return nextptr;
}
void setnextptr(node* nptr)
{
nextptr = nptr;
}
};
class linkedlist
{
node* headptr;
node* addnodeatspecificpoition;
public:
linkedlist()
{
headptr = NULL;
}
void insertionAtTail(node* n)
{
if (headptr == NULL)
{
headptr = n;
}
else
{
node* rptr = headptr;
while (rptr->getNextptr() != NULL)
{
rptr = rptr->getNextptr();
}
rptr->setnextptr(n);
}
}
void insertionAtHead(node *n)
{
node* tmp = n;
tmp->setnextptr(headptr);
headptr = tmp;
}
int sizeOfLinkedList()
{
int i = 1;
node* ptr = headptr;
while (ptr->getNextptr() != NULL)
{
++i;
ptr = ptr->getNextptr();
}
return i;
}
bool isListEmpty() {
if (sizeOfLinkedList() <= 1)
{
return true;
}
else
{
false;
}
}
void insertionAtAnyPoint(node* n, int position)
{
if (position > sizeOfLinkedList() || position < 1) {
cout << "\n\nInvalid insertion at index :" << position;
cout <<".There is no index " << position << " in the linked list.ERROR.\n\n";
return;
}
addnodeatspecificpoition = new node;
addnodeatspecificpoition = n;
addnodeatspecificpoition->setnextptr(NULL);
if (headptr == NULL)
{
headptr = addnodeatspecificpoition;
}
else if (position == 0)
{
addnodeatspecificpoition->setnextptr(headptr);
headptr = addnodeatspecificpoition;
}
else
{
node* current = headptr;
int i = 1;
for (i = 1; current != NULL; i++)
{
if (i == position)
{
addnodeatspecificpoition->setnextptr(current->getNextptr());
current->setnextptr(addnodeatspecificpoition);
break;
}
current = current->getNextptr();
}
}
}
friend ostream& operator<<(ostream& output,const linkedlist& L)
{
char checkWhatInput;
int i = 1;
node* ptr = L.headptr;
while (ptr->getNextptr() != NULL)
{
++i;
checkWhatInput = ptr->checkWhichInput();
/// <summary>
switch (checkWhatInput)
{
case 'i':output <<ptr->getintData()<<endl;
break;
case 's':output << ptr->getstringData()<<endl;
break;
case 'd':output << ptr->getdoubleData() << endl;
break;
case 'c':output << ptr->getcharData() << endl;
break;
default:
break;
}
/// </summary>
/// <param name="output"></param>
/// <param name="L"></param>
/// <returns></returns>
ptr = ptr->getNextptr();
}
/// <summary>
switch (checkWhatInput)
{
case 'i':output << ptr->getintData() << endl;
break;
case 's':output << ptr->getstringData() << endl;
break;
case 'd':output << ptr->getdoubleData() << endl;
break;
case 'c':output << ptr->getcharData() << endl;
break;
default:
break;
}
/// </summary>
/// <param name="output"></param>
/// <param name="L"></param>
/// <returns></returns>
if (ptr->getNextptr() == NULL)
{
output << "\nNULL (There is no pointer left)\n";
}
return output;
}
~linkedlist() {
delete addnodeatspecificpoition;
}
};
int main()
{
linkedlist L1;
//Insertion at tail
L1.insertionAtTail(new node("dsaf"));
L1.insertionAtTail(new node("sadf"));
L1.insertionAtTail(new node("sfa"));
L1.insertionAtTail(new node(12));
L1.insertionAtTail(new node(67));
L1.insertionAtTail(new node(23));
L1.insertionAtTail(new node(45.677));
L1.insertionAtTail(new node(12.43556));
//Inserting a node at head
L1.insertionAtHead(new node(1));
//Inserting a node at any given point
L1.insertionAtAnyPoint(new node(999), 3);
cout << L1;
cout << "\nThe size of linked list after insertion of elements is : " << L1.sizeOfLinkedList();
}
The output is
1
dsaf
sadf
999
sfa
12
67
23
45.677
12.4356
Thats what you can use to create a linked list without worrying of data type
Just an FYI, In C# you can use Object as your data member.
class Node
{
Node next;
Object Data;
}
User can then use something like this to find out which Object the Node stores:
if (obj.GetType() == this.GetType()) //
{
}