C - String Linked List - c

I need to take the following code, and modify it to accept strings as arguments, instead of ints. In the end, I need the program to take all command line arguments, and add them to a linked list of strings.
So if the input was six seven eight, when i printed the linked list, it would print: eight seven six.
#include <stdio.h>
#include <stdlib.h>
typedef struct iNode
{
int myInt;
struct iNode* next;
} IntNode, *IntNodePtr;
IntNodePtr insert(int i, IntNodePtr p)
{
IntNodePtr newp = malloc(sizeof(struct iNode));
newp->myInt = i;
newp->next = p;
return newp;
}
printlist(IntNodePtr p)
{
if(p == NULL)
printf("\n");
else
{
printf("%d ", p->myInt);
printlist(p->next);
}
}
main(int argc, char* argv[])
{
int n = 5;
if(argc > 1)
n = atoi(argv[1]);
IntNodePtr iNodeList;
iNodeList = NULL;
int i = 0;
while(i < n)
{
iNodeList = insert(i++, iNodeList);
printf("List is now: ");
printlist(iNodeList);
}
}

If printing the solution backwards is the problem, just maintain a global head ptr that points at the first iNode. When you have to print, while(headPtr.next !=null){ printf(...); }

I think your question relates to the order of items in the list.
Consider that, with linked lists, it is possible to add items to the head, to the tail, or insert them at an arbitrary place.
Look at the insert() function, it adds new items where?
Simplistically, you can just reverse the order in which you insert items. In real life that probably won't go down too well.
Maybe maintain a tail pointer?
And write an addItemToTail() function?

You should read more about pointers and memory. Good place to learn that is Stanford CS Education Library. You'll find there also nice materials about linked lists.

Related

Linked list without struct, but using only arrays

#include <stdio.h>
int main()
{
int n, i;
int head = 0;
printf("No of Students:\n");
scanf("%d", &n);
int data[n];
int address_of_data[n];
int *next;
printf("Enter Marks:\n");
for (i = 0; i < n; i++)
{
scanf("%d", &data[i]);
}
for (i = 0; i < n; i++)
{
if (data[head] != -1)
{
address_of_data[head] = &data[i];
}
else
{
break;
}
head++;
}
next = address_of_data[0];
for (i = 0; i < n; i++)
{
printf("%d ", *(next + i));
}
return 0;
}
In the above code, I used pointers to print the data values. Using two arrays, one for the data and another for the address of the data. But I don't how to actually implement a linked List out of this, I am really confused, can anyone tell how to implement a Linked-List without using structures.
The key advantage of a linked list is that when you insert or append an element, you can store that element anywhere in memory. Other elements in the list can point to it, and if you iterate over the list, you jump back and forth anywhere in memory following the pointers down the chain formed by the elements, until you reach the tail, which has a null pointer because it is the last element.
Implementing a linked list 'using only arrays' does not really make much sense. Even if you could, why would you want to? Arrays are great because you can index directly into them in constant time - you can't do this with linked lists, you can only iterate over them. But arrays have their drawbacks too - they are fixed size, and when they fill up, they fill up! Most shared library lists like the ArrayList in Java or the vector class in C++ store the underlying data in a fixed size array, and then if you insert too many items for that array, they create a new, larger array behind the scenes and copy the elements across for you. There really is no magic solution for when you run out of room in your array.
So with that being said, why would you implement a linked list using only arrays? You remove their only advantage - that you can append arbitrarily without costly reallocations. I'm not even sure if it's a well defined question. Perhaps if you're really desperate, you can create one large array and treat it like your own virtual memory, allocating and freeing slots in it, and then treat a two element array as an entry (entry[0] = data, entry[1] = 'address' of next, i.e. an index into your large array). But this smacks of terrible code and is really missing the point of linked lists.
Here is a complete example of a simple linked list - for more ease in pure C. Note the "next" member in the structure - this is a pointer to the successor in the list.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct MY_DATA {
int number;
char info[30];
struct MY_DATA *next;
};
#define MAX_ELEMS 5
int main(int argc, char **argv)
{
struct MY_DATA *root = NULL; /* Root of list */
struct MY_DATA *prev = NULL; /* Previously created element */
for(int i = 0; i < (MAX_ELEMS); i++)
{
/* Allocate memory ... */
struct MY_DATA *new_data = (struct MY_DATA *)malloc(sizeof(MY_DATA));
/* ...and inialize new data set */
memset(new_data, 0x00, sizeof(MY_DATA));
new_data->number = i * i;
sprintf((char *)&(new_data->info), "This is data record %d", i);
if (root == NULL)
{
root = prev = new_data; /* Remember the first element */
}
else
{
prev->next = new_data; /* The previous element has now a successor */
prev = new_data; /* Remember this for next iteration */
}
}
struct MY_DATA *current = root; /* Get the 1st element in the list */
struct MY_DATA *temp = NULL; /* Just for clean up stuff */
for(int i = 0; i < (MAX_ELEMS); i++)
{
/* Display data */
printf("Data set #%d: %s\n", current->number, current->info);
temp = current; /* This becomes deleted */
current = current->next; /* Set current pointer to successor of current element */
free(temp);
}
return 0;
}
Another exampe - accessing an array with indexes or pointers:
#include <stdio.h>
#define MAX_ELEMS 5
int my_array[MAX_ELEMS] = { 5, 18, 42, 31, 10 };
int main(int argc, char **argv)
{
int *current = (int *)my_array; /* Get the 1st element in the list */
for(int i = 0; i < (MAX_ELEMS); i++)
{
/* Using array index */
printf("Data set #%d \n" \
" Indexed access: %d\n", i, my_array[i]);
/* Using the pointer*/
printf(" Pointer access: %d\n", *current++);
}
return 0;
}

