I created a program to sort double linked list in ascending order, and the result was unexpected, but when I used the same program for descending order by changing a line in it, it worked perfectly. Please tell where m going wrong
/*Structure of double linked list */
struct dlink
{
int num;
struct dlink *plink; //previous address
struct dlink *nlink; //next address
};
void main()
{
clrscr();
struct dlink *st;
st=NULL;
append(&st,100); //to put values in double linked list
append(&st,32);
append(&st,200);
append(&st,107);
display(st);
ascending(&st);
display(st);
getch();
}
/* function to add values to double linked list */
void append(struct dlink **q,int n)
{
struct dlink *temp,*r;
temp=*q;
if(temp==NULL)
{
temp=(dlink *)malloc(sizeof(dlink));
temp->num=n;
temp->plink=NULL;
temp->nlink=NULL;
*q=temp;
}
else
{
while(temp->nlink!=NULL)
temp=temp->nlink;
r=(dlink *)malloc(sizeof(dlink));
r->num=n;
r->nlink=NULL;
r->plink=temp;
temp->nlink=r;
}
}
void ascending(struct dlink **q)
{
struct dlink *temp,*s,*p=NULL;
temp=*q;
int a=count(*q);
printf(" a %d ",a);
for(int i=0;i<a;i++,temp=temp->nlink)
{
s=temp->nlink;
for(int j=i+1;j<=a;j++,s=s->nlink)
{
if((temp->num) < (s->num)) //for ascending i was using //if(temp->num > s->num but it is not getting desired result it is just printing //one value and by this one for descending order program is working perfectly //for descending order
{
(s->plink)->nlink=s->nlink;
if(s->nlink!=NULL)
(s->nlink)->plink=s->plink;
s->plink=temp->plink;
s->nlink=temp;
temp=s;
(temp->nlink)->plink=temp;
}
}
if(i==0)
*q=temp;
if(i!=0)
{
p->nlink=temp;
temp->plink=p;
}
p=temp;
}
temp=*q;
/* To see if the addresse , previous address , next address are correct */
while(temp!=NULL)
{
printf("as %u %u %u\n",temp->plink,temp->nlink,temp);
temp=temp->nlink;
}
}
Look at this part
int a=count(*q);
for(int i=0; i<a; i++,temp=temp->nlink)
{
s=temp->nlink;
for(int j=i+1; j<=a; j++,s=s->nlink)
{ ....
Seems you are using indexes from 0 (first loop) to count(*q) (second) for a list with count(*g) elements.
Something is probably wrong in your algorithm - even if it doesnt cause "index out of bounds" errors (because you don't use arrays).
And it appears when you try to sort the second way, because you have not tested the first way seriously enough.
Related
I was solving a problem which allowed two types of operations: subtracting one from a number or multiplying it by two, with the source and the destination numbers provided. Input constraints are 1<=n<=10^4 for both numbers. I'm supposed to output the number of operations needed to produce the desired number from the given one. The following is my implementation, getting runtime error and, obviously, I do not know why. It'll be awesome if someone explains the bug. Thanks.
#include <stdio.h>
#include <stdlib.h>
int g[22222][3], v[2222], size;//g == graph, v == visited and size == the size of queue
typedef struct _queue
{
int val;
struct _queue *next;
struct _queue *prev;
} queue;
queue *head=NULL, *last=NULL;
void push(int val)
{
queue *ptr=(queue *) malloc(sizeof(queue));
ptr->next=NULL;
ptr->val=val;
if (head)
{
last->next=ptr;
ptr->prev=last;
}
else
{
head=ptr;
ptr->prev=NULL;
}
last=ptr;
}
void pop()
{
if (size)
{
queue *ptr=last;
last=last->prev;
if (head) last->next=NULL;
free(ptr);
}
}
int front() {return last->val;}
int bfs(int s, int d)//s == source and d == destination
{
int cnt=0;
push(s);
size++;
v[s]=1;
while (size)
{
int u=front();
pop();
size--;
for (int j=1; j<=2; j++)
{
if (d==g[u][j]) return (cnt+1);
if (!v[g[u][j]])
{
v[g[u][j]]=1;
size++;
push(g[u][j]);
}
}
cnt++;
}
}
int main()
{
int n, m, val;
scanf("%d%d", &n, &m);
if (n==m) {printf("0"); return 0;}
val=(n>m?n:m)*2;
v[0]=1;
for (int i=1; i<=val; i++)
{
g[i][1]=2*i;
g[i][2]=i-1;
}
printf("%d", bfs(n, m));
return 0;
}
You have implemented a stack i.e. LIFO (last in first out): you are adding to the end and retrieving from the end.
You should implement a queue i.e. FIFO (first in first out), so if you add to end, you should retrieve from front:
void pop()
{
if (size)
{
queue *ptr=head;
head=head->next;
if (head) head->prev=NULL;
free(ptr);
}
}
int front()
{
return head->val;
}
Also, I guess your aim is to count the smallest number of operations required to produce the desired number from a given one. Your cnt variable does not represent the smallest number of operations, it represents the number of times you retrieved an element from the queue. You need to increment it for each new level instead.
Finally, your bfs should return a value even if there is no path from s to d, so you should put return 0; after the while(size){} loop.
UPD. You need to skip g[u][j] if it is larger than 2 * (10^4) inside of bfs, otherwise those values be enqueued which is a waste of space. By the way your v array has only 2222 elements, it should have at least 20001 (v[20000] is the last one)
I'm a bit stuck on how to make a user defined function that would printout the output. I also have to make a user defined function that will add up the data in each node and print out the total but it's not adding up correctly and the format is a little off as well.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
char printout();
int sum();
typedef struct node
{
int number;
struct node*next;
} node;
char printout()
{
};
int sum()
{
int s,sum_all=0, node_sum=0;
for(s=0;s=100;s++)
{
sum_all=node_sum+s;
return printf("The sum of all nodes is %d.\n",sum_all);
};
};
int main()
{
srand (time(NULL));
int i, total=0;
struct node*head=malloc(sizeof(struct node));
head->number = rand()%100;
printf("Node #%d contains %d.\n", 0, head->number);
struct node*here=head;
for (i=1; i<100; i++)
{
here->next=malloc(sizeof(struct node));
here->number=rand()%100;
printf("Node #%d contains %d.\n", i, here->number);
};
total=sum(here->number);
printf("%2.2d", total);
return 0;
}
There is the litany of errors here, but let's just focus on the most important meat:
You should be pass the list's head to the function sum(), ie
sum(head); // This is how you call most linked list functions.
by which you should change the header to
int sum(struct node *head)
{ ... }
This is not an array. You should traverse the linked list correctly.
I can't show all the code for you, as this is what your professor wants you to learn.
But you should be using these
for( struct node*p = head; p!=NULL; p=p->next)
instead of these
for( s=0; s<=100; s++)
You also forgot to step forward in your malloc-and-fill-with-rand loop
here = here->next; // this does in linked lists what i++ does in arrays
and this
sum_all += p->number; // p->number is analogous to array[i]
instead of
sum_all = node_sum +s; // what are s and node_sum anyway?
Also, if you insist that sum return something,
It should return, well, the sum;
return sum_all;
And don't print it inside the function
printf("The sum of all nodes is %d.\n",sum_all); // please don't
Because you're already printing it outside.
total = sum(head);
printf("%2.2d", total);
Please try to think first what your code is going to accomplish instead of putting code blankly.
It will help you a lot. Good luck!
I m trying to unterstand the code below but there´s something not clear in DFS function
enter code here
#include<stdio.h>
typedef struct node
{
struct node *next;
int vertex;
}node;
node *G[20];
int visited[20];
int n;
void read_graph();
void insert(int,int);
void DFS(int);
void main()
{
int i;
read_graph();
//initialised visited to 0
for(i=0;i<n;i++)
visited[i]=0;
DFS(0);
}
void DFS(int i)
{
node *p;
printf("\n%d",i);
p=G[i];
visited[i]=1;
while(p!=NULL)
{
i=p->vertex;
if(!visited[i])
DFS(i);
p=p->next;
}
}
void read_graph()
{
int i,vi,vj,no_of_edges;
printf("Enter number of vertices:");
scanf("%d",&n);
//initialise G[] with a null
for(i=0;i<n;i++)
{
G[i]=NULL;
//read edges and insert them in G[]
printf("Enter number of edges:");
scanf("%d",&no_of_edges);
for(i=0;i<no_of_edges;i++)
{
printf("Enter an edge(u,v):");
scanf("%d%d",&vi,&vj);
insert(vi,vj);
}
}
}
void insert(int vi,int vj)
{
node *p,*q;
//acquire memory for the new node
q=(node*)malloc(sizeof(node));
q->vertex=vj;
q->next=NULL;
//insert the node in the linked list number vi
if(G[vi]==NULL)
G[vi]=q;
else
{
//go to end of the linked list
p=G[vi];
while(p->next!=NULL)
p=p->next;
p->next=q;
}
}
how does the backtracking happen after terminating the while loop in the function DFS() ? i don´t get it
Thx
Well, this is not a DFS (Depth First Search), as nothing is searched for. All that your DFS function does is traverse all edges, marking their nodes as visited. Once done, you only know if this is a connected graph - if there are any edges that have not been visited, then they have not been marked, and so cannot be reached from G[0].
the original code is not mine .. i just found it on this website : http://www.thecrazyprogrammer.com/2014/03/depth-first-search-dfs-traversal-of-a-graph.html
I am trying to do ascending order in linked list through change of links and addresses rather than value
struct node
{
char name[30];
int percent;
struct node *link;
};
int main
{
clrscr();
randomize();
struct node *st;
st=NULL;
for(int i=0;i<7;i++)
append(&st,random(101)); //Assigning random values to structure node->percent
display(st);
AscMarks(&st); //Changing the order of links and addresses to arrange them in ascending order
printf("\nAscending order list...\n");
display(st);
getch();
return 0;
}
/*Adds a node at the end of a linked list */
void append(struct node **q,int per)
{
struct node *temp,*r;
temp=*q;
/* If the list is empty , create first node */
if(temp==NULL)
{
temp=(node*)malloc(sizeof(struct node));
temp->percent=per;
getName(temp->name);
temp->link=NULL;
*q=temp;
}
else
{
while(temp->link!=NULL)
temp=temp->link;
r=(struct node*)malloc(sizeof(struct node));
r->percent=per;
getName(r->name);
r->link=NULL;
temp->link=r;
}
}
/*Displays the contents of the linked list */
void display(struct node *q)
{
while(q!=NULL)
{
printf("%d\t%s\n",q->percent,q->name);
q=q->link;
}
}
void getName(char *c)
{
for(int i=0;i<30;i++)
{
if(i==10||i==20)
*(c+i)=' ';
else
*(c+i)=(char)((random(26)+97));
}
*(c+i+1)='\0';
}
/*To change the links and addresses in order to arrange the percent in ascending order */
void AscMarks(struct node **q)
{
struct node *temp,*temp1,*r;
temp=*q;
// r=q;
for(int i=0;i<7;i++,temp=temp->link)
{ temp1=temp->link;
for(int j=i+1;j<7;j++,temp1=temp1->link)
{
if(temp->percent>temp1->percent)
{
r=*q;
while(r->link!=temp1)
{
r=r->link;
}
r->link=temp1->link;
temp1->link=temp;
temp=temp1;
}
}
if(i==0)
*q=temp;
}
temp->link=NULL;
/*
while(r!=NULL)
{
printf("\n%d",r->percent);
r=r->link;
} */
}
Ascending order (AscMarks) is not giving results as expected and I am unable to see what's my fault in the code Please help
You are not establishing link between the smallest address to the second smallest address and so on ... i have got that through node variable "*s"
by s->link=temp& giving the address of last sorted value (temp) to s..through s=temp.. And in "j" loop after each time , temp->percent> temp1->percent .. you have done temp1-link=temp, it makes the address of temp1, the address of starting temp... means in short ... the number of tries of "j" will be too less to compare all the addresses ... as most of it will repeat ...
so for it you should do j=i;
void AscMarks(struct node **q)
{
struct node *temp,*temp1,*r,*s;
temp=*q;
// r=q;
for(int i=0;i<7;i++,temp=temp->link)
{ temp1=temp->link;
for(int j=i+1;j<7;j++,temp1=temp1->link)
{
if(temp->percent>temp1->percent)
{
r=*q;
while(r->link!=temp1)
{
r=r->link;
}
r->link=temp1->link;
j=i;//resetting the value of j
temp1->link=temp;
temp=temp1;
if(i!=0)
s-link=temp; //establishing link between
//this sorted address(in this loop) to the
//last sorted address
}
}
if(i==0)
*q=temp;
s=temp;//giving it the address of structure which have the last
//sorted value
}
temp->link=NULL; //No need to do this
/*
while(r!=NULL)
{
printf("\n%d",r->percent);
r=r->link;
} */
}
I am having trouble with a project I am working on for class. I am particularly having trouble with recursively printing a linked list of spheres. Whenever the program runs over the particular part:
ss=ss->next;
there is a Segmentation fault: 11. What could the problem be?
(Note: I've included the necessary structssphereandsphere_list, and left outrgbandvec` so as to not clutter up the code.)
typedef struct sphere {
vec *center;
double radius;
rgb *color;
} sphere;
typedef struct sphere_list sphere_list;
/* convention: NULL is the empty sphere list */
struct sphere_list {
sphere *s;
sphere_list *next;
};
void sl_print(sphere_list *ss)
{
if(ss==NULL)
printf("SPHERE LIST EMPTY\n");
printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
printf("SPHERE LIST:\n");
int i=1;
while(ss->s!=NULL){
printf("\t%d ", i);
sphere_print(ss->s);
if(ss->next==NULL){
printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
return;
}
ss=ss->next;
i++;
}
printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
return;
}
try this:
void sl_print(sphere_list *ss)
{
if(ss==NULL){
printf("SPHERE LIST EMPTY\n");
printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
printf("SPHERE LIST:\n");
return ;
}
int i=1;
while(ss != NULL){
printf("\t%d ", i);
sphere_print(ss->s);
ss=ss->next;
i++;
}
}
struct sphere_list {
sphere *s;
sphere_list *next;
};
have you allocated space for sphere *s and made the pointer point to valid memory?, I would have done this, just a suggestion.
typedef struct sphere {
vec *center;
double radius;
rgb *color;
//included the pointer in the struct//
struct sphere *next
} sphere;
Also, typedef structs are not favoured by most people.makes the code harder to read.
You made an error in your loop conditions. You have to test next value, because this is why you move on on sphere_list.
void sl_print(sphere_list *ss)
{
sphere_list *tmp = ss;
if(ss==NULL)
printf("SPHERE LIST EMPTY\n");
printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
printf("SPHERE LIST:\n");
int i=1;
while(tmp!=NULL){
printf("\t%d ", i);
if (tmp->s != NULL)
sphere_print(tmp->s);
if(tmp->next==NULL){
printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
return;
}
tmp=tmp->next;
i++;
}
printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
return;
}
Modified*