I wanted to create a chained list, initialize it and add a new node at the beginning.
But i have this problem :
////
error: request for member ‘value’ in something not a structure or union
////
t_bool list_add_elem_at_front(t_list *front_ptr, double elem)
{
if (front_ptr == NULL)
{
front_ptr = malloc(sizeof(*front_ptr));
front_ptr->value = elem;
front_ptr->next = NULL;
}
printf("%f\n", front_ptr->value);
return (TRUE);
}
I'm sure the struct is malloc but I really don't get why it doesn't find "value" and the "*next" on the structure
int main(void)
{
int i = 2.1;
t_list list_head = NULL;
list_add_elem_at_front(&list_head, i);
}
And the header file
typedef struct s_node
{
double value;
struct s_node *next;
} t_node;
typedef t_node *t_list;
try this
t_bool list_add_elem_at_front(t_list *front_ptr, double elem)
{
if (*front_ptr == NULL)
{
*front_ptr = malloc(sizeof(**front_ptr));
(*front_ptr)->value = elem;
(*front_ptr)->next = NULL;
}
printf("%f\n", (*front_ptr)->value);
return (TRUE);
}
In:
t_bool list_add_elem_at_front(t_list *front_ptr, double elem)
You have too many pointers in the argument:
t_list *front_ptr
when you combine that with:
typedef t_node *t_list;
result in a t_node**
Rather than remove the * in the argument, I would just use t_node * everywhere
And additionally the problem is in the argument of sizeof that should be t_node
Related
i have couple of linked lists in my larger program which i now want to keep in a struct (t_holder).
typedef struct s_list
{
int val;
struct t_list *next;
} t_list;
typedef struct s_holder
{
t_list *a_starts;
// more lists...
} t_holder;
now i try to figure out how i dereference this in my program.
void try_out(t_holder *list_holder, int num)
{
//assigning something to a_starts
list_holder->a_starts->val = num;
}
int main(int argc, char *argv[])
{
t_holder *list_holder;
int num;
num = 42;
list_holder = NULL;
try_out(list_holder, num);
return (0);
}
in the function "try_out" i simlpy try to assign a value to a_starts->val but my debugger shows me ACCESS_ERROR if i declare it like this
list_holder->a_starts->val = num;
For starters this typedef declarations
typedef struct s_list
{
int val;
struct t_list *next; // <===
} t_list;
is incorrect. It seems you mean
typedef struct s_list
{
int val;
struct s_list *next; // <===
} t_list;
As for your other code then you declared a null pointer
t_holder *list_holder;
//...
list_holder = NULL;
So dereferencing the null pointer results in undefined behavior.
You need to write something like the following
t_holder list_holder = { .a_starts = NULL };
//...
try_out( &list_holder, num);
and then within the function something like
void try_out(t_holder *list_holder, int num)
{
t_list *node = malloc( sizeof( *node ) );
node->val = num;
node->next = list_holder->a_starts;
list_holder->a_starts = node;
}
Suppose I have two structures in my code like this:
typedef struct Food {
char* name;
int food_id;
int price;
int capacity;
int hall_id;
int day;
int reserved;
int profit;
Food* next;
} Food;
typedef struct Coupon {
int id;
int percentage;
int capacity;
Coupon* next;
} Coupon;
And I want to implement a linked list data structure with them. For example I have a Food* variable which points to food number 1 and then food number 2 in next points to the next food and...
The problem is when I want to write functions for the linked lists, I have to write 2 functions for every job. For example I want to have a function that gets the head of the list and a new element, then add the new element to the list. Because the types of these two linked lists are different, I can't think of a way to write only one function for both. Is there a way to do so?
For example I want to make this function work for all types:
void add_front(Coupon* head, Coupon* new_el){
while (head->next != NULL){
head = head->next;
}
head->next = new_el;
new_el->next = NULL;
}
First, you separate the domain data of each entry from the managing data.
typedef struct {
char* name;
int food_id;
int price;
int capacity;
int hall_id;
int day;
int reserved;
int profit;
} Food;
typedef struct {
int id;
int percentage;
int capacity;
} Coupon;
Then you can use a union with pointers to the domain data in the entry's structure. Each entry will be of the same size.
typedef struct Entry {
struct Entry* next;
union {
Food* food;
Coupon* coupon;
} data;
} Entry;
You could even place the domain data directly in the union, but this will waste memory if only small sized values are stored.
typedef struct Entry {
struct Entry* next;
union {
Food food;
Coupon coupon;
} data;
} Entry;
Now you are able to add new entries of different data with a generic function.
void add_front(Entry* head, Entry* new_el) {
while (head->next != NULL){
head = head->next;
}
head->next = new_el;
new_el->next = NULL;
}
A possible trick is to use the fact that it is legal to convert a pointer to a struct to a pointer to its initial member, and that it is legal to convert from any pointer type to void * and back. So provided next is the first member, a number of functions could be independant of the actual class, if they take void * parameters for any struct for which the first element is a next pointer. Of course, auxiliary function able to handle a real object should be provided...
Here is an example code showing a possible implementation of add_before, add_after, list_remove (remove is defined in stdio.h) and display and showing an example of use with Coupon objects:
#include <stdio.h>
typedef struct Food {
struct Food* next;
char* name;
int food_id;
int price;
int capacity;
int hall_id;
int day;
int reserved;
int profit;
} Food;
typedef struct Coupon {
struct Coupon* next;
int id;
int percentage;
int capacity;
} Coupon;
void* add_before(void* list, void* elem) {
*(void **)elem = list;
return elem;
}
void* add_after(void* list, void* elem) {
if (NULL == list) return elem;
void** last = list;
while (*last != NULL) {
last = *last;
}
*last = elem;
return list;
}
// eltdisplay is a pointer to a function able to display an element
void display(void* list, void (*eltdisplay)(void*, FILE *), FILE *out) {
while (NULL != list) {
eltdisplay(list, out);
if (NULL != *(void **)list) {
fprintf(out, " -> ");
}
list = *(void **)list;
}
fprintf(out, "\n");
}
void* list_remove(void* list, void* elem, int(*comp)(void* elt1, void* elt2)) {
if (list == NULL) return NULL;
void** cur = list, **old = NULL;
while (cur != NULL) {
if (0 == comp(cur, elem)) {
if (old == NULL) return *cur;
*old = *cur;
break;
}
old = cur;
cur = *cur;
}
return list;
}
int couponcomp(void* elt1, void* elt2) {
return ((Coupon*)elt1)->id != ((Coupon*)elt2)->id;
}
void coupondisplay(void* elt, FILE *out) {
Coupon* coupon = elt;
fprintf(out, "%d", coupon->id);
}
int main() {
Coupon data[3] = { {NULL, 1}, {NULL, 2}, {NULL, 3} };
Coupon* list = NULL;
for (int i = 0; i < sizeof(data) / sizeof(*data); i++) {
list = addLast(list, data+i);
}
display(list, coupondisplay, stdout);
Coupon data2 = { NULL, 2 };
list = list_remove(list, &data2, couponcomp);
display(list, coupondisplay, stdout);
return 0;
}
It compiles with no warning and displays as expected:
1 -> 2 -> 3
1 -> 3
You could use a macro :
From one of my personal project
#if !defined(CIRCULAR_DOUBLE_LINKED_LIST_H)
#define CIRCULAR_DOUBLE_LINKED_LIST_H
//T must include ->prev and ->next member
#define DECLARE_NAMED_CIRCULAR_DOUBLE_LINKED_LIST(T, name) \
static inline T* name ## _add_after(T* source, T* item) { \
T* last_next = source->next; \
source->next = item; \
item->prev = source; \
item->next = last_next; \
last_next->prev = item; \
return source; \
} \
static inline T* name ## _add_before(T* source, T* item) {\
T* last_prev = source->prev; \
source->prev = item; \
item->next = source; \
item->prev = last_prev; \
last_prev->next = item; \
return source; \
} \
static inline T* name ## _remove(T* item) { \
T* next = item->next; \
item->prev->next = item->next; \
item->next->prev = item->prev; \
return next == item ? NULL : next; \
}
#define DECLARE_CIRCULAR_DOUBLE_LINKED_LIST(T) DECLARE_NAMED_CIRCULAR_DOUBLE_LINKED_LIST(T, list_ ## T)
#endif // CIRCULAR_DOUBLE_LINKED_LIST_H
typedef struct Food {
Food* next;
Food* prev;
char* name;
int food_id;
int price;
int capacity;
int hall_id;
int day;
int reserved;
int profit;
} Food;
DECLARE_CIRCULAR_DOUBLE_LINKED_LIST(Food)
list_Food_add_after(Food*, Food*);
list_Food_add_before(Food*, Food*);
list_Food_remove(Food*);
I think the best way I ever found to do this in C (i.e., without templates) was:
Make a SinglyLinkedNode class that just has SinglyLinkedNode *next
Write your list functions based on this class -- every list is a list of SinglyLinkedNode
Add SinglyLinkedNode node fields to Food and Coupon, and use that to link them together.
Additionally provide functions or macros to get the containing Food or Coupon pointer from a SinglyLinkedNode pointer, like Coupon *couponFromNode(Node *p);
Note that I would never actually do this for singly-linked lists, because singly-linked list operations are so easy to write that you don't really need list methods. This technique starts to get useful for doubly-linked lists or more complex introspective containers.
I'm trying to create a small list for each element in a main list. I have the main list working fine but I don't know how to access and add elements to the small list.
struct smallList
{
char data;
struct smallList *next;
};
struct bigList
{
char data;
struct bigList *next;
struct smallList *head;
} *root;
When I add stuff to the main list, I declare for each new node:
newNode->head = NULL;
I use this function to get the current pointer to an element in main list:
struct bigList *pointer = getPointer(root, value);
Then, to add stuff to its smallList| using that pointer. I pass alongpointer->head` to this function. And its not working.
insert(pointer->head, value)
As WhozCraig suggests, you can resolve your problem using a pointer to a pointer. Something like this:
void insert(struct smallList **head, char value)
{
*head = newSmallList(value, *head);
}
newSmallList would be something like:
struct smallList *newSmallList(char value, struct smallList *rest)
{
struct smallList *result = malloc(sizeof(struct smallList));
result->next = rest;
result->data = value;
return result;
}
The problem with your current setup is that you are passing the value of the pointer->head field (which happens to be null) to the function, when what you want is to alter what is stored in the field. Here is a program using integers that illustrates a similar mistake:
void setFive(int i)
{
i = 5;
}
int main(void)
{
int myInt = 7;
setFive(myInt);
printf("%d\n", myInt); /* still 7! */
return 0;
}
i have a dynamic number of pointers all having the same size. i need to store all the addresses of my pointers in some place like a link List in order to fetch them later on.
my question is what structs should i use. is the following correct:
struct Node{
int *k;
Node*Next;
}
struct LS{
Node*first,*last;
void push(Node*n);
Node* GetFirst();
Node* GetLast();
}
the LS is the linked list that stores Nodes. and a Node is a struct that holds the address of my pointer and a pointer to the next Node.
am i using int *k to store the address of my pointer correctly? should i continue with this implementation or is there any easier way to do this?
this sample code may help you start...
#include <stdio.h>
struct Node{
int *k;
Node *Next;
}* Temp;
struct LS
{
Node *first,*last;
void push(Node *MyNode)
{
MyNode->Next=NULL;
if(empty())
{
first=MyNode;
last=MyNode;
}
else
{
last->Next = MyNode;
last=MyNode;
}
}
Node* front()
{
return first;
}
void pop()
{
free(first->k);
first=first->Next;
}
bool empty()
{
if(first==NULL) return true;
return false;
}
};
int N=10;
int main()
{
LS Q;Q.first=NULL;
for(int i=0;i<3;i++)
{
Node *NewNode= (Node*)malloc(sizeof(Node));
NewNode->k = (int*)malloc(sizeof(int)*N);
for(int k=0;k<N;k++) NewNode->k[k]=i;
Q.push(NewNode);
}
while(!Q.empty())
{
Temp=Q.front();
for(int i=0;i<N;i++) printf("%d ",Temp->k[i]);
printf("\n");
Q.pop();
}
return 1;
}
Yes, your Node struct is correct.
As to whether there is an easier way it depends. If there is a maximum number of pointers that you will need then an array of pointers would be easier. If you can do it in C++ then an STL vector (can use it like an array, but underneath the hood it can grow dynamically as needed) is easier. If you have to do it in C and it has to be dynamic, though, then no, there is not an easier way.
WDM.H (microsoft header) has a bunch of linked list stuff to look at ( http://msdn.microsoft.com/en-us/library/ff547799(VS.85).aspx ) , I've cut and pasted from that, and added a very simple example.
typedef struct _LIST_ENTRY {
struct _LIST_ENTRY *Flink;
struct _LIST_ENTRY *Blink;
} LIST_ENTRY, *PLIST_ENTRY;
typedef struct _MY_THING
{
LIST_ENTRY ListEntry;
ULONG randomdata1;
ULONG randomdata2;
ULONG randomdata3;
ULONG randomdata4;
} MY_THING, *PMY_THING;
#define CONTAINING_RECORD(address, type, field) ((type *)( \
(PCHAR)(address) - \
(ULONG_PTR)(&((type *)0)->field)))
VOID
InsertHeadList(
IN PLIST_ENTRY ListHead,
IN PLIST_ENTRY Entry
)
{
PLIST_ENTRY Flink;
Flink = ListHead->Flink;
Entry->Flink = Flink;
Entry->Blink = ListHead;
Flink->Blink = Entry;
ListHead->Flink = Entry;
}
VOID
InitializeListHead(
IN PLIST_ENTRY ListHead
)
{
ListHead->Flink = ListHead->Blink = ListHead;
}
PLIST_ENTRY
RemoveHeadList(
IN PLIST_ENTRY ListHead
)
{
PLIST_ENTRY Flink;
PLIST_ENTRY Entry;
Entry = ListHead->Flink;
Flink = Entry->Flink;
ListHead->Flink = Flink;
Flink->Blink = ListHead;
return Entry;
}
void main()
{
LIST_ENTRY HeadOfMyList;
MY_THING Thing;
InitializeListHead(&Head);
// example of add thing to list.
InsertHeadList(&HeadOfMyList, &Thing.ListEntry);
// example of removing thing from the list
PLIST_ENTRY listEntry = RemoveHeadList(&HeadOfMyList);
PMY_THING pThing = (PMY_THING) CONTAINING_RECORD(listEntry, MY_THING, ListEntry);
}
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()) //
{
}