Numbering Elements in a Linked List of structs - c

I am trying to write a function that takes in as an argument a linked list of structs. One of the elements of these structs is a value for storing the position, example struct #3 has 3 for the element. The list that comes in is not in order. I want to go through each element in the linked list and set the value based on the order they are in. How would I do this?
nodeT numberStructs(nodeT *temp)
{
int i;
i=0;
while(temp!=NULL)
{
temp->struct.struct_order=i;
temp=temp->next;
i++;
}
return temp;
}
This is clearly not going to cut it but it's what I got so far.
Also, to clarify, I will be adding elements, moving elements, deleting elements etc. Instead of adjusting the counts every time do something that changes the line order, I want to call a single function to straighten these out. This allows me to just change the pointers of the linked list structs whenever I want to make a change.

typedef struct NodeT {
struct Node *next;
int struct_order;
...
} NodeT;
void fill_idx(NodeT *first) {
int idx;
NodeT *node;
for (node = first, idx = 0;
node;
node = node->next, ++idx) {
node->struct_order = idx;
}
}
Equivalently, with a while loop:
void fill_idx(NodeT *first) {
int idx = 0;
NodeT *node = first;
while (node) {
node->struct_order = idx;
node = node->next;
++idx;
}
}

Related

How to iterate through a list in c