sorting a linked list containing strings

So what I want to do is to sort an linked list containing only strings. To do so, I have 2 options.
Option 1 - dynamically allocate an array with the same size as the linked list and the strings containing it also with the same size, copy the contents of the linked list into the array and sort it using qsort.
Option 2 - implement a merge sort algorithm in order to sort it.
One of the problems is will it cost more memory and time if I do option 2 over option 1 or the option is the better?
My second problem is that I'm trying to do option 1 and to do so I have a header file which contains the code of the linked lists.
The problem is after allocating memory for the array of strings when I try to copy the contents I get segmentation fault.
Program:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "Listas_ligadas_char.h"
int main() {
link_char head = NULL;
char **strings;
head = insertEnd_char(head, "fcb");
head = insertEnd_char(head, "bvb");
head = insertEnd_char(head, "slb");
head = insertEnd_char(head, "fcp");
int len = length_char(head);
int i = 0, j;
strings = (char **)malloc(sizeof(char *) * len);
link_char t;
t = head;
while (t != NULL && i <= len) {
strings[i] = (char *)malloc(sizeof(char) * (strlen(t->str) + 1));
strcpy(strings[i++], t->v.str)
t = t->next;
}
for (t = head; t != NULL; t = t->next) {
printf("* %s\n", strings[i]);
}
}
Header file:
#ifndef _Listas_ligadas_char_
#define _Listas_ligadas_char_
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
typedef struct node_char {
char *str;
struct node_char *next;
} *link_char;
link_char lookup_str(link_char head, char *str) {
link_char t;
for (t = head; t != NULL; t = t->next)
if (strcmp(t->str, str) == 0)
return t;
return NULL;
}
link_char NEW_str(char *str) {
int i;
link_char x = (link_char)malloc(sizeof(struct node_char));
x->str = (char *)malloc(sizeof(char) * (strlen(str) + 1));
strcpy(x->str, str);
x->next = NULL;
return x;
}
link_char insertEnd_char(link_char head, char *str) {
link_char x;
if (head == NULL)
return NEW_str(str);
for (x = head; x->next != NULL; x = x->next)
;
x->next = NEW_str(str);
return head;
}
int length_char(link_char head) {
int count = 0;
link_char x;
for (x = head; x != NULL; x = x->next)
count++;
return count;
}
void print_lista_char(link_char head, int NL) {
link_char t;
for (t = head; t != NULL; t = t->next) {
printf("%d * %s\n", NL, t->str);
}
}
void FREEnode_str(link_char t) {
free(t->str);
free(t);
}
link_char delete_el_char(link_char head, char *str) {
link_char t, prev;
for (t = head, prev = NULL; t != NULL;
prev = t, t = t->next) {
if (strcmp(t->str, str) == 0) {
if (t == head)
head = t->next;
else
prev->next = t->next;
FREEnode_str(t);
break;
}
}
return head;
}
#endif
btw if you are wondering what NL is, NL is a variable to count the respective line of the stdin and what I only want is to print the array, I don't want to keep its elements.
So if you can tell what option you think is the best I would appreciate it a lot.
Option 1 - dynamically allocate an array with the same size as the linked list and the strings containing it also with the same size, copy the contents of the linked list into the array and sort it using qsort.
It is not necessary to convert the linked list to an array. The quicksort algorithm can also be applied to linked lists.
However, since your linked list is only singly-linked, you cannot use the (generally more efficient) Hoare partition scheme, but must use the Lomuto partition scheme instead. This is because the Hoare partition scheme requires the ability to traverse the linked list backwards (which requires a doubly-linked list).
Even if it is not necessary to convert the linked list to an array for the quicksort algorithm, this may still be meaningful, as a linked list has worse spacial locality than an array. Either way, the average time complexity of the algorithm will be O(n*log n) and the worst-case time complexity will be O(n^2).
But since your nodes only contain pointers to strings, you will have bad spacial locality anyway when dereferencing these pointers. So in this case, it may not be very helpful to convert the linked list to an array, because that would only improve the spacial locality of the pointers to the strings, but not of the strings themselves.
One of the problems is will it cost more memory and time if i do option2 over option1 or the option is the better?
Merge-sort is ideal for linked lists.
Another advantage of merge-sort is its worst-case time complexity, which is O(n*log n), whereas it is O(n^2) with quicksort.
Merge-sort has a space complexity of O(1) for linked lists, whereas quicksort has a space complexity of O(log n). However, if you decide to convert the list to an array for quicksort, the space complexity of your algorithm will increase to O(n) ).
My second problem is that im trying to do option 1 and to do so i have an header file which contains the code of the linked lists. The problem is after allocating memory for the array of strings when i try to copy the contents i get segmentation fault.
I can only help you if you provide a minimal reproducible example of your problem. The code you posted does not reproduce the problem. It does not even compile. The following line contains several errors:
strcpy(strings[i++],t->v.str)
You indeed have 2 sensible options:
option 1 will usually provide the best performance but requires additional space of sizeof(link_char) * N.
option 2 will only require O(log(N)) stack space for pending sublists using bottom-up mergesort or similar space complexity for recursive top-down mergesort. The drawback is you have to write the sorting function yourself and it is easy to make mistakes.
Note that for option 1, you should not make a copy of the strings, but just allocate an array of pointers and initialize it to point to the nodes themselves. This way you can preserve the node structures that could contain other information and avoid extra allocations.
Note also that once you have the array of node pointers and a comparison function, you can use qsort or other sorting functions such as timsort or mergesort which may be more appropriate in terms of worst case time complexity.
There are multiple problems in your implementation:
the loop test while (t != NULL && i <= len) is incorrect. the tests should be redundant, but if you insist on testing i, it should be i < len or you might access beyond the end of the string array if length_char returned an incorrect count.
strcpy(strings[i++], t->v.str) has a syntax error, you probably mean strcpy(strings[i++], t->str);
the printing loop has undefined behavior because you do not reset i to 0 nor do you increment i in the loop body, so you pass strings[i] for all calls to printf and i should be len, so strings[i] accesses beyond the end of the allocated array. You might get a crash or an invalid pointer or by chance a null pointer that printf might ignore... It should be:
for (i = 0; i < len; i++) {
printf("* %s\n", strings[i]);
}
Here is a modified version:
#include <stdio.h>
#include <stdlib.h>
#include "Listas_ligadas_char.h"
int cmp_char(const void *aa, const void *bb) {
link_char a = *(const link_char *)aa;
link_char b = *(const link_char *)bb;
return strcmp(a->str, b->str);
}
link_char sort_char(link_char head) {
if (head != NULL && head->next != NULL) {
size_t i, len = length_char(head);
link_char *array = malloc(sizeof(*array) * len);
link_char t = head;
for (i = 0; i < len; i++, t = t->next)
array[i] = t;
qsort(array, len, sizeof(*array), cmp_char);
head = t = array[0];
for (i = 1; i < len; i++)
t = t->next = array[i];
t->next = NULL;
free(array);
}
return head;
}
int main() {
link_char head = NULL;
head = insertEnd_char(head, "fcb");
head = insertEnd_char(head, "bvb");
head = insertEnd_char(head, "slb");
head = insertEnd_char(head, "fcp");
head = sort_char(head);
for (link_char t = head; t != NULL; t = t->next) {
printf("* %s\n", strings[i]);
}
return 0;
}
Notes:
it is error prone to hide pointers behind typedefs. You should define node_char as typedef struct node_char node_char and use node_char * everywhere.
it is unconventional to define the list functions in the header file. You might do this for static inline functions, but the global functions should not be defined in the header file as this will cause name clashes if multiple modules include this header file and get linked together.

