Adding weighted edges to my linked list graph in c - c

So I'm trying to build a graph data structure with towns as the nodes and the edges as the distance between them. I want to create an adjacency list for each node/location and add a weighted edges. So far I've created a linked list program which asks the user how many nodes they want. The user can then name each node when they've been created and it prints out a linked list with the nodes.
#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
char city[20];
int weight;
struct node *next;
}node;
node *createLinkedList(int n);
void displayList(node *head);
int main()
{
int n = 0;
node *HEAD = NULL;
printf("\nHow many nodes:\t");
scanf("%d", &n);
HEAD = createLinkedList(n);
displayList(HEAD);
return 0;
}
node *createLinkedList(int n)
{
int i = 0;
node *head = NULL;
node *temp = NULL;
node *p = NULL;
for (i = 0; i < n; i++)
{
// create an individual node
temp = (node*)malloc(sizeof(node));
printf("\nEnter the name of the city: ", i+1);
scanf("\t%s",(temp->city));
temp->next = NULL;
if (head == NULL) //if list is currently empty, then make temp as first node
{
head = temp;
}
else
{
p = head;
while(p->next != NULL)
p = p->next;
p->next = temp;
}
}
return head;
}
void displayList(node *head)
{
node *p = head;
while(p != NULL)
{
printf("\t%s->",p->city);
p = p->next;
}
}
Now, I want the user to specify the weights of each edge and for it to be printed. I've tried to do this myself but to no avail. I've specified a weight int in the structure at the top. I'd appreciate any help. Thanks!

You just need to use scanf as the you used for city. Using the type format %d for int.
printf("\nEnter the name of the city %d: ", i+1);
scanf("\t%19s",(temp->city));
printf("\nEnter the the weight of the city %d: ", i+1);
scanf("\t%d",&(temp->weight));
For printing the weight:
printf("weight = %d\n",p->weight);
Is that you want ?
UPDATE:
If you want to request the sub-sequence of linked-list, you can add two argument start, end into the create and display function.
node *createLinkedList(int n, int start, int end);
void displayList(node *head, int start, int end);
For create function:
for (i = 0; i < n; i++) {
....
if (start <= i && i <= end) {
printf("\nEnter the the weight of the city %d: ", i+1);
scanf("\t%d",&(temp->weight));
}
...
}
For display function, you can use the counter for the order of the node in list:
int counter = 0;
while(p != NULL)
{
...
if (start <= counter && counter <= end) {
printf("\n weight = %d \n", p->weight);
}
...
counter++;
p = p->next;
}
Then, when you call function, for example, you want to print from 2nd node to 4th node.
displayList(HEAD, 1, 3);
If you dont want to add the start and end values, or you want to work many time with sub-sequence, you can add one parameter int index into the struc for tracking the order of each node.
typedef struct node
{
char city[20];
int weight;
int index
struct node *next;
}node;

Related

Graphs: for an adjacency matrix

I have to write a program, whitch will show out graph results in the form of an adjacency list and adjacency matrix. I've guided myself by a tutorial on YT on how to implement the adjency list, and with the current stored data (whitch the user is introducing himself, like the number of nodes, edges, to how many edges a edge is connected and to which one) and I want to know/understand how, with the already stored data, to build a adjacency matrix.
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node *next;
};
void read_graf(struct node *ad[], int no_of_nodes);
void print_graf(struct node *ad[], int no_of_nodes);
int main()
{
int op;
int i,j,k, nodes;
begin:
printf("Type in the number of edges: ");
scanf("%d", &nodes);
struct node *adj[nodes];
for (i=0;i<nodes;i++)
adj[i] = NULL;
read_graf(adj,nodes);
print_graf(adj,nodes);
printf("\nDo you want to try again? 1 for yes and 0 for no: ");
scanf("%d", &op);
if (op==1)
goto begin;
else
{
printf("Thank you for visiting! :)");
exit(0);
}
return 0;
}
void read_graf(struct node *ad[], int no_of_nodes)
{
struct node *new_node;
int i,j,k, val;
for (i=0;i<no_of_nodes;i++)
{
struct node *last= NULL;
printf("\n To how many edges is edge %d connected to: ", i+1);
scanf("%d", &k);
for (j=0;j<k;j++)
{
printf("To which edges is it connected : ");
scanf("%d", &val);
new_node = (struct node *)malloc(sizeof(struct node*));
new_node->data = val;
new_node->next = NULL;
if(ad[i]==NULL)
ad[i]= new_node;
else
last->next = new_node;
last = new_node;
}
}
}
void print_graf(struct node *ad[], int no_of_nodes)
{
struct node *ptr = NULL;
int i,j;
for(i=0;i<no_of_nodes;i++)
{
ptr = ad[i];
printf("\n x%d : ", i+1);
while(ptr != NULL)
{
printf("%d,\t", ptr->data);
ptr = ptr->next;
}
printf("0");
}
}
If you only need to print out the adjacency matrix and assuming that a 1 would represent a connection between node i and node j, you just have to slightly modify the inner loop inside the print_graf function.
void print_as_mat(struct node *ad[], int no_of_nodes)
{
struct node *ptr = NULL;
for(int i = 0; i < no_of_nodes; ++i)
{
ptr = ad[i];
// Loop over all the possible nodes
for(int j = 0; j < no_of_nodes; ++j)
{
if ( ptr && ptr->data == j ) {
// ^^^^^^^^^^^^^^ Check if the index correspond to the
// current node in the adjacency list.
printf(" 1");
// update the current node in the list, but only here.
ptr = ptr->next;
}
else {
printf(" 0");
}
}
// The row is completed.
putchar('\n');
}
}

