Graphs: for an adjacency matrix - c

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');
}
}

Related

Linked list unable to print all elements

I'm trying to print the linked list to which I prompt for user input.
This code below is not printing the whole list, only the last element at a time.
I don't seem to find the bug. Can you please take a look at it?
#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
struct Node *next;
};
struct Node *head;
void Insert(int x) {
struct Node *temp = (struct Node *)malloc(sizeof(struct Node));
temp->data = x;
temp->next = NULL;
head = temp;
};
void Print() {
struct Node *temp = head;
printf("Linked list is: ");
while (temp != NULL) {
printf("%d ", temp->data);
temp = temp->next;
}
printf("\n");
};
int main() {
head = NULL;
int i, x;
for (i = 1; i <= 10; i++) {
if (i == 1) {
printf("Enter 1st number: \n");
} else if (i == 2) {
printf("Enter 2nd number: \n");
} else {
printf("Enter %dth number: \n", i);
}
scanf("%d", &x);
Insert(x);
Print();
}
}
temp->next = NULL; is the culprit. It should be temp->next = head;.
Another (more cornercase) issue is that your code fails to check for errors in malloc and scanf.
Edit in response to comment:
If you want to append (as opposed to prepend), you'll need to keep a tail pointer for forward traversal and then either use a dummy first node (avoids a branch) or special-case an insert to an empty list.
Example of both (with simplistic error handling via exit(1)) in one piece of code:
#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
struct Node *next;
};
#define DUMMYFIRST 1 //change to 0 to compile the other variant
#if DUMMYFIRST
struct Node dummyfirst;
struct Node *head=&dummyfirst;
#else
struct Node *tail,*head=0;
#endif
void Insert(int x) {
struct Node *newnode = malloc(sizeof(struct Node));
//don't cast the result of malloc in C
//https://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc
if(!newnode) { perror("malloc"); exit(1); }
newnode->data = x;
newnode->next = 0;
#if !DUMMYFIRST
if(!tail) tail = head = newnode;
else head->next = newnode;
#else
head->next = newnode;
#endif
head = newnode;
};
void Print() {
#if DUMMYFIRST
struct Node *newnode = dummyfirst.next;
#else
struct Node *newnode = tail;
#endif
printf("Linked list is: ");
while (newnode != NULL) {
printf("%d ", newnode->data);
newnode = newnode->next;
}
printf("\n");
};
int main() {
int i, x;
for (i = 1; i <= 10; i++) {
if (i == 1) {
printf("Enter 1st number: \n");
} else if (i == 2) {
printf("Enter 2nd number: \n");
} else {
printf("Enter %dth number: \n", i);
}
if(1!=scanf("%d", &x)) exit(1);
Insert(x);
Print();
}
}
A more library friendly approach to handling errors would be to propagate the error to the caller, i.e., instead of exiting with an error message right away, you'd change the return value from void to something indicating the error, e.g. so that the caller could check and decide what to do (print it, print it in a localized version, try a different algorithm...)
E.g.:
struct Node *Insert(int x) {
struct Node *newnode = malloc(sizeof(struct Node));
//don't cast the result of malloc in c
//https://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc
if(!newnode) return NULL;
//...
};
//...
//calling code:
if(!Insert(x)) perror("Insert"),exit(1);
When you insert the new node, you do not link the rest of the list, instead of temp->next = NULL; you should write
temp->next = head;
To ensure defined behavior, you should check for memory allocation failure and invalid input.
Also remove the dummy ; after the function bodies.
Here is a modified version:
#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
struct Node *next;
};
struct Node *head;
int Insert(int x) {
struct Node *temp = malloc(sizeof(*temp));
if (temp) {
temp->data = x;
temp->next = head;
head = temp;
return 1;
} else {
return 0;
}
}
void Print(void) {
struct Node *temp = head;
printf("Linked list is: ");
while (temp != NULL) {
printf("%d ", temp->data);
temp = temp->next;
}
printf("\n");
}
int main() {
static char suffix[4][3] = { "th", "st", "nd", "rd" };
int i, x;
for (i = 1; i <= 10; i++) {
int suff = (i >= 1 && i <= 3) ? i : 0;
printf("Enter %d%s number:\n", i, suffix[suff]);
if (scanf("%d", &x) != 1) {
fprintf(stderr, "invalid or missing input\n");
break;
}
if (!Insert(x)) {
fprintf(stderr, "cannot allocate memory for Node\n");
return 1;
}
Print();
}
return 0;
}

Adding weighted edges to my linked list graph in 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;

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;
}

Linked list representation of a polynomial