Why am I not able to display strings with the following code?

If I put an "&" in the printf, it will at-least print the names of the countries and it will crash. Otherwise, it crashes immediately. My guess is, there is something wrong with the for loop. Let me know, if I am wrong.
//Implementation file//
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct list
{
char *item;
int length;
};
typedef struct list LIST; //aliasing the structure//
LIST *create() //constrcutor//
{
LIST *L = (LIST*)malloc(sizeof (LIST));
L->length=0;
return L;
}
void insert(LIST* L, char *newitem)
{
L->item=(char*)malloc(sizeof(char));
strcpy(L->item, newitem);
(L->length)++;
}
void display(LIST *L)
{
int i;
for(i=0;i<(L->length);i++)
{
printf("Elements are: %s\n", L->item[i]);
}
}
int main ()
{
LIST *L;
L=create();
insert(L, "America");
insert(L, "Brazil");
display(L);
free(L->item);
free(L);
return 0;
}
L->item=(char*)malloc(sizeof(char));
strcpy(L->item, newitem);
You are allocating only one byte, but you try to copy a whole string into L->item, resulting in undefined behaviour. This should be:
L->item=malloc(sizeof(char)*(strlen(newitem)+1));
strcpy(L->item, newitem);
You are also calling the function insert twice, which will allocate new memory for L->item and loose the pointer to the previous allocated space -> Memory leak. You should add list elements instead of overwriting the first one all the time, see #DavidKernin's answer.
There's a gigantic error in your code: when inserting new elements you're supposed to create a new list element and initialize it..
With the function
void insert(LIST* L, char *newitem)
{
L->item=(char*)malloc(sizeof(char));
strcpy(L->item, newitem);
(L->length)++;
}
called like this:
insert(L, "America");
insert(L, "Brazil");
you're always writing the same element for length and allocating new memory (without even using/storing a pointer to the old allocated one.. which is lost!).
You should rather do something like:
//Implementation file//
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct list
{
char *item;
struct list* next;
};
typedef struct list LIST; //aliasing the structure//
LIST *create() //constrcutor//
{
LIST *L = (LIST*)malloc(sizeof (LIST));
L->next = 0;
return L;
}
LIST* insert(LIST* L, char *newitem)
{
L->item=(char*)malloc(sizeof(char)*strlen(newitem));
strcpy(L->item, newitem);
LIST *newL = (LIST*)malloc(sizeof (LIST));
newL->next = 0;
L->next = newL;
return newL;
}
void display(LIST *L)
{
int i;
for(i=0; L->next != 0;L = L->next) // Assumes there's at least 1 item
{
printf("Elements are: %s\n", L->item);
}
}
int main ()
{
LIST *startElement;
startElement=create();
LIST *lastElement = insert(startElement, "America");
lastElement = insert(lastElement, "Brazil");
display(startElement);
// Free all memory.. exercise :)
return 0;
}
Try it out interactively: http://ideone.com/n8tRtv
Otherwise the purpose of linked lists would be entirely defeated.. who wants a list which loses the previous elements when you insert new ones?
Notice that the above code
Doesn't free memory
Always assumes there's at least an item in the list
If you want a complete code, well.. fix it. If you understand how it works it should be rather feasible to fix it entirely. Good luck!
The following modification of your code will allow you to insert strings and print them. Since that is what you asked for, that is what you shall get. If you had some sort of specific data structure in mind (perhaps a linked list etc.) when coding this up, please specify.
struct list
{
char **item;
int length;
};
struct list now holds an array of pointers to char *.
LIST *create()
{
LIST *L = (LIST*)malloc(sizeof (LIST));
L->item = (char **)malloc(sizeof(char *));
L->length=0;
return L;
}
This would be the proper way to malloc for your list.
void insert(LIST* L, char *newitem)
{
L->item[L->length] = (char *)malloc(sizeof(char *));
strcpy(L->item[L->length++], newitem);
}
To insert you malloc for a new char pointer, which is placed in the end of your array of char pointers. The inserted string is copied and length is incremented.
And don't forget to free()!
L->item=(char*)malloc(sizeof(char));
is one problem in the code
The specifier in the printf statement is incorrect. You are using %s which expects a char* but you are passing a char. As a result the printf implementation is treating the character value as an address and promptly running off into invalid memory and crashing
To fix this you need to switch to using %c
printf("Elements are: %c\n", L->item[i]);
Note that this will cause every char to be printed out on a different line. Most likely you want something like the following
printf("Elements are: %s\n", L->item[i]);
int i;
for(i=0;i<(L->length);i++)
{
printf("%c", L->item[i]);
}
printf("\n");
Note that if your intent is to have the item member be a null terminated char* then the simplest fix is to do the following
printf("Elements are: %s\n", L->item);