Need Help Troubleshooting Program in C

I need this program to stop asking for flavors when the word "lemon" is said. For some reason, I can't get it to work correctly. I have tried to add an "if" statement for it but it wasn't working out correctly. The code will stop asking for flavor for a split sentence and then will start asking for it again and it will go all the way to 15 flavors instead of stopping at the flavor "lemon".
#include <stdio.h>
#include <string.h>
#include<stdlib.h>
typedef struct node {
void *data;
int d;
struct node *next;
}node;
node * createLinkedList(char [][20], int);//function to create linked list for all flavours
node * createLinkedListPrice(int ar[], int);//function to declare linkedlist for all prices
int main(void) {
int c= 1;//count of input flavors
char allFlavors[16][20];
int allPrice[16];
char ch[] = "lemon";
while(c != 16) {//taking input flavors and prices
char flavorName[20];
printf("Enter flavor %d name:", c);
scanf("%s", flavorName);
if(!(strcmp(flavorName,ch)) && c > 5) {
break;
}
else if(!(strcmp(flavorName,ch)) && c <= 5) {
continue;
}
int price;
printf("Enter flavor %d price in $", c);
scanf("%d", &price);
strcpy(allFlavors[c], flavorName); //storing all flavors in array of strings
allPrice[c] = price;//storing all prices in array
c += 1;//This variable is to keep track of count of input
}
while(1) {
char instruct[5];
printf("Do u want icecream:");
scanf("%s", instruct);
if(!strcmp(instruct,"no"))//If the given instruction is no then break
break;
else {//If given instruction is yes then calculate the cost of flavour
char flav[20];
int scoops;
int cost = 0;
printf("Which flavor do u want\n");
scanf("%s", flav);
printf("How many scoops:");
scanf("%d", &scoops);
node *head = createLinkedList(allFlavors,c);//calling all flavors function for head
node *priceHead = createLinkedListPrice(allPrice,c);//calling all price function for head
while(head != NULL) {//searching for the flavour in the linkedlist
if(!strcmp(head->data,flav)) {//If flavour is found then add the price to cost
cost += (scoops * priceHead->d);
break;
}
priceHead = priceHead->next;
head = head->next;
}
printf("cost is $%d\n", cost);
}
}
}
node * createLinkedList(char allFlavors[][20], int n) {//creates linkedlist of all flavors and returns head
node * head = NULL;
node * temp = NULL;
node * ptr = NULL;
for(int pd = 1; pd < n; pd++) {
temp = (node*)malloc(sizeof(node));
temp->data = allFlavors[pd];
temp->next = NULL;
if (head == NULL)
head= temp;
else {
ptr=head;
while(ptr->next!=NULL) {
ptr=ptr->next;
}
ptr->next=temp;
}
}
return head;
}
node * createLinkedListPrice(int ar[], int n) {//creates linkedlist of all prices and returns head
node * head = NULL;
node * temp = NULL;
node * ptr = NULL;
for(int pd = 1; pd < n; pd++) {
temp = (node*)malloc(sizeof(node));
temp->d = ar[pd];
temp->next = NULL;
if (head == NULL)
head= temp;
else {
ptr=head;
while(ptr->next!=NULL) {
ptr=ptr->next;
}
ptr->next=temp;
}
}
return head;
}