I have to write a program to sum two polynomials. For the purpose, first of all, I am writing a program to take two polynomials and print them.
My program is like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct node
{
int power;
int coef;
struct node *link;
};
int input( struct node *Phead);
int display( struct node *Phead);
int main()
{
struct node *Phead= malloc(sizeof(struct node)),*Qhead = malloc(sizeof(struct node));
input(Phead);
display(Phead);
input(Qhead);
display(Qhead);
return 0;
}
int input( struct node *Phead)
{
//Phead
//Qhead = malloc(sizeof(struct node));
int value;
printf("\n\t\tEntry of polynomial:\n");
printf("Enter the coefficient: ");
scanf("%d",&Phead->coef);
printf("Enter the power: ");
scanf("%d",&Phead->power);
Phead->link = NULL ;
printf("Enter the coefficient,( 0 to break ): ");
scanf("%d", &value);
while ( value != 0 )
{
struct node *new_node = malloc(sizeof(struct node ));
new_node -> coef = value;
printf("Enter the power: ");
scanf("%d",&new_node->power);
new_node->link = Phead;
Phead = new_node;
//printf("%d",Phead->power);
printf("Enter the coefficient,( 0 to break ): ");
scanf("%d", &value);
}
return 0;
}
int display( struct node *Phead)
{
struct node *temp = Phead;
//printf("I am in display.\n");
while ( temp != NULL )
{
//printf("I am in while.\n");
printf("%d * x ^ %d + ",temp->coef,temp->power);
temp=temp->link;
}
//printf("%d * x ^ %d + ",temp->coef,temp->power);
//printf("0");
return 0;
}
I am unable to print the polynomial.The issue is with temp variable. Please help me to solve this.
The problem is with your this part of code:
new_node->link = Phead;
Phead = new_node;
Solve it as follows:
Phead->link = new_node;
Phead = new_node;

LinkedList Elements Swap Problem In C

I wrote a program that has many functionalities but I can not swap 2 elements of 2 nodes in the linked list.Actually I can swap 2 nodes by changing their links but I can not swap 2 elements when the user requested 2 elements swapping.Here is my code without any swap operation.Again I have to say I want to do this swap operation by swapping 2 node elements not changing node links.How can I get rid of this problem?Any help will be appreciated.
#include <stdio.h>
#include <stdlib.h>
struct node{
int data;
struct node *next;
};
typedef struct node nodetype;
void insert(int ,struct node **);
void display(struct node *);
void search(int, struct node *);
void delete(int, struct node **);
int main(void){
nodetype *p;
p=NULL;
int x=0,choice;
int s_no,k,r_no;
while(x!=1){
printf("enter 1 for insert\n");
printf("enter 2 for display\n");
printf("enter 3 for search\n");
printf("enter 4 for delete\n");
printf("enter 0 for exit\n");
fflush(stdout);
scanf("%d",&choice);
if(choice==1){
printf("enter inserted no\n");
fflush(stdout);
scanf("%d",&k);
insert(k,&p);
}
else if(choice==2)
display(p);
else if(choice==3){
printf("enter searched no\n");
scanf("%d",&s_no);
search(s_no, p);
}
else if(choice==4){
printf("enter deleted no\n");
scanf("%d",&r_no);
delete(r_no,&p);
}
else
printf("invalid choice\n");
}
return 0;
}
void display ( struct node *p)
{
printf("the content is:\n");
if(p==NULL)
printf("the link is empty\n");
while ( p != NULL )
{
printf ( "%d ", p -> data ) ;
p = p -> next ;
}
printf ( "\n" ) ;
}
void search(int no, struct node *p){
nodetype * loc;
for(loc=p;loc!=NULL;loc=loc->next)
{
if(no==loc->data){
printf("\nthe number exist in the list\n");
return;
}
}
printf("\nthe number is not exist in the \n");
}
void insert(int x,struct node **p)
{
struct node *r,*temp=*p;
r = (struct node *)malloc ( sizeof (struct node)) ;
r ->data = x ;
r->next=NULL;
if ( *p == NULL)
{
*p = r ;
}
else
{
while(temp->next!= NULL)
{
temp=temp->next;
}
temp->next=r;
}
}
void delete(int num, struct node **p){
struct node *temp,*x;
temp=*p;
x= NULL;
while (temp->next !=NULL){
if(temp->data == num)
{
if (x==NULL)
{
*p = temp->next;
free(temp);
return;
}
else
{
x->next = temp->next;
free(temp);
return;
}
}
x=temp;
temp=temp->next;
}
printf(" No such entry to delete ");
}
I attempted swap operation with using
user entered numbers.For instance,the
user entered 12 and 45 in order to
swap in the linkedlist.How can I do
that?
I would suggest you extend the existing function with return values, (not tested just the idea)
nodetype * search(int no, struct node *p){
nodetype * loc;
for(loc=p;loc!=NULL;loc=loc->next)
{
if(no==loc->data){
printf("\nthe number exist in the list\n");
return loc;
}
}
printf("\nthe number is not exist in the \n");
return NULL;
}
After that you call search for both values entered by the user.
Then you swap the values in place without changing any pointer references simply be assigning new values. Of course you need to check whether the nodes were actually found (not NULL).
nodetype *node1;
nodetype *node2;
node1 = search( userInput1, &p );
node2 = search( userInput2, &p );
int tmp_data = node1->data;
node1->data = node2->data;
node2->data = tmp;

Resources