Starting with graphs

I know this may sound a lot naive, but can someone please explain me how can i implement graphs in C language. I have read the theory, but I am not able to get off the blocks with graph programming.
I would really appreciate if someone could explain how would to create a graph using adjacency lists and adjacency matrix and how would you perform breadth first search and depth first search in C code with some explanations
And before anything, I would like to tell you that this is not a homework. I really want to learn graphs but can't afford a tutor.
I assume that here graph is a collection of vertex and edges. For that you would need an array of pointer to structures. This is adjacency list representation of graph. These structures would having at least an value, which is node number and pointer to another structure. While inserting a new node to graph just go to appropriate index of array and push the node at beginning. This is O(1) time for insertion. My implementation might help you in understanding how it really works. If you are having good skills at C this wouldn't take much longer to understand the code.
// Graph implementation by adjacency list
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_SIZE 1000
typedef struct node{
int number;
struct node * next;
} Node;
// U is starting node, V is ending node
void addNode (Node *G[], int U, int V, int is_directed)
{
Node * newnode = (Node *)malloc(sizeof(Node));
newnode->number = V;
newnode->next = G[U];
G[U] = newnode;
// 0 for directed, 1 for undirected
if (is_directed)
{
Node * newnode = (Node *)malloc(sizeof(Node));
newnode->number = U;
newnode->next = G[V];
G[V] = newnode;
}
}
void printgraph(Node *G[], int num_nodes)
{
int I;
for (I=0; I<=num_nodes; I++)
{
Node *dum = G[I];
printf("%d : ",I);
while (dum != NULL)
{
printf("%d, ",dum->number);
dum =dum->next;
}
printf("\n");
}
}
void dfs (Node *G[], int num_nodes, int start_node)
{
int stack[MAX_SIZE];
int color[num_nodes+1];
memset (color, 0, sizeof(color));
int top = -1;
stack[top+1] = start_node;
top++;
while (top != -1)
{
int current = stack[top];
printf("%d ",current);
top--;
Node *tmp = G[current];
while (tmp != NULL)
{
if (color[tmp->number] == 0)
{
stack[top+1] = tmp->number;
top++;
color[tmp->number] = 1;
}
tmp = tmp->next;
}
}
}
void bfs (Node *G[], int num_nodes, int start_node)
{
int queue[MAX_SIZE];
int color[num_nodes+1];
memset (color, 0, sizeof (color));
int front=-1, rear=-1;
queue[rear+1] = start_node;
rear++;printf("\n\n");
while (front != rear)
{
front++;
int current = queue[front];
printf("%d ",current);
Node *tmp = G[current];
while (tmp != NULL)
{
if (color[tmp->number] == 0)
{
queue[rear+1] = tmp->number;
rear++;
color[tmp->number] = 1;
}
tmp = tmp->next;
}
}
}
int main(int argc, char **argv)
{
int num_nodes;
// For Demo take num_nodes = 4
scanf("%d",&num_nodes);
Node *G[num_nodes+1];
int I;
for (I=0; I<num_nodes+1 ;I++ )
G[I] = NULL;
addNode (G, 0, 2, 0);
addNode (G, 0, 1, 0);
addNode (G, 1, 3, 0);
addNode (G, 2, 4, 0);
addNode (G, 2, 1, 0);
printgraph( G, num_nodes);
printf("DFS on graph\n");
dfs(G, num_nodes, 0);
printf("\n\nBFS on graph\n");
bfs(G, num_nodes, 0);
return 0;
}
Well, a real naive and basic answer would be that graph can be represented in C using data structures that contain their pointers to other such data structures. Graphs are really just doubly linked lists that can have multiple links from a single node. If you haven't digested linked lists and doubly linked lists, that'd be a good place to start.
So let's say you have a adjacency list, {a,b},{b,c},{d},{b,e}. First off, you parse that and make a list of all your unique items. (A regular linked list, array, whatever, it's just a temporary structure to help you. You could bypass that, do it on the fly, and probably reap a speedup, but this is simple.) Walking through that list, you generate a node for each item. For each node, you go through the adjacency list again and create an edge when it sees itself. This is a pointer inside the node pointing to another node.
In the end you have a regular list of all you nodes, so you don't lose that lone 'd' node hanging out by itself. You also have a graph of all your nodes so you know their relationship to each other.
Search
Searching across graphs is a pretty basic idea. Start in a node, compare, move to one of it's neighbors and do it again. There are a lot of pitfalls though. Like getting into an endless loop and knowing when to stop.
You'll have to ask more specific questions if you want a better explanation than what you can find online already.