Segmentation fault issue while reversing linked list in c

#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node *next;
};
struct node *insert(struct node *link, int data) {
if (link == NULL) {
link = (struct node *)malloc(sizeof(struct node));
link->data = data;
link->next = NULL;
} else {
struct node *newlink = (struct node *)malloc(sizeof(struct node));
newlink->data = data;
newlink->next = link;
link = newlink;
}
return link;
}
void reverse(struct node *link) {
int i, j = 0;
int arr1[100], arr2[100];
struct node *current;
int count = 0;
current = link;
while (current != NULL) {
arr1[i] = current->data;
i = i + 1;
count = count + 1;
current = current->next;
}
printf("\n");
i = 0;
j = 0;
for (i = count - 1; i >= 0; i--) {
arr2[j] = arr1[i];
j = j + 1;
}
printf("The elements in the linked list are: ");
for (i = 0; i < count; i++) {
printf("%d ", arr1[i]);
}
printf("The elements in the reversed linked list are: ");
for (j = 0; j < count; i++) {
printf("%d ", arr2[j]);
}
}
void print(struct node *link) {
struct node *temp = link;
printf("The elements in the linked list are: ");
while (temp != NULL) {
printf("%d ", temp->data);
temp = temp->next;
}
}
void main() {
int value;
printf("Enter the value:\n");
scanf("%d", &value);
struct node *link = NULL;
link = insert(link, value);
char ans[3] = "yes";
while (ans[0] == 'y') {
printf("Do you want to add another node? Type Yes/No\n");
scanf("%s", ans);
if (ans[0] == 'y') {
printf("Enter the value:\n");
scanf("%d", &value);
link = insert(link, value);
} else {
reverse(link);
}
}
}
Here is the code I wrote to reverse a single linked list in C. I seem to try different combinations of the program but while doing it by array method, I am unable to get rid of the segmentation fault, and hence it doesn't give output.
There are some problems in your code:
i is uninitialized when used in the while loop in function reverse, causing undefined behavior which could explain the segmentation fault.
j is not modified in the loop at the end of the reverse function, causing an infinite loop:
for (j = 0; j < count; i++) {
printf("%d ", arr2[j]);
}
you are not reversing the list, you just print the list contents in reverse order, and assume its length is at most 100. This is probably not what you are expected to do.
in function main, the array ans should be made larger to accommodate at least the word yes, and you should prevent scanf() from storing more characters into it than would fit. Also reorganize the code to avoid duplication:
int main(void) {
struct node *link = NULL;
for (;;) {
char ans[80];
int value;
printf("Enter the value:\n");
if (scanf("%d", &value) != 1)
break;
link = insert(link, value);
printf("Do you want to add another node? Type Yes/No\n");
if (scanf("%79s", ans) != 1 || ans[0] != 'y') {
break;
}
}
reverse(link);
return 0;
}
Most of the above problems would have been spotted immediately by increasing the compiler warning level (for example gcc -Wall -Werror or clang -Weverything -Werror).
Here is a simpler version that reads numbers and allocates the list in the same order as you do, inserting each new element before the previous one, then reverses the list and finally prints it. As expected, the list is printed in the order of entry.
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node *next;
};
struct node *insert(struct node *head, int data) {
struct node *newlink = malloc(sizeof(*newlink));
newlink->data = data;
newlink->next = head;
return newlink;
}
struct node *reverse(struct node *link) {
struct node *prev = NULL;
while (link) {
struct node *temp = link->next;
link->next = prev;
prev = link;
link = temp;
}
return prev;
}
void print(struct node *link) {
printf("The elements in the linked list are: ");
for (struct node *n = link; n; n = n->next) {
printf("%d ", n->data);
}
printf("\n");
}
int main(void) {
struct node *link = NULL;
int value;
printf("Enter the values, end the list with 0:\n");
while (scanf("%d", &value) == 1 && value != 0) {
link = insert(link, value);
}
link = reverse(link);
print(link);
return 0;
}

Insertion at end of linked list