Let "List" be a struct that represents a singly-linked list, i have the following function:
int List_contains(List node, const char* key) {
List *search;
search=node.next;
assert(search->key!=NULL);
return 1;
}
and List is the following struct:
typedef struct List { /*A new node*/
char* key;
void* value;
struct List *next;
} List;
The function "List_contains" should tell me if "key" is contained in the list or not. Problem is, i can't iterate through the list, and the line
assert(search->key != NULL);
throws a Segfault. How can i iterate through the list with what i have?
(Note: The function is, obviously, not "completed".)
Here is an example of a search I wrote a while back.
struct node
{
int data;
struct node *next;
};
int
search_list(struct node *head, int search)
{
if (!head)
{
fprintf(stderr, "Invalid head\n");
return 1;
}
struct node *temp = head;
while (temp)
{
if (temp->data == search)
{
printf("Found %d\n", search);
break;
}
temp = temp->next;
}
return 0;
}
int List_contains(List node, const char* key) {
List *search;
search=node.next;
assert(search->key!=NULL);
return 1;
}
so a lot to parse here...
Generally you would pass in a pointer to the node so that it isn't copied, but it is actually safe to do what you have done, in this instance, assuming no multithreaded shenanigans go on...
but in the future I would look for:
int List_contains(List* node, const char* key) {
next line you make a pointer without a value... which is fine, because you assign it the next line, but that could be condensed...
// List *search;
// search=node.next; # could easily become:
List *search = node.next;
now at this point you actually know if you are at the end of the list...
if(search == null)
{
return 0;
}
after that you need to do some sort of compare...
if (strcmp(key,search->key) == 0)
{
//found it;
return 1;
}
now you have code that will match the key against the first element of the list, so you would need to put the whole thing in a loop, each iteration swapping search with search->next and checking for null

Creating a sublist from a linked list based on position?

I'm trying to type a function that takes 2 linked list. One has the values to be printed and the second has positions for the linked list values to be printed. It gives me an error that i put as comment in the code.
Structs
typedef int Item;
typedef struct node_struct * link;
typedef struct list_struct * list;
struct node_struct {
Item item;
link next;
};
struct list_struct {
link first;
int length;
};
Function:
list sublist(list A, list pos_list) {
link tempOne;
link tempTwo;
link node = malloc(sizeof *node);
tempOne = pos_list->first;
tempTwo = A->first;
int counter;
while(tempOne->next != NULL)
{
counter = 0;
while(counter < tempOne->item && tempOne->next != NULL)
{
tempTwo = tempTwo->next;
counter = counter+1;
}
node->item = tempTwo->item; //EXC_BAD_ACCESS code:1
node = node->next;
tempTwo = A->first;
tempOne = tempOne->next;
counter = 0;
}
return node;
There are bunch of bad practices in the code which makes understanding (and hence debugging and maintaining) such code very difficult for you and for us.
You are creating a pointer typdef when there is no intention to hide the actual data behind the pointer
You are creating a linked list of positions and a linked list of data, using the same data type. I understand in your case both are int, but then don't use the misleading typedef int Item and simply stick to using int
tempOne and tempTwo are probably the worst naming options in this case, not only for calling the variables with non-intuitive names like temp, but also calling the first arg as Two and second arg as One - as counter-intuitive as it can get
I can see cases where you use 2 different structures node_struct (which frankly I would call node) and list_struct see node_structcomment), but in this example, you don't need list_struct, it only adds more confusion to the code.
You should really do the "find" job (the inner for loop)in a separate function, so you can easily handle errors, and not confuse the inner loop with the outer loop
With that out of the way, You haven't specified if the pos_list actually contains relative positions (position from previous position) or absolute positions (like array index). I will assume it is absolute position.
after you do node = node->next; you need to malloc it again. Or rather just malloc it before using it on line node->item = tempTwo->item; and get rid of the malloc out side the loops
I don't have a c compiler handy, so couldn't test it. But I don't see any other issues
EDIT
I noticed that the return value for sublist is always just the last node, instead of the first node in the linked list - this is obviously going to be a problem too.
Below is how I would write this code. Remember, this is not a debugged and tested code, but mere expression of the idea (first draft if you will)
typedef struct Node_ Node;
struct Node_ {
int Item;
Node* Next;
};
Node* GetNodeAt(Node *dataList, int indx) {
for (int i = 0; i < indx && dataList != NULL; ++i)
dataList = dataList->Next;
return dataList;
}
Node* SubList(Node *dataList, Node *posList) {
Node* origDataList = dataList;
Node *currentRetNode = malloc(sizeof(Node));
Node *prevRetNode = NULL, *returnList = currentRetNode;
while (posList->Next != NULL) {
// Find the node in dataList
Node *node = GetNodeAt(dataList, posList->Item);
// create/manage the linked list to be returned
prevRetNode = currentRetNode;
currentRetNode->Next = malloc(sizeof(Node));
currentRetNode->Item = node->Item;
currentRetNode = currentRetNode->Next;
posList = posList->Next; // move to the next index
}
free(currentRetNode);
if (prevRetNode == NULL)
returnList = NULL;
else
prevRetNode->Next = NULL;
return returnList;
}

General function for sorting a linked list

Is there any general user defined function that can be used to sort any given linked list, given that it has a pointer field and a data field.
The function should not swap the data between the nodes. The swapping should be done by using the pointers.
I found one online, but it is using a user defined function. I'm not allowed to use any other functions, but the bubble sort one.
We were asked not to initialize any new variables, other than temp structs within the function. So, i can't use integers or variables like swapped.
The one that i was using is as follows:
/* Bubble sort the given linked lsit */
void bubbleSort(struct node *start)
{
int swapped, i;
struct node *ptr1;
struct node *lptr = NULL;
/* Checking for empty list */
if (ptr1 == NULL)
return;
do
{
swapped = 0;
ptr1 = start;
while (ptr1->next != lptr)
{
if (ptr1->data > ptr1->next->data)
{
swap(ptr1, ptr1->next);
swapped = 1;
}
ptr1 = ptr1->next;
}
lptr = ptr1;
}
while (swapped);
}
/* function to swap data of two nodes a and b*/
void swap(struct node *a, struct node *b)
{
int temp = a->data;
a->data = b->data;
b->data = temp;
}
Given that my linked list structure is as follows:
struct node
{
int data;
struct node *next;
};
For your case, you can use an edited version of the function that you have provided. The swap function was omitted in here.
//Sorting according to the data, ascending order
void bubbleSortLL(struct node *header){
struct node *temp1, *temp2, *temp3, *temp4, *temp5;
temp4=NULL;
while(temp4!=header->next)
{
temp3=temp1=header;
temp2=temp1->next;
while(temp1!=temp4)
{
if(temp1->data > temp2->data)
{
if(temp1==header)
{
temp5=temp2->next;
temp2->next=temp1;
temp1->next=temp5;
header=temp2;
temp3=temp2;
}
else
{
temp5=temp2->next;
temp2->next=temp1;
temp1->next=temp5;
temp3->next=temp2;
temp3=temp2;
}
}
else
{
temp3=temp1;
temp1=temp1->next;
}
temp2=temp1->next;
if(temp2==temp4)
temp4=temp1;
}
}
}
This will work by passing your specified list as an argument. Nevertheless, i don't understand why you can't use the swap function.
To get rid of the call of the swap function, replace the
function call with its content:
Instead of
swap(ptr1, ptr1->next);
write
int temp = ptr1->data;
ptr1->data = ptr1->next->data;
ptr1->next->data = temp;
To swap the elements and not the data, you need
to to track the previous element.
Here a suggestion for the swap of the elements(without maybe needed NULL checks)
previous->next = ptr1->next;
previous->next->next=ptr1;
Instead of ptr1=ptr1->next you need:
previous=previous->next;
ptr1=previous->next;

deleting a node in linear single linked list given the start of the list

I have the following code which deletes a given node from the linear single linked list.
I want to know if we can still improve this program and does it break anytime
struct node
{
int num;
struct node *next;
} ;
typedef struct node s;
void delete(struct node *first)
{
int flag = 0;
s *ptr, *lastNodePtr = NULL, *deleteNode;
deleteNode = (s*) malloc(sizeof(s));
printf("enter the node value to delete");
scanf_s("%d",&deleteNode->num);
deleteNode->next = NULL;
for (ptr=first;ptr!=NULL;ptr=ptr->next) //at least one element exist
{
if(deleteNode->num == ptr->num)
{
flag=1;
if(ptr==first) //need to delete at first place
{
free(ptr);
first = null; //i dont think we need to do this as it points to ptr and ptr is already null.
}
else // need to delete some where middle.it can be last as well.
{
lastNodePtr->next=ptr->next;
free(ptr);
}
printf("successfully deleted..");
break;
}
lastNodePtr=ptr; // taking note of last node visited..
}
if (flag==0)
{
printf("\n Couldn't find the node");
return;
}
}
if ptr is the first element in the list to delete, you set first to null, not to the next of ptr. (sideeffect: you are not able to free the the rest of the list)
your EDITH: delete should return the new Head, better make it a struct node **first parameter which changes the first element if the first is the deleted one
BTW: never cast the result of malloc.
BTW two. why use for-loop? everybody uses while-loop with linked lists
BTW three: normal variable names for linked lists are "head", "list", "next", "prev", "last" with the nice side-affect, they are all the same length, so making it neatly aligned.
struct node
{
struct node *next;
int num;
} ;
void delete(struct node **pp, int num) {
struct node *del;
for ( ;*pp; pp= &(*pp)->next) {
if((*pp)->num == num) break;
}
if (!*pp) { printf("Couldn't find the node(%d)\n", num); return; }
del = *pp;
*pp = del->next;
free(del);
}
BTW: there is nothing wrong with for() loops; they allow you to put all the loop logic on one line.

How to implement a linked list in C?

I am creating a linked list as in the previous question I asked. I have found that the best way to develop the linked list is to have the head and tail in another structure. My products struct will be nested inside this structure. And I should be passing the list to the function for adding and deleting. I find this concept confusing.
I have implemented the initialize, add, and clean_up. However, I am not sure that I have done that correctly.
When I add a product to the list I declare some memory using calloc. But I am thinking shouldn't I be declaring the memory for the product instead. I am really confused about this adding.
Many thanks for any suggestions,
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define PRODUCT_NAME_LEN 128
typedef struct product_data
{
int product_code;
char product_name[PRODUCT_NAME_LEN];
int product_cost;
struct product_data_t *next;
}product_data_t;
typedef struct list
{
product_data_t *head;
product_data_t *tail;
}list_t;
void add(list_t *list, int code, char name[], int cost);
void initialize(list_t *list);
void clean_up(list_t *list);
int main(void)
{
list_t *list = NULL;
initialize(list);
add(list, 10, "Dell Inspiron", 1500);
clean_up(list);
getchar();
return 0;
}
void add(list_t *list, int code, char name[], int cost)
{
// Allocate memory for the new product
list = calloc(1, sizeof(list_t));
if(!list)
{
fprintf(stderr, "Cannot allocated memory");
exit(1);
}
if(list)
{
// First item to add to the list
list->head->product_code = code;
list->head->product_cost = cost;
strncpy(list->head->product_name, name, sizeof(list->head->product_name));
// Terminate the string
list->head->product_name[127] = '/0';
}
}
// Initialize linked list
void initialize(list_t *list)
{
// Set list node to null
list = NULL;
list = NULL;
}
// Release all resources
void clean_up(list_t *list)
{
list_t *temp = NULL;
while(list)
{
temp = list->head;
list->head = list->head->next;
free(temp);
}
list = NULL;
list = NULL;
temp = NULL;
}
============================== Edited ============================
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define PRODUCT_NAME_LEN 64
// typedef struct product_data product_data_t;
typedef struct product_data
{
int product_code;
char product_name[PRODUCT_NAME_LEN];
int product_cost;
}product_data_t;
typedef struct list
{
struct list *head;
struct list *tail;
struct list *next;
struct list *current_node;
product_data_t *data;
}list_t;
void add(list_t *list, int code, char name[], int cost);
int main(void)
{
list_t *list = NULL;
list = initialize(list);
add(list, 1001, "Dell Inspiron 2.66", 1299);
add(list, 1002, "Macbook Pro 2.66", 1499);
clean_up(list);
getchar();
return 0;
}
void add(list_t *list, int code, char name[], int cost)
{
/* Allocate memory for the new product */
product_data_t *product = (product_data_t*) calloc(1, sizeof(*product));
if(!product)
{
fprintf(stderr, "Cannot allocate memory.");
exit(1);
}
/* This is the first item in the list */
product->product_code = code;
product->product_cost = cost;
strncpy(product->product_name, name, sizeof(product->product_name));
product->product_name[PRODUCT_NAME_LEN - 1] = '\0';
if(!list->head)
{
/* Assign the address of the product. */
list = (list_t*) product;
/* Set the head and tail to this product */
list->head = (list_t*) product;
list->tail = (list_t*) product;
}
else
{
/* Append to the tail of the list. */
list->tail->next = (list_t*) product;
list->tail = (list_t*) product;
}
/* Assign the address of the product to the data on the list. */
list->data = (list_t*) product;
}
If you are looking to better understand the basics of linked lists, take a look at the following document:
http://cslibrary.stanford.edu/103/LinkedListBasics.pdf
Arguably you want your list data structure to be external to the data that it stores.
Say you have:
struct Whatever
{
int x_;
}
Then your list structure would look like this:
struct Whatever_Node
{
Whatever_Node* next_
Whatever* data_
}
Ryan Oberoi commented similarly, but w/o example.
In your case the head and tail could simply point to the beginning and end of a linked-list. With a singly linked-list, only the head is really needed. At it's most basic, a linked-list can be made by using just a struct like:
typedef struct listnode
{
//some data
struct listnode *next;
}listnodeT;
listnodeT *list;
listnodeT *current_node;
list = (listnodeT*)malloc(sizeof(listnodeT));
current_node = list;
and as long as list is always pointing to the beginning of the list and the last item has next set to NULL, you're fine and can use current_node to traverse the list. But sometimes to make traversing the list easier and to store any other data about the list, a head and tail token are used, and wrapped into their own structure, like you have done. So then your add and initialize functions would be something like (minus error detection)
// Initialize linked list
void initialize(list_t *list)
{
list->head = NULL;
list->tail = NULL;
}
void add(list_t *list, int code, char name[], int cost)
{
// set up the new node
product_data_t *node = (product_data_t*)malloc(sizeof(product_data_t));
node->code = code;
node->cost = cost;
strncpy(node->product_name, name, sizeof(node->product_name));
node->next = NULL;
if(list->head == NULL){ // if this is the first node, gotta point head to it
list->head = node;
list->tail = node; // for the first node, head and tail point to the same node
}else{
tail->next = node; // append the node
tail = node; // point the tail at the end
}
}
In this case, since it's a singly linked-list, the tail is only really useful for appending items to the list. To insert an item, you'll have to traverse the list starting at the head. Where the tail really comes in handy is with a doubly-linked list, it allows you to traverse the list starting at either end. You can traverse this list like
// return a pointer to element with product code
product_data_t* seek(list_t *list, int code){
product_data_t* iter = list->head;
while(iter != NULL)
if(iter->code == code)
return iter;
iter = iter->next;
}
return NULL; // element with code doesn't exist
}
Often times, the head and tail are fully constructed nodes themselves used as a sentinel to denote the beginning and end of a list. They don't store data themselves (well rather, their data represent a sentinel token), they are just place holders for the front and back. This can make it easier to code some algorithms dealing with linked lists at the expense of having to have two extra elements. Overall, linked lists are flexible data structures with several ways to implement them.
oh yeah, and nik is right, playing with linked-lists are a great way to get good with pointers and indirection. And they are also a great way to practice recursion too! After you have gotten good with linked-list, try building a tree next and use recursion to walk the tree.
I am not writing the code here but you need to do the following:
Create and object of list, this will remain global for the length of program.
Malloc the size of product _ data _ t.
For first element (head is NULL), point head to the malloced' address.
To add next element, move to the end of list and then add the pointer of malloced address to next of last element. (The next of the last element will always be NULL, so thats how you traverse to end.)
Forget tail for a while.
If you are learning C pointer theory this is a good exercise.
Otherwise, it feels like too much indirection for code that is not generic (as in a library).
Instead of allocating a static 128 byte character string, you might want to do some more pointer practice and use an allocated exact length string that you clean up at exit.
Academically, kungfucraigs' structure looks more generic then the one you have defined.
You're calloc'ing space for your list_t struct, just pointers to list head and tail, which isn't what you want to do.
When you add to a linked list, allocate space for an actual node in the list, which is your product_data_t struct.
You're allocating the wrong chunk of memory. Instead of allocating memory for each list element, you're allocating for the list head and tail.
For simplicity, get rid of the separate structure for the head and tail. Make them global variables (the same scope they're in now) and change them to be listhead and listtail. This will make the code much more readable (you won't be needlessly going through a separate structure) and you won't make the mistake of allocating for the wrong struct.
You don't need a tail pointer unless you're going to make a doubly linked list. Its not a major element to add once you create a linked list, but not necessary either.
In memory your items are linked by pointers in the list structure
item1 -> item2
Why not make the list structure part of your item?
Then you allocate a product item, and the list structure is within it.
typedef struct product_data
{
int product_code;
char product_name[PRODUCT_NAME_LEN];
int product_cost;
struct list_t list; // contains the pointers to other product data in the list
}product_data_t;
I think u first need to Imagin back-end. Code are nothing to important. Go here and visualize back-end basic c code of all insertion.
1) Insertion at beginning Visit and scroll to get every instruction execution on back- end
And u need front and imagin Go here
Back end imagin
And All other possible insertion here.
And important thing u can use this way.
struct Node{
int data;//data field
struct Node*next;//pointer field
};
struct Node*head,*tail; // try this way
or short cut
struct Node{
int data;//data field
struct Node*next;//pointer field
}*head,*tail; //global root pointer
And << Click >> To visualize other linked list problem.
Thanks.
A demo for Singly Linked List. If you prefer, try to check Circular Linked List and Doubly Linked List.
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int val;
struct node * next;
} node_t;
// Iterating over a list
void
print_list(node_t *head)
{
node_t *current = head;
while(current != NULL)
{
printf("%d\n", current->val);
current = current->next;
}
}
// Adding an item to the end of the list
void
push_end(node_t *head, int val)
{
node_t *current = head;
while (current->next != NULL)
{
current = current->next;
}
current->next = malloc(sizeof(node_t));
current->next->val = val;
current->next->next = NULL;
}
// Adding an item to the head of the list
void
push_head(node_t **head, int val)
{
node_t *new_node = NULL;
new_node = malloc(sizeof(node_t));
new_node->val = val;
new_node->next = *head;
*head = new_node;
}
// Removing the head item of the list
int
pop_head(node_t **head)
{
int retval = -1;
node_t *next_node = NULL;
if (*head == NULL) {
return -1;
}
next_node = (*head)->next;
retval = (*head)->val;
free(*head);
*head = next_node;
return retval;
}
// Removing the last item of the list
int
pop_last(node_t *head)
{
int retval = 0;
node_t *current = NULL;
if (head->next == NULL) {
retval = head->val;
free(head);
return retval;
}
/* get to the second to last node in the list */
current = head;
while (current->next->next != NULL) {
current = current->next;
}
/* now current points to the second to last item of the list.
so let's remove current->next */
retval = current->next->val;
free(current->next);
current->next = NULL;
return retval;
}
// Removing a specific item
int
remove_by_index(node_t **head, int n)
{
int i = 0;
int retval = -1;
node_t *current = *head;
node_t *temp_node = NULL;
if (n == 0) {
return pop_head(head);
}
for (i = 0; i < n - 1; i++) {
if (current->next == NULL) {
return -1;
}
current = current->next;
}
temp_node = current->next;
retval = temp_node->val;
current->next = temp_node->next;
free(temp_node);
return retval;
}
int
main(int argc, const char *argv[])
{
int i;
node_t * testnode;
for (i = 0; i < argc; i++)
{
push_head(&testnode, atoi(argv[i]));
}
print_list(testnode);
return 0;
}
// http://www.learn-c.org/en/Linked_lists
// https://www.geeksforgeeks.org/data-structures/linked-list/
The linked list implementation inspired by the implementation used in the Linux kernel:
// for 'offsetof', see: https://stackoverflow.com/q/6433339/5447906.
#include <stddef.h>
// See: https://stackoverflow.com/q/10269685/5447906.
#define CONTAINER_OF(ptr, type, member) \
( (type *) ((char *)(ptr) - offsetof(type, member)) )
// The macro can't be used for list head.
#define LIST_DATA(ptr, type, member) \
CONTAINER_OF(ptr, type, member);
// The struct is used for both: list head and list nodes.
typedef struct list_node
{
struct list_node *prev, *next;
}
list_node;
// List heads must be initialized by this function.
// Using the function for list nodes is not required.
static inline void list_head_init(list_node *node)
{
node->prev = node->next = node;
}
// The helper function, mustn't be used directly.
static inline void list_add_helper(list_node *prev, list_node *next, list_node *nnew)
{
next->prev = nnew;
nnew->next = next;
nnew->prev = prev;
prev->next = nnew;
}
// 'node' must be a list head or a part of a list.
// 'nnew' must not be a list head or a part of a list. It may
// be uninitialized or contain any data (even garbage).
static inline void list_add_after(list_node *node, list_node *nnew)
{
list_add_helper(node, node->next, nnew);
}
// 'node' must be a list head or a part of a list.
// 'nnew' must not be a list head or a part of a list. It may
// be uninitialized or contain any data (even garbage).
static inline void list_add_before(list_node *node, list_node *nnew)
{
list_add_helper(node->prev, node, nnew);
}
// 'node' must be part of a list.
static inline list_node *list_del(list_node *node)
{
node->prev->next = node->next;
node->next->prev = node->prev;
return node->prev;
}
Example of usage:
#include <stdio.h>
// The struct must contain 'list_node' to be able to be inserted to a list
typedef struct
{
int data;
list_node node;
}
my_struct;
// Convert 'list_node *' to 'my_struct*' that contains this 'list_node'
static inline my_struct* get_my_struct(list_node *node_ptr)
{
return LIST_DATA(node_ptr, my_struct, node);
}
void print_my_list(list_node *head)
{
printf("list: {");
for (list_node *cur = head->next; cur != head; cur = cur->next)
{
my_struct *my = get_my_struct(cur);
printf(" %d", my->data);
}
printf(" }\n");
}
// Print 'cmd' and run it. Note: newline is not printed.
#define TRACE(cmd) \
(printf("%s -> ", #cmd), (cmd))
int main()
{
// The head of the list and the list itself. It doesn't contain any data.
list_node head;
list_head_init(&head);
// The list's nodes, contain 'int' data in 'data' member of 'my_struct'
my_struct el1 = {1};
my_struct el2 = {2};
my_struct el3 = {3};
print_my_list(&head); // print initial state of the list (that is an empty list)
// Run commands and print their result.
TRACE( list_add_after (&head , &el1.node) ); print_my_list(&head);
TRACE( list_add_after (&head , &el2.node) ); print_my_list(&head);
TRACE( list_add_before(&el1.node, &el3.node) ); print_my_list(&head);
TRACE( list_del (head.prev) ); print_my_list(&head);
TRACE( list_add_before(&head , &el1.node) ); print_my_list(&head);
TRACE( list_del (&el3.node) ); print_my_list(&head);
return 0;
}
The result of execution of the code above:
list: { }
list_add_after (&head , &el1.node) -> list: { 1 }
list_add_after (&head , &el2.node) -> list: { 2 1 }
list_add_before(&el1.node, &el3.node) -> list: { 2 3 1 }
list_del (head.prev) -> list: { 2 3 }
list_add_before(&head , &el1.node) -> list: { 2 3 1 }
list_del (&el3.node) -> list: { 2 1 }
http://coliru.stacked-crooked.com/a/6e852a996fb42dc2
Of course in real life you will most probably use malloc for list elements.
In C language, we need to define a Node to store an integer data and a pointer to the next value.
struct Node{
int data;
struct Node *next;
};
To add a new node, we have a function add which has data as an int parameter. At first we create a new Node n. If the program does not create n then we print an error message and return with value -1. If we create the n then we set the data of n to have the data of the parameter and the next will contain the root as it has the top of the stack. After that, we set the root to reference the new node n.
#include <stdio.h>
struct node
{
int data;
struct node* next;
};
int main()
{
//create pointer node for every new element
struct node* head = NULL;
struct node* second = NULL;
struct node* third = NULL;
//initialize every new pointer with same structure memory
head = malloc(sizeof(struct node));
second = malloc(sizeof(struct node));
third = malloc(sizeof(struct node));
head->data = 18;
head->next = second;
second->data = 20;
second->next = third;
third->data = 31;
third->next = NULL;
//print the linked list just increment by address
for (int i = 0; i < 3; ++i)
{
printf("%d\n",head->data++);
return 0;
}
}
This is a simple way to understand how does pointer work with the pointer. Here you need to just create pointer increment with new node so we can make it as an automatic.
Go STL route. Declaring linked lists should be agnostic of the data. If you really have to write it yourself, take a look at how it is implemented in STL or Boost.
You shouldn't even keep the *next pointer with your data structure. This allows you to use your product data structure in a various number of data structures - trees, arrays and queues.
Hope this info helps in your design decision.
Edit:
Since the post is tagged C, you have equivalent implementations using void* pointers that follow the basic design principle. For an example, check out:
Documentation | list.c | list.h

Resources