Compare using strcmp on linked-list

I'm not a great understanding on linked-list, i don't know if it's possible, but i need to do it :) I have a linked list that are load to the struct, and i need to compare a all the chars on the struct....It's better with an example:
This is without linked lists
struct
typedef struct x{
char name[100];
}x;
typedef x Info;
typdef struct Elem{
Info node;
struct Elem*next;
}Element;
for(i=0;i<100;i++){
if(strcmp(a.name[i],a.name[i+1])==0){
printf("Same name\n");
}
}
else
printf("Diff name\n");
Now i need to do something like this but with linked-list
First of all: int strcmp ( const char * str1, const char * str2 ) compares two C-strings (char pointers). This means that a.name[i] should be a char pointer and not a char! Make sure this is the case (i.e. make sure a.name is an array of c-string arrays, and not an array of chars).
Secondly, if the previous is the case, your code will only compare string i with string i+1. It will not compare all strings with each other.
In any case, it looks like you are not doing whatever it is you want to do the right way. I'm guessing you want a struct that is defined like this:
struct example {
char * name;
// other members of choice
example * next;
}
A placeholder for a name, other members, and a next pointer to enable the linked list data type. That way you can compare names with:
while (list->next != 0 && list->next->next != 0) {
if (strcmp(list->name, list->next->name) == 0) // do something;
else // do something else;
}
or with a double loop if you want to compare all strings with each other.
So the first thing you need to do is understand the fundamentals of linked-list. You can read in detail here: http://www.codeproject.com/KB/cpp/linked_list.aspx
NOTE: You really can't undersand linked lists until you understand pointers. http://www.cplusplus.com/doc/tutorial/pointers/
Essentially a linked-list is composed of numerous "nodes" that link to each other. At a minimum each node will have two pieces of data, one being the data (in your case a character) and the other being a pointer to the next node in the list.
Defining a struct would look like (in pseudocode):
LinkedList nodeT {
char *c; //NOTE: strcmp only compares pointers to chars
nodeT *nextNode;
}
You would have a pointer to the first node of the linked list. Something like:
nodeT *firstElement;
Then cycling through the entire list is a piece of cake:
nodeT *curElement = firstElement;
while(curElement->next != NULL) { //assuming the last node's next pointer is NULL
if(strcmp(curElement->c,curElement->next->c)==0){
printf("Same name\n");
} else {
printf("Diff name\n");
}
curElement = curElement->nextNode;
}
But again, to understand this you need to understand the fundamentals of pointers.
Here is a program that traverses the linked list and compares the names of adjacent elements. I have taken the liberty of renaming a couple of things, but otherwise the code for the data structures is the same as yours.
#include <string.h>
#include <stdio.h>
#include <assert.h>
typedef struct Info_ {
char name[100];
} Info;
typedef struct Element_ {
Info info;
struct Element_* next;
} Element;
void print_comparisons(Element* elm)
{
assert(elm);
Element* cur = elm;
Element* next = cur->next;
for (; next; cur = next, next = next->next) {
if (strcmp(cur->info.name, next->info.name) == 0)
printf("Same name\n");
else
printf("Diff name\n");
}
}
int main()
{
Info a; a.name[0] = 'A'; a.name[1] = '\0';
Info b; b.name[0] = 'B'; b.name[1] = '\0';
Info c; c.name[0] = 'B'; c.name[1] = '\0';
Info d; d.name[0] = 'D'; d.name[1] = '\0';
Element na; na.info = a;
Element nb; nb.info = b;
Element nc; nc.info = c;
Element nd; nd.info = d;
na.next = &nb;
nb.next = &nc;
nc.next = &nd;
nd.next = NULL;
print_comparisons(&na);
}
The output of the program:
Diff name
Same name
Diff name

Resources