I am trying to write a program that creates and displays linked lists, and allows people to insert an element at the beginning, middle or end.
Insertion at the beginning or the middle works perfectly. However, my program fails when it comes to inserting at the end. Please have a look and tell me where I am going wrong or what needs modification. Here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
struct node {
int number;
struct node *next;
};
typedef struct node NODE;
NODE *node1, *start, *rear, *m, *nodex, *temp1;
int main() {
int i, n1, n2;
start = NULL;
printf("Enter the number of inputs to the list:");
scanf("%d", &n1);
for (i = 0; i < n1; i++) {
// node creation begins here
node1 = (NODE*) malloc(sizeof(NODE));
int inf;
printf("Enter node value:");
scanf("%d", &inf);
node1->number = inf;
node1->next = NULL;
if (start == NULL) {
// first node creation
start = rear = node1;
} else {
m = start;
if (m->number > inf) {
// for insertion in beginning
node1->next = m;
start = node1;
} else {
while (m->next->number < inf) {
// searching to insert in middle of sorted list
m = m->next;
}
temp1 = m->next;
m->next = node1;
node1->next = temp1;
}
}
display(); // to display the linked list
}
return 0;
}
void display() {
nodex = start;
while (nodex != NULL) {
printf("%d ->", nodex->number);
nodex = nodex->next;
}
}
What happens at the end of the list?
while(m->next->number < inf){
//searching to insert in middle of sorted list
m=m->next;
}
This check fails when m->next is NULL. NULL->something fails. So do a check if it's a valid pointer, like:
while(m->next)
if(m->next->number < inf)
m=m->next;
else
break;

C infinite loop with linked list

I am trying to make a program that initialize a singular linked list and then ask user for more data and add them at the end of current linked list. However, my programming is trapped in infinite loop.
#include <stdio.h>
#include <stdlib.h>
typedef struct linked_list
{
int data;
struct linked_list *next;
}element;
typedef element *elementptr;
void addend(elementptr *,int);
void traverse(elementptr);
int main()
{
// create a linked list
elementptr first = NULL,
last = NULL;
int input,num;
printf("Please enter first integer data: \n");
scanf("%d",&input);
//Create a linked list with user initialized data
first = (elementptr)malloc(sizeof(element));
last = first;
last -> data = input;
last -> next = NULL;
printf("Please enter number of data you want to add in the end of linked list\n");
scanf("%d",&num);
addend(&last,num);
traverse(first);
return 0;
}
void addend(elementptr *l, int num)
{
int i = 0,extradata;
while(i<num)
{
i++;
printf("Please enter a data: \n");
scanf("%d",&extradata);
(*l) -> next = (elementptr)malloc(sizeof(element));
*l = (*l) ->next;
(*l) -> data = extradata;
(*l) -> next = NULL;
}
printf("The data sets are added\n");
}
void traverse(elementptr f)
{
elementptr current;
int count = 0;
current = f;
while (current != NULL)
{
count++;
printf("The data is %d \n", current->data);
}
printf("The linked list has %d elements \n",count);
}
In your code
while (current != NULL)
{
count++;
printf("The data is %d \n", current->data);
}
you never change the value of current. Either it starts as NULL and the loop never executes, or it starts non-NULL and the loop runs forever.
You should add
current = current->next
after your printf to advance to the next element in the linked list.
current = current -> next; you are missing this statement in the while loop. Although I would suggest :
#include<stdio.h>
#include<stdlib.h>
struct linked_list
{
int number;
struct linked_list *next;
struct linked_list *prev;
};
typedef struct linked_list node;
void create(node *p);
void print(node *p);
int main()
{
node *head;
printf("---Start of the list ---\n");
printf("enter -1 to exit\n");
head = (node*)malloc(sizeof(node));
create(head);
print(head);
}
void create(node *list)
{
printf("enter the data");
scanf(" %d",&list->number);
if(list->number == -1)//Enter -1 to exit untill then keep on taking values
{
list->next=NULL;
}
else
{
list->next = (node*)malloc(sizeof(node));
create(list->next);
}
}
void print(node *list)
{
if(list->next != NULL)
{
printf("%d-->",list->number);
if((list->next->next == NULL) && (list->next->number!=-1))
printf("%d -->End of the List",list->next->number);
print(list->next);
}
}
In your traverse function, the current node is not pointing to next node. So the while condition while (current != NULL) will not be true and hence the while loop is running infinitely.
To fix it, current node should point to the next node (current = current->next) in the list after printing the data.
For example:
void traverse(elementptr f)
{
elementptr current;
int count = 0;
current = f;
while (current != NULL)
{
count++;
printf("The data is %d \n", current->data);
// Fix
current = current->next; // Point to next node in link list
}
}

Resources