Swapping linked list items issue C - c

i'm trying to invert the "info" field of the in a list like the one below
struct nodo {
int info;
struct nodo *next;
struct nodo *prev;
} ;
typedef struct nodo nodo;
Here is the main, the two output should be the original list of n mebmers, and the inverted list (First value go n , second n-1 and so on)
int main(int argc, const char * argv[]) {
struct nodo *p;
p = CreateList();
PrintList(p);
IvertList(p);
Printlist(p);
return 0;
}
Here is InvertList(): (Count() function just returns dimension of the list, i know it is a messy way but i'm focused on result for now)
void InvertList (struct nodo *p) {
int tmp = 0, num = 0, i = 0;
num = (Count(p));
tmp = num;
for (i=1; i!=tmp; i++) {
Swap(p,num);
num--;
}
}
And here is Swap(), this should bring a value (int info) to the first place of the list, to the last swapping with each:
void Swap (struct nodo *p, int n) {
int *tmp1 = NULL, *tmp2 = NULL;
int i;
for ( i = 1; i != n && p != NULL; i++) {
tmp1 = &p->info;
p = p->succ;
tmp2 = &p->info;
p->info = *tmp1;
p->prec->info = *tmp2;
}
}
Now the output i got printed is:
Value: 1
Value: 2
Value: 3
Value: 4
Value: 5
Value: 1
Value: 1
Value: 1
Value: 1
Value: 1
Where the last 5 values should be 5-4-3-2-1.

The bug(s) in your code not withstanding, you're not reversing your physical list at all, which I can all-but-guarantee is the point of the exercise in the first place.
Inversion of a linked list means all the pointers switch directions and the old tail becomes the new head. You seem to be avoiding that and trying to swap node info values instead.
To invert your list using simple pointer swapping:
// note head pointer passed by address
void InvertList(node **pp)
{
node *cur = *pp;
while (cur)
{
node *tmp = cur->prev;
cur->prev = cur->next;
cur->next = tmp;
*pp = cur;
cur = cur->prev;
}
}
And invoke from main() as:
InvertList(&p);
Note that no info values need be swapped, copied, etc. The node pointers simply switch direction and their enumeration will start at the other end. A full working example appears below:
#include<stdio.h>
#include<stdlib.h>
struct node
{
int info;
struct node *next;
struct node *prev;
};
typedef struct node node;
static void PrintList(const node *head)
{
while (head)
{
printf("%d: this=%p, prev=%p, next=%p\n",
head->info, head, head->prev, head->next);
head = head->next;
}
}
static void InvertList(node **pp)
{
node *cur = *pp;
while (cur)
{
node *tmp = cur->prev;
cur->prev = cur->next;
cur->next = tmp;
*pp = cur;
cur = cur->prev;
}
}
int main()
{
node *prev = NULL, *head = NULL, **pp = &head;
for (int i=1; i<=5; ++i)
{
*pp = malloc(sizeof **pp);
(*pp)->info = i;
(*pp)->prev = prev;
prev = *pp;
pp = &(*pp)->next;
}
*pp = NULL;
PrintList(head); // prints 1,2,3,4,5
InvertList(&head);
PrintList(head); // prints 5,4,3,2,1
}
Output (addresses vary, obviously)
1: this=0x1001054b0, prev=0x0, next=0x1001054d0
2: this=0x1001054d0, prev=0x1001054b0, next=0x1001054f0
3: this=0x1001054f0, prev=0x1001054d0, next=0x100105510
4: this=0x100105510, prev=0x1001054f0, next=0x100105530
5: this=0x100105530, prev=0x100105510, next=0x0
5: this=0x100105530, prev=0x0, next=0x100105510
4: this=0x100105510, prev=0x100105530, next=0x1001054f0
3: this=0x1001054f0, prev=0x100105510, next=0x1001054d0
2: this=0x1001054d0, prev=0x1001054f0, next=0x1001054b0
1: this=0x1001054b0, prev=0x1001054d0, next=0x0

There is a bug in your Swap fcn:
p->info = *tmp1;
p->prev->info = *tmp2;
But what are tmp1 and tmp2 at that time? Well, after we advanced p, tmp1 points at p->prev->info, while tmp2 = &p->info; So we could rewrite these assignments in effect as:
p->info = p->prev->info;
p->prev->info = p->info;
So, we could rewrite them again, in effect, as:
p->info = p->prev->info;
p->prev->info = p->prev->info;
So, the second assignment doesn't change anything in effect. Therefore, the first call to Swap in InvertList takes the value of the first element (1) and sets all the values in the list equal to it. The subsequent calls to Swap act similarly but have no effect as the list already contains all 1's.
Here's a simple way to rewrite Swap:
void Swap(struct nodo *p, int n)
{
if (n <= 1)
return;
int tmp = p->info;
for (int i = 1; i != n; ++i, p = p->next)
p->info = p->next->info;
p->info = tmp;
}
Note, however, that the way you've written InvertList is doing theta(n^2) work. The first loop iteration shifts the first element n-1 spots, the second iteration shifts the first element n-2 spots, the third iteration shifts the first element n-3 spots, and so on, down to shifting the first element 1 spot. So, you end up doing something like n * (n - 1) / 2 total shifts to reverse the list.
A linked list can be reversed / inverted in theta(n) work. See if you can figure out a better way to do this. If you had a pointer to both the beginning and the end of the list (which you often want anyway), then you could do something similar to reversing the characters in a string, for example.

Related

How to dynamically populate Linked List with Fibonacci series

I have a linked list, which I wanted to populate up to a certain loop number. I have my code below is shows a Fibonacci series using a C Linked list.
Here is my code without any loop:
#include <stdio.h>
#include <stdlib.h>
typedef struct Node
{
int count;
int fibo;
struct Node* next;
}node;
int
fibo(int val){
if(val == 1 || val == 2) {
return 1;
}
return fibo(val - 1) + fibo(val - 2);
}
int
main (void)
{
node f1, f2, f3;
f1.count = 1;
f1.fibo = fibo(1);
f2.count = 2;
f2.fibo = fibo(2);
f3.count = 3;
f3.fibo = fibo(3);
f1.next = &f2;
f2.next = &f3;
f3.next = NULL;
printf("f1 fibo : %i\n", f1.fibo);
printf("f2 fibo : %i\n", f2.fibo);
printf("f3 fibo : %i\n", f3.fibo);
return (0);
}
Now I want to do this via a loop. How would I do that?
For this answer, I'm going to ignore the computational efficiency concerns that arise from recomputing all of the Fibonacci numbers up to the given number you are retrieving with each call to fibo(n).
Linked lists are not usually "random access" data structures that let you access an arbitrary element with an index. When using a linked list with pointers, you only need to have the pointer to the head (first element) of the linked list. You then traverse the list starting at the head using a loop going through each next link. If a list is empty, your head is usually NULL.
You can apply this here. One way (there are several) is to define a function to allocate and set a single entry:
node *set_fibo(int n)
{
node *fibo_entry = malloc(sizeof(node));
if ( fibo_entry == NULL ) {
// error
}
fibo_entry->count = n;
fibo_entry->fibo = fibo(n);
fibo_entry->next = NULL;
return fibo_entry;
}
And then in your main:
node *fibo_list = NULL;
node *last_fibo = NULL;
// Assume n_fibo is the number of Fibonacci numbers you want to store in order
for ( int n = 1; n <= n_fibo; n++ ) {
if ( n == 1 )
fibo_list = last_fibo = set_fibo(1);
else {
last_fibo->next = set_fibo(n);
last_fibo = last_fibo->next;
}
}
Although the question has already been answered, I would like to add something regarding the efficiency aspect of your code. As pointed out before, you do not have to calculate the fibo value by starting from the beginning, since you saved the latest results in the singly linked list.
So given you have the following list 1-1-2-3-5-, you can easily calculate the fibo value of the new node by simply adding the fibo value of the two lates elements (i.e. 3 and 5). Hence the value of the fibo value of the new node should be 8.
Given the pointer to the second last element, this function will add add a new node to the list and set the correct fibo value:
void addNode(struct Node* node){
struct Node* n = malloc(sizeof(struct Node));
n->next = NULL;
n->count = node->next->count + 1;
n->fibo = node->fibo + node->next->fibo;
node->next->next = n;
}
In order to use this function, you have to create the first two nodes in the list:
struct Node* n2 = malloc(sizeof(struct Node));
n2->count = 2;
n2->fibo = 1;
n2->next = NULL;
struct Node* n1 = malloc(sizeof(struct Node));
n1->count = 1;
n1->fibo = 1;
n1->next = n2;
If you now want to add - lets say 10 - new nodes, you simply do:
struct Node* ptr = n1;
int i;
for(i=0; i<10;i++) {
addNode(ptr);
ptr = ptr->next;
}
If you now want to print the entries of all nodes in the list, simply iterate over the list until you reach NULL.
ptr = n1;
while(ptr != NULL) {
printf("fib(%d) = %d\n ", ptr->count, ptr->fibo);
ptr = ptr->next;
}
Please keep in mind, that you have to manually free dynamically allocated items!
In your example, the nodes are automatic variables in main. They are not dynamically allocated and they live as long as you don't return from main. You can extend this concept with a automatic array of nodes:
#include <stdio.h>
#include <stdlib.h
typedef struct Node Node;
struct Node {
int count;
int fibo;
Node* next;
};
#define N 30
int main (void)
{
Node fibo[N];
Node *head = NULL;
Node **p = &head;
int f1 = 0;
int f2 = 0;
for (size_t i = 0; i < N; i++) {
Node *nd = &fibo[i];
nd->count = i + 1;
nd->fibo = f2 + f1 ? f2 + f1 : 1;
f1 = f2;
f2 = nd->fibo;
*p = nd;
p = &(*p)->next;
}
*p = NULL;
Node *nd = head;
while (nd) {
printf("fib(%d) == %d\n", nd->count, nd->fibo);
nd = nd->next;
}
return (0);
}
It's not clear, though, why you need the Fibonacci series as linked list. Also, a word of warning: Don't mix nodes on the stack (like here) and nodes on the heap (as in lurker's answer) in a list. This answer just extends your answer to many nodes, whereas lurker's answer shows a more general concept of linked lists.
Here is how I think you can do it. You can use an array for the nodes.
node f[3];
int i;
for ( i = 0 ; i < 3 ; i++ )
{
f[i].count = i+1;
f[i].fibo = fibo (i+1);
if ( i == 2 )
{
f[i].next = NULL;
}
else
{
f[i].next = &f[i+1];
}
}

Split linked list into half

I am trying to create a function splitlist(), which will split a singly linked list into two sublists – one for the front half, and one for the back half. I have come up with a code below which will work for the first time that I call the function, but when I call the function repeatedly, the program crashes. Any advice on how I can change my code to prevent such an error? The function splitlist() is void as it prints two lists which contains frontList and backList.
typedef struct _listnode {
int item;
struct _listnode *next;
} ListNode;
typedef struct _linkedlist {
int size;
ListNode *head;
} LinkedList;
void splitlist(LinkedList* list1, LinkedList * firsthalf, LinkedList *secondhalf)
{
ListNode *cur = list1->head;
ListNode *front = firsthalf->head;
ListNode *back = secondhalf->head;
int totalnodes = list1->size;
int i;
if (totalnodes % 2 != 0) //if odd number of elements, add 1 to make it easier for traversal of list
{
totalnodes = totalnodes + 1;
}
int halfnodes = totalnodes / 2;
{
for (i = 0; i < halfnodes; i++)
{
if (firsthalf->head == NULL) //initialise the head
{
firsthalf->head = malloc(sizeof(ListNode)); //create first node
front = firsthalf->head;
}
else
{
front->next = malloc(sizeof(ListNode));
front = front->next;
}
front->item = cur->item; // insert value from list1 into firsthalf
cur = cur->next; //point to next node in list1
}
front->next = NULL; //last node
for (i = halfnodes; i < totalnodes; i++)
{
if (secondhalf->head == NULL)
{
secondhalf->head = malloc(sizeof(ListNode));
back = secondhalf->head;
}
else
{
back->next = malloc(sizeof(ListNode));
back = back->next;
}
back->item = cur->item;
cur = cur->next;
}
back->next = NULL;
}
}
There are many things wrong with this code. First of all malloc return values are not checked, malloc can fail. And i strongly suspect that because of malloc fail your programm stops. You repeatedly allocate the memory inside the function, but do you free it when you do not need it anymore? Why do yo use malloc at all?
As posted earlier you do not need to.
Please post how the function is called, because it is really unclear how LinkedList* list1, LinkedList * firsthalf, LinkedList *secondhalf are used. Also it is unclear what is the structure of LinkedList is.
why use malloc?It will create a new list.But we want to split the list.
I guess firsthalf and second half are NULL
void splitlist(LinkedList* list1, LinkedList * firsthalf, LinkedList *secondhalf)
{
ListNode *cur = list1->head;
ListNode *front;
int totalnodes = list1->size;
int i;
if (totalnodes % 2 != 0) //if odd number of elements, add 1 to make it easier for traversal of list
{
totalnodes = totalnodes + 1;
}
int halfnodes = totalnodes / 2;
firsthalf->head=list1->head;
front=firsthalf->head;
for(i=0;i<halfnode;i++)
front=front->next;
secondhalf->head=front->next;
front->next=NULL;
}
At first glance I can't see much wrong with your code (assuming the assignment is to create copies of the list nodes in the new half lists), so the error could be in how you call the function, as an exmple, that could be:
LinkedList mainlist= {0};
LinkedList firsthalf= {0}, secondhalf= {0};
//mainlist got filled somehow; we now want to split
firsthalf->List= malloc(sizeof(ListNode));
secondthalf->List= malloc(sizeof(ListNode));
memset(firsthalf->List, 0, sizeof(ListNode));
memset(secondhalf->List, 0, sizeof(ListNode));
splitlist(&mainlist, &firsthalf, &secondhalf);

Cycle through List and Ordering

I want to create a linked list.
The user adds numbers and the idea is that the numbers are inserted to the list in descending order.
Here goes what I did, but when rearranging, it just orders the first number...
int addInputNumber(numberList **node){
numberList *temp;
int userInput;
temp = (numberList*)malloc(sizeof(numberList));
//Memory Check
if ( temp == 0 )//out of memory, return 0
return 0;
//Get the users input
printf("Give me a Number!\n");
scanf("%d",&userInput);
//Add it to the list.
temp->numbero = userInput;
///Link to the list.
temp->next = *node;
*node = temp;
//Lets cycle through the list.
numberList *temp2;
int helpNumber;
temp2 = *node;
//Rearrange the list.
while(temp2 != 0){
if(temp->numbero < temp2->numbero){
//Switch position..
helpNumber= temp2->numbero;
temp2->numbero = temp->numbero;
temp->numbero = helpNumber;
temp2 = *node;// If we change number, we must cycle from the beginning AGAIN.
}//eof if
temp2 = temp2->next;
}//eof while
return 0;
}//eof addNUmber function.
Here's the structure just in case:
typedef struct dynamicNumberList {
int numbero;
struct dynamicNumberList *next;
}numberList;
I've got 2 quick questions.
Why would it only arrange the first number?
This list adds a space towards the left (visually), how could I make it so I can add a space to the right?
You need to get into the habit of creating one function per task, instead of cramming everything into a single one. It makes the code easier to read and reuse and reduces the chance of errors.
A correct implementation could look like this:
#include <stdio.h>
#include <stdlib.h>
typedef struct s_List
{
int n;
struct s_List *next;
} List;
void print_list (List *head)
{
List *ptr;
for (ptr = head; ptr; ptr = ptr->next) {
printf ("%d\t", ptr->n);
}
putchar ('\n');
}
List * make_node (int n, List *next)
{
List * node = malloc (sizeof(List));
node->n = n;
node->next = next;
return node;
}
void insert_number_front (List **head, int n)
{
*head = make_node (n, *head);
}
void insert_number_after (List *prev, int n)
{
prev->next = make_node (n, prev->next);
}
// If HEAD is sorted, it will stay sorted after insertion
void insert_number_sorted (List **head, int n)
{
List *ptr;
List *ptr2;
// search for the rightmost node whose number is smaller than n.
ptr2 = NULL;
for (ptr = *head; ptr; ptr = ptr->next) {
if (ptr->n >= n)
break;
ptr2 = ptr;
}
// If such a node exists we insert the new node after it,
// otherwise we insert it at the front of the list.
if (ptr2) {
insert_number_after (ptr2, n);
}
else {
insert_number_front (head, n);
}
}
int input_number ()
{
int n;
printf ("enter a number: ");
scanf ("%d", &n);
return n;
}
int main ()
{
List *head = NULL;
int i;
// By adding elements exclusively with insert_number_sorted()
// we ensure the list is always sorted
for (i = 0; i < 5; i++) {
int n;
n = input_number ();
insert_number_sorted (&head, n);
}
print_list (head);
return 0;
}
To answer your second question, what you have here is a singly linked list, which can be described by a pointer to the first node. If you want to be able to insert nodes at the back you need to maintain an additional pointer to the last node. However this is not necessary in this case.

Write a function that rearranges a linked list to put the nodes in even positions after the nodes in odd positions in the list

Write a function that rearranges a linked list to put the nodes in even positions after the nodes in odd positions in the list, preserving the relative order of both the evens and the odds.
I found this problem in the book Algorithm in c writtern by Sedgewick. I have tried but failed. I trid to put all nodes in even positions on another linked list. It's grateful for you to help me. A good idea is enough. Thanks :).
This is my Code in C.
/*
* File: rearranges.c <Exercise 3.36>
* Note: Write a function that rearranges a linked list to put the nodes in even
* positions after the nodes in odd positions in the list, preserving the
* relative order of both the evens and the odds.
* NOTICE: I think it's necessary to use linked list with a dummy head.
* Time: 2013-10-26 10:58
*/
#include <stdio.h>
#include <stdlib.h>
#define LEN 11
typedef struct node *link;
struct node {
int item;
link next;
};
/* Traverse a linked list with a dummy head. */
void traverse(link t) {
link x = t->next;
while (x != NULL) {
printf("%d ", x->item);
x = x->next;
}
putchar('\n');
}
/* Detach even positon nodes from a linked list. */
link detach(link t) {
link u = malloc(sizeof(*u));
link x = t, y = u;
/* x is odd position node. We should ensure that there's still one even
* position node after x. */
while (x != NULL && x->next != NULL) {
y->next = x->next;
x->next = x->next->next;
x = x->next;
y = y->next;
y->next = NULL;
}
return u;
}
/* Combine two linked list */
link combine(link u, link t) {
link x = u;
link y = t->next;
while (y != NULL) {
link n = y->next;
y->next = x->next;
x->next = y;
x = x->next->next;
y = n;
}
return u;
}
/* The function exchanges the position of the nodes in the list. */
link rearranges(link t) {
link u = detach(t);
link v = combine(u, t);
return v;
}
int main(int argc, char *argv[]) {
int i;
link t = malloc(sizeof(*t));
link x = t;
for (i = 0; i < LEN; i++) {
x->next = malloc(sizeof(*x));
x = x->next;
x->item = i;
x->next = NULL;
}
traverse(t);
traverse(rearranges(t));
return 0;
}
curr=head;
end=lastOfList;//last node if size of list is odd or last-1 node
for(int i=1;i<=listSize()/2;i++)
{
end->next=curr->next;
end=end->next;
end->next=null;
if(curr->next!=null)
if((curr->next)->next!=null)
curr->next=(curr->next)->next;
curr=curr->next;
}
You can implement a recursive solution where each call returns an updated node that will serve as the new next reference for the upper caller. We just have to go down the list until we find the last element, and then move every even node to the end of the list, and update the reference to the last element. Here's my solution (please try to do it yourself before looking at my and other solutions):
struct node {
int val;
struct node *next;
};
struct node *reorder_aux(struct node *l, int count, struct node **last);
struct node *reorder(struct node *l) {
struct node *x;
if (l == NULL)
return NULL;
return reorder_aux(l, 1, &x);
}
struct node *reorder_aux(struct node *l, int count, struct node **last) {
struct node *n;
if (l->next == NULL) {
*last = l;
return l;
}
n = reorder_aux(l->next, count+1, last);
if (count & 1) {
l->next = n;
return l;
}
else {
(*last)->next = l;
l->next = NULL;
*last = l;
return n;
}
}
At each step, if the current node l is an even node (as determined by count), then we append this node to the end, and tell the upper caller that its next pointer shall be updated to our next (because our next will be an odd node). In case we're an odd node, we just have to update our next pointer to whatever the recursive call returned (which will be a pointer to an odd node), and return the current node, since we will not move ourselves to the end of the list.
It's a nice exercise!
#include <stdio.h>
struct list {
struct list *next;
int ch;
};
void swap_odd_even (struct list **pp)
{
struct list *one, *two ;
for( ; (one = *pp) ; pp = &one->next) {
two = one->next;
if (!two) break;
*pp = two;
one->next = two->next;
two->next = one;
}
}
struct list arr[] =
{ {arr+1, 'A'} , {arr+2, 'B'} , {arr+3, 'C'} , {arr+4, 'D'}
, {arr+5, 'E'} , {arr+6, 'F'} , {arr+7, 'G'} , {arr+8, 'H'}
, {arr+9, 'I'} , {arr+10, 'J'} , {arr+11, 'K'} , {arr+12, 'L'}
, {arr+13, 'M'} , {arr+14, 'N'}, {arr+15, 'O'} , {arr+16, 'P'}
, {arr+17, 'Q'} , {arr+18, 'R'} , {arr+19, 'S'} , {arr+20, 'T'}
, {arr+21, 'U'} , {arr+22, 'V'}, {arr+23, 'W'} , {arr+24, 'X'}
, {arr+25, 'Y'} , {NULL, 'Z'} };
int main (void) {
struct list *root , *ptr;
root = arr;
for (ptr=root ; ptr; ptr = ptr->next ) {
printf( "-> %c" , ptr->ch );
}
printf( "\n" );
printf( "Swap\n" );
swap_odd_even ( &root);
for (ptr=root ; ptr; ptr = ptr->next ) {
printf( "-> %c" , ptr->ch );
}
printf( "\n" );
return 0;
}
In the following, every time swap_nodes is called another odd sinks to the last sunk odd. The evens are grouped together on each iteration and they bubble up to the end of the list. Here is an example:
/*
[0]-1-2-3-4-5
1-[0-2]-3-4-5
1-3-[0-2-4]-5
1-3-5-[0-2-4]
*/
#include <stdio.h>
#include <stdlib.h>
#define LIST_LENGTH 10
struct node{
int id;
struct node *next;
};
void print_list(struct node *current)
{
while(NULL != current){
printf("node id = %d\n",current->id);
current = current->next;
}
printf("Done\n");
}
struct node *swap_nodes(struct node *head_even, struct node *tail_even, struct node *next_odd)
{
tail_even->next = next_odd->next;
next_odd->next = head_even;
return next_odd;
}
struct node *reorder_list(struct node *head)
{
struct node *head_even;
struct node *tail_even;
struct node *next_odd;
struct node *last_odd;
if(NULL == head->next){
return head;
}
head_even = head;
tail_even = head;
next_odd = head->next;
last_odd = head->next;
head = swap_nodes(head_even, tail_even, next_odd);
if(NULL != tail_even->next){
tail_even = tail_even->next;
}
while (NULL != tail_even->next) {
next_odd = tail_even->next;
last_odd->next = swap_nodes(head_even, tail_even, next_odd);
last_odd = last_odd->next;
if(NULL != tail_even->next){
tail_even = tail_even->next;
}
}
return head;
}
int main(void)
{
int i;
struct node *head = (struct node *) malloc(LIST_LENGTH*sizeof(struct node));
struct node *mem = head;
if(NULL == head){
return -1;
}
struct node *current = head;
for(i=0;i<LIST_LENGTH-1;i++){
current->next = current + 1;
current->id = i;
current = current->next;
}
current->next = NULL;
current->id = i;
head = reorder_list(head);
print_list(head);
free(mem);
return 0;
}

Circular linked list going in infinite loop

I am supposed to do a program which can do polynomial addition/subtraction/multiplication/evaluation using circular linked list.
My multiplication code is going in infinite loop, and I have marked a comment where it is happening (detected with printf statements, removed).
list* poly_mul(list *p1, list *p2) {
term tmp;
list *result = malloc(sizeof(list));
memcpy(result, p1, sizeof(list));
node *b = p2->head;
node *r = result->head;
do {
do {
tmp.exp = r->data.exp + b->data.exp;
tmp.coeff = r->data.coeff * b->data.coeff;
unsigned int add_term = 1;
node *c = result->head;
do {
if(c->data.exp == tmp.exp) {
c->data.coeff += tmp.coeff;
add_term = 0;
break;
}
c = c->next;
//Here it goes in infinite loop
} while(c != result->head);
if(add_term)
node_add(result, &tmp);
b = b->next;
} while(b != p2->head);
r = r->next;
} while(r != result->head);
return result;
}
The structures used are here:
typedef struct {
int exp;
int coeff;
} term;
typedef struct node {
term data;
struct node *next;
} node;
typedef struct {
node *head;
node *tail;
unsigned int count;
} list;
And this is the code in main:
void main() {
list p1, p2, *p3;
p1.count = p2.count = 0;
poly_create(&p1);
p3 = poly_mul(&p1, &p2);
poly_print(p3);
}
void poly_create(list *l) {
int i, n;
printf("\nEnter number of terms in the polynomial: ");
scanf("%d", &n);
for(i = 1; i <= n; i++) {
printf("\nEnter details for term %d: ", i);
term_append(l);
}
void node_add(list *l, term *t) {
node *tmp = malloc(sizeof(node));
memcpy(&tmp->data, t, sizeof(term));
if(l->count == 0) {
l->head = tmp;
l->tail = tmp;
tmp->next = tmp;
}
else {
l->tail->next = tmp;
tmp->next = l->head;
l->tail = tmp;
}
l->count++;
}
void term_append(list *l) {
term t;
enter:
printf("\nEnter term as <coefficient>,<exponent>: ");
scanf("%d,%d", &t.coeff, &t.exp);
if(!t.coeff) {
printf("\nCoefficient is zero, reenter term");
goto enter;
}
if(l->count >= 1) {
node *i = l->head;
do {
if(i->data.exp == t.exp) {
printf("\nExponent %d was already entered, reenter term", t.exp);
goto enter;
}
i = i->next;
} while(i != l->head);
node_add(l, &t);
}
else
node_add(l, &t);
}
Please get me a solution for this problem, I've been trying to solve this for the past three hours.
Why is it going into an infinite loop? You can find out by using a debugger and stepping through the code. Just put a breakpoint at the appropriate place and you should be able to find it yourself. In all likelihood, you have a loop in your linked list.
You can check for loops in your linked list with two pointers. The first one (tail) point to the start of your list. The second (head) points to the second element of your list. Loop till head is past the last element (I have those pointed to NULL, not head) by incrementing both head and tail by one. If at any point tail > head, you have a loop.
What happens if you printf("%d",(int) c); at each iteration? I suspect that result->head is pointing to a node which is pointing to a member of the linked list, but is not in the linked list itself.
Potential test: Add a int seen to each member of the list and increment it on each member as you loop for a given number of nodes (something excessively high such as INT_MAX) and, when the loop stops, see if result->head->seen > 0:
typedef struct node {
term data;
struct node *next;
// to be removed later
int seen;
} node;
// place this before you get the infinite loop
unsigned int i = 1;
c->seen = 0;
do
{
c = c->next;
c->seen = i;
// replace INT_MAX with some number which is greater than the maximum list length
} while(++i <= INT_MAX);
// this should be roughly equal to i (might be off by 1).
// I'll bet it isn't though!
printf("result->head->seen = %d", result->head->seen);
One possible cause: you're never creating p2. Are you missing a line like this in your main function:
poly_create(&p2);
?

Resources