Im trying to write a program in c that adds big numbers with linked list. I used reverse to add the numbers, but i cant get it to reverse again. It should be used several times(iow, looped to ask numbers until exit)
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "function.c"
int main()
{
char n1[500];
int lenSum, len;
printf("Welcome! \nThis program performs addition of big whole numbers that can contain upto a maximum of 500 digits.");
printf("\nEnter first number: ");
scanf("%s", n1);
len = strlen(n1);
node *root = create(n1[0]);
node *head = root;
root, head = createList(n1,root,head,len);
root=head;
printf("Enter second number: ");
scanf("%s", n1);
len = strlen(n1);
node *root2 = create(n1[0]);
node *head2 = root2;
root2, head2 = createList(n1,root2,head2,len);
root2=head2;
root=head;
printf("\nYour first number is:\t ");
while(root!=NULL){
printf("%d\t",root->digit);
root=root->next;
}
root2=head2;
printf("\nYour second number is: ");
while(root2!=NULL){
printf("%d\t",root2->digit);
root2=root2->next;
}
printf("\nCalculating sum:\n");
root=head;
root2=head2;
node *sum = create('0');
node *headSum = sum;
sum,headSum = addIntegers(root, root2, sum, headSum);
printf("\nThe sum is : ");
sum=headSum;
while(sum->next!=NULL){
printf("%d",sum->digit);
sum=sum->next;
}
printf("\n");
sum = headSum;
printf("\nThe number ");
saveResult(sum);
printf("has been saved in the file 'results.txt'\n");
root, head = reverseLinkedList(sum, headSum);
printDigit(root);
root=head;
printf("\n\n\t ");
while(root!=NULL){
printf("%d\t",root->digit);
root=root->next;
}
free(root);
free(root2);
//free(sumDigit);//
return 0;
}
function.h:
#ifndef function.h
#define function.h
typedef struct node {
int digit;
struct node *next;
}node;
node* create(char digit);
node* createList(char number[500], node* root,node* head, int length);
node* addIntegers(node* root, node* root2, node* sum, node* headSum);
#endif
function.c:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "function.h"
node* createList(char number[500], node* root,node* head, int length){
int i;
i=0;
for(i=1;i<=length-1;i++) {
root = (node *)malloc(sizeof(node));
root->digit = number[i]-'0';
root->next = head;
head = root;
}
return root, head;
}
void printDigit(node* root){
while(root!=NULL){
printf("%d",root->digit);
root=root->next;
}
}
node* addIntegers(node* root, node* root2, node* sum, node* headSum){
int carry = 0;
int sumDigit = 0;
while((root!=NULL || root2!=NULL)) {
if (root==NULL || root2==NULL){
if (root == NULL){
sumDigit=root2->digit +carry;
root2=root2->next;
goto add;}
if (root2 == NULL){
sumDigit = root->digit + carry;
root=root->next;
goto add;
}
}
else{
sumDigit = root->digit + root2-> digit + carry;
}
root2 = root2->next;
root = root->next;
add:
sum = (node *)malloc(sizeof(node));
sum->digit = sumDigit%10;
sum->next = headSum;
headSum = sum;
if (sumDigit > 9){
carry = 1;}
else{
carry = 0;
}
}
if (carry == 1){
sum = (node *)malloc(sizeof(node));
sum->digit = 1;
sum->next = headSum;
headSum = sum;
}
return sum, headSum;
}
node* create(char digit)
{
node *root = (node *) malloc( sizeof(node));
if (root == NULL){
printf("ERROR\n");
exit(1);
}
root->digit = digit-'0';
root->next = NULL; //default is null
return root;
}
void saveResult(struct node *sum)
{
FILE * fp = fopen ("result.txt", "w+");
while(sum->next != NULL)
{
printf("%d", sum->digit);
fprintf(fp, "%d", sum->digit);
sum = sum->next;
}
fclose(fp);
printf(" ");
}
node* reverseLinkedList(node *root, node* head){
node* reversed = create(root->digit);
node* reversedTail = reversed;
while(root!=NULL){
//printf("%d", root->digit);
root = root->next;
reversed->digit = root;
reversed->next =head->next;
reversed = reversed->next;
head = root;
}
reversed = reversedTail;
return reversed, reversedTail;
}
As the question is not very specific with the issue you're are facing, below are some points to be taken care,
In function reverse(),
return reversed, reversedTail; will always return reversedTail.
You are trying to call this function from main() as
root, head = reverseLinkedList(sum, headSum); which again head will get the return values. This is incorrect. Usually you should be using a assignment to one member at a time.
link list reverse sample like this
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int digit;
struct node *next;
} node;
node *reverse_copy(node *list){
node *new_list = NULL;
while(list){
node *new_node = malloc(sizeof(node));
new_node->digit = list->digit;
new_node->next = new_list;
new_list = new_node;
list = list->next;
}
return new_list;
}
void reverse_not_copy(node **header){
node *tmp, *list, *newList = NULL;
if (header==NULL || *header == NULL) return;
list = *header;
while(list != NULL){
tmp = list;
list = list->next;
tmp->next = newList;
newList = tmp;
}
*header = newList;
}
void print(node *head){
while(head){
printf("%d ", head->digit);
head = head->next;
}
printf("\n");
}
int main(void){
node *np;
node n[3] = { {1,NULL}, {2, NULL}, {3, NULL}};
n[0].next = &n[1];
n[1].next = &n[2];
print(&n[0]);//1 2 3
np=reverse_copy(&n[0]);
print(np);//3 2 1
reverse_not_copy(&np);
print(np);//1 2 3
return 0;
}
Related
I am a beginner to C and am learning linked lists. I tried making functions to have everything organised but no matter what i do the function print_list doesn't print the values. The output is only START and END. I noticed that if I put the same block of code directly into the function that builds the lists, then it prints correctly. What am I doing wrong? (Also first time asking on stack overflow)
Thank you to whoever answers.
#include <stdlib.h>
#include <stdio.h>
typedef struct nd
{
int val;
struct nd *next;
} node;
typedef node * Lista;
void print_list(node*currnode)
{
printf("START -> ");
while (currnode != NULL)
{
printf("%d -> ", currnode->val);
currnode = currnode->next;
}
printf("END");
}
//reimpilista means "buildlist"
node*riempilista(Lista lis){
node *currentNode, *temp;
int i,n;
printf("how many nodes?\n");
scanf("%d",&n);
for (i = 0; i < n; i++)
{
currentNode = (node *)malloc(sizeof(node));
printf("Enter element %d : ", (i + 1));
scanf("%d", ¤tNode->val);
if (i == 0)
{
temp = currentNode;
}
else
{
temp->next = currentNode;
temp = currentNode;
}
}
temp->next = NULL;
return lis;
}
int main(){
Lista listautente=NULL;
listautente=riempilista(listautente);
print_list(listautente);
return 0;
}
When you build the list you need to return the head of the list as a result. So you need to store the pointer to the first node. Then when adding a new node you need to know the previous node, so you need to store it as well. The last added node should have next field poiting to NULL otherwise you won't be able to determine the end of the list and will get an exception.
Here is your code slightly edited.
#include <stdlib.h>
#include <stdio.h>
typedef struct nd {
int val;
struct nd *next;
} node;
typedef node *Lista;
void print_list(node *currnode) {
printf("START -> ");
while (currnode != NULL) {
printf("%d -> ", currnode->val);
currnode = currnode->next;
}
printf("END");
}
//reimpilista means "buildlist"
node *riempilista() {
node *firstNode = NULL, *currentNode = NULL, *previousNode = NULL;
int i, n;
printf("how many nodes?\n");
scanf("%d", &n);
for (i = 0; i < n; ++i) {
currentNode = (node *)malloc(sizeof(node));
printf("Enter element %d : ", (i + 1));
scanf("%d", ¤tNode->val);
currentNode->next = NULL;
if (i == 0) {
firstNode = currentNode;
}
if (previousNode != NULL) {
previousNode->next = currentNode;
}
previousNode = currentNode;
}
return firstNode;
}
int main() {
Lista listautente = riempilista();
print_list(listautente);
return 0;
}
I tried to fix your program with minimal changes. Here it is:
Change
node *currentNode, *temp;
to
node *currentNode, *temp, *head;
Change
temp = currentNode;
to
temp = currentNode; head = temp;
Change
return lis;
to
return head;
Here is the link to the modified code:
https://onlinegdb.com/8cjqifgl2
I want an array of linked List and obviously each linked should have separate head node. Initially, as an example, I am starting with one array element. I am storing linkedlist into current[0] . But it is giving segmentation fault. If I use Node *current it will create a list and working fine. But, I want to store the list within array. What is wrong with the code ?
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
int data;
struct Node *next;
} Node;
Node *current[20];
void insert_beg_of_list(Node *current[0], int data);
void print_list(Node *current[0]);
void insert_beg_of_list(Node *current[0], int data) {
//keep track of first node
Node *head = current[0];
while(current[0]->next != head) {
current[0] = current[0]->next;
}
current[0]->next = (Node*)malloc(sizeof(Node));
current[0] = current[0]->next;
current[0]->data = data;
current[0]->next = head;
}
void print_list(Node *current[0]) {
Node *head = current[0];
current[0] = current[0]->next;
while(current[0] != head){
printf(" %d ", current[0]->data);
current[0] = current[0]->next;
}
}
int main() {
Node *head = (Node *)malloc(sizeof(Node));
head->next = head;
int data = 0 ;
int usr_input = 0;
int i;
int m;
int j;
scanf("%d", &usr_input);
for (i=0; i<usr_input; i++) {
scanf("%d", &data);
insert_beg_of_list(head, data);
}
printf("The list is ");
print_list(head);
printf("\n\n");
return 0;
}
I think you have mixed the global array current's use. Change your code to this :
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
int data;
struct Node *next;
} Node;
void insert_beg_of_list(Node *current, int data);
void print_list(Node *current);
void insert_beg_of_list(Node *current, int data) {
//keep track of first node
Node *head = current;
while(current->next != head) {
current = current[0]->next;
}
current->next = malloc(sizeof(Node));
if (current->next == NULL)
return;
current = current->next;
current->data = data;
current->next = head;
}
void print_list(Node *current) {
Node *head = current;
current = current->next;
while(current != head){
printf(" %d ", current->data);
current = current->next;
}
}
int main() {
Node *current[20];
Node *head = malloc(sizeof(Node));
if (head == NULL)
return;
head->next = head;
int data = 0 ;
int usr_input = 0;
int i;
int m;
int j;
scanf("%d", &usr_input);
for (i = 0; i < usr_input; i++) {
scanf("%d", &data);
insert_beg_of_list(head, data);
}
//assign the newly created pointer to a place in the array
current[0] = head;
printf("The list is ");
print_list(head);
printf("\n\n");
return 0;
}
Keep in mind that the parameter current in your functions' prototypes and declarations is not the same as the array current created in your main function. I just left the name as it was.
NOTE : You should do something with head->next pointer, initialize it.
Also read this link on why not to cast the result of malloc and another one on why you should check its result.
You probably want this:
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
int data;
struct Node *next;
} Node;
void insert_beg_of_list(Node *current, int data);
void print_list(Node *current);
void insert_beg_of_list(Node *current, int data) {
//keep track of first node
Node *head = current;
while (current->next != head) {
current = current->next;
}
current->next = (Node*)malloc(sizeof(Node));
current = current->next;
current->data = data;
current->next = head;
}
void print_list(Node *current) {
Node *head = current;
current = current->next;
while (current != head) {
printf(" %d ", current->data);
current = current->next;
}
}
Node *NewList()
{
Node *newnode = (Node *)malloc(sizeof(Node));
newnode->next = newnode;
}
int main() {
Node *arrayofheads[20];
// We are using only arrayofheads[0] in this example
arrayofheads[0] = NewList();
int data = 0;
int usr_input = 0;
int i;
scanf("%d", &usr_input);
for (i = 0; i<usr_input; i++) {
scanf("%d", &data);
insert_beg_of_list(arrayofheads[0], data);
}
printf("The list is ");
print_list(arrayofheads[0]); printf("\n\n");
return 0;
}
The program is supposed to take a user entered integer and convert it into binary through a stack of singly linked lists. I think it's either my toBin() function or my printStack() function that's causing the infinite loop.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
typedef struct node_def node;
struct node_def
{
int val;
node *next;
};
node *head;
void push(int val);
void pop(node *head);
int top();
void printStack();
int toBin(int val);
int main()
{
int num = 0;
printf("Enter an integer: ");
scanf("%d", &num);
push(num);
toBin(num);
printStack();
return 0;
}
void push(int val)
{
node *new;
new = malloc(sizeof(node));
if (head == NULL)
{
head = malloc(sizeof(node));
head->next = NULL;
head->val = val;
}
else
{
new->next = head;
new->val = val;
head = new;
}
return;
}
void pop(node *head)
{
node *tmp;
if(head == NULL)
{
printf("Stack is Empty\n");
return;
}
else
{
tmp = head;
head = head->next;
free(tmp);
}
return;
}
int top()
{
return(head->val);
}
void printStack()
{
node *tmp;
tmp = head;
if(head == NULL)
{
return;
}
while(head != NULL)
{
printf("%d ", head->val);
head = head->next;
}
printf("\n");
return;
}
int toBin(int val)
{
pop(head);
int i = 1, remainder, binary;
while(val != 0)
{
remainder = val % 2;
binary = binary + remainder * i;
val = val / 2;
i = i * 10;
push(binary);
}
return val;
}
You run into an infinite loop due to not properly initialising your variables. In particular, you have no guarantees that your node* head will be initialised to NULL, or that your int variables in toBin() will be initialised to zero.
Always, always, always initialise your variables when programming in C/C++.
Fixing these bugs and removing unused code leaves us with:
#include <stdio.h>
#include <stdlib.h>
typedef struct node_def node;
struct node_def
{
int val;
node *next;
};
/* Note that we are initialising the global variable to NULL. */
node *head = NULL;
void push(int val);
void printStack();
int toBin(int val);
int main()
{
int num = 0;
printf("Enter an integer: ");
scanf("%d", &num);
/* Removed push(num), as you're using parameters in the following call: */
toBin(num);
printStack();
return 0;
}
/* Changed printStack to use a tmp pointer to
traverse the stack without mutating it */
void printStack()
{
node* tmp = head;
while(tmp != NULL)
{
printf("%d ", tmp->val);
tmp = tmp->next;
}
printf("\n");
return;
}
int toBin(int val)
{
/* Removed pop() as you're getting val from parameters */
/* Also initialising remainder and binary variables */
int i = 1, remainder = 0, binary = 0;
while(val != 0)
{
remainder = val % 2;
binary = binary + remainder * i;
val = val / 2;
i = i * 10;
push(binary);
}
return val;
}
/* It's a stack so no if's are necessary for pushing */
void push(int val)
{
node *new = malloc(sizeof(node));
new->val = val;
new->next = head;
head = new;
return;
}
The program runs fine and displays the data I want but then crashes. I don't think it is a memory leak from the linked list because I've tried many ways to free it and none have worked.
#include "Buildings.h"
void displayBuilding(struct node *x){
printf("Building Name: %s\n\tFloors: %d\n\tValue: %d\n\n", x->payload.name, x->payload.floors, x->payload.value);
if(x->last!=1){
displayBuilding(x->next);
}
}
void insert(struct node *x, char str[50]){
srand(t);
int f = (rand() % 6)+1;
int v = ((rand() % 20)+1)*f;
//printf("Floors: %d and Value: %d\n", f, v);
strcpy(x->payload.name, str);
x->payload.floors = f;
x->payload.value = v;
srand(time(NULL));
t+=f+v*(rand()%1000);
}
FILE* openData(FILE *f){
f = fopen("Buildings-Data.txt", "r");
if(f==NULL){
printf("No File!");
return 0;
}
return f;
}
void freeList(struct node* head)
{
struct node* tmp;
while (head != NULL)
{
tmp = head;
head = head->next;
free(tmp);
}
}
int main(){
FILE *f1;
struct node *head;
struct node *curr;
head = malloc(sizeof(struct node));
curr = malloc(sizeof(struct node));
curr = head;
int i;
for(i=0;i<9;i++){
curr->next = malloc(sizeof(struct node));
curr = curr->next;
}
f1 = openData(f1);
curr = head;
int readNum;
char trash;
fscanf(f1, "%d", &readNum);
fscanf(f1, "%c", &trash);
for(i=0;i<readNum;i++){
char str[50];
fscanf(f1, "%s",str);
insert(curr, str);
curr->last = 0;
if(readNum-i==1){
curr->last = 1;
}else{
curr = curr->next;
}
}
fscanf(f1, "%c", &trash);
fclose(f1);
curr = head;
printf("\n");
displayBuilding(curr);
curr = head;
freeList(head);
return 0;
}
My header file:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
struct building{
char name[50];
int floors;
int value;
};
typedef struct building place;
struct node{
place payload;
struct node *next;
int last;
};
int t = 500;
The problem is that when you create the linked list, you never set next to NULL in the last node of the list. You need to do that after the loop:
for(i=0;i<9;i++){
curr->next = malloc(sizeof(struct node));
curr = curr->next;
}
curr->next = NULL;
Because of this, the while (head != NULL) loop in freeList() never stops, and eventually tries to free the uninitialized pointer in the last node of the list.
I need to find the maximum number and the minimum number in a circular linked list and i should move the minimum number to the start of the list (before head) and the maximum number to the end of the list (before minimum)
why my code is giving me error in output?
Note: Using doubly linked list is disallowed ,we should do this only with circular linked list.
#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
int num;
struct node *next;
} NODE;
void init(NODE **h)
{
(*h) = (NODE*)malloc(sizeof(NODE));
(*h)->next = *h;
}
NODE* add(NODE* h,NODE* p,int x)
{
int i;
NODE *temp;
temp = (NODE*)malloc(sizeof(NODE));
temp->num = x;
temp->next = h;
if(h->next == h)
{
h->next = temp;
return h;
}
else
{
temp = p->next;
p = temp;
return h;
}
return h;
}
NODE* fin(NODE *h,NODE *p)
{
NODE* ptr,*pmin,*pmax,*temp,*temp2,*mnprev,*mxprev;
// temp: minimum
// temp2: maximum
// pmin: holds the minimum
// pmax: holds the maximum
// ptr: o(n) search
// mnprev: holds the previous node of the minimum
// mxprev: hold the previous node of the maximum
mnprev = mxprev = pmin = pmax = h;
ptr = h->next;
int mini, maxi;
mini = h->num;
maxi = h->num;
do
{
if(ptr->num < mini)
{
mini = ptr->num;
pmin = ptr;
mnprev->next = pmin;
}
if(ptr->num > maxi)
{
maxi = ptr->num;
pmax = ptr;
mxprev->next = pmax;
}
ptr = ptr->next;
} while(ptr != h);
temp = pmin;
temp2 = pmax;
mnprev->next = pmin->next;
mxprev->next = pmax->next;
free(pmin);
free(pmax);
temp->next = h;
temp2->next = temp;
ptr = temp;
do {
printf("%d ",ptr->num);
ptr = ptr->next;
} while(ptr != h);
}
int main()
{
int i,x;
NODE *lis,*p;
init(&lis);
p = lis;
for(i=0;i<7;i++)
{
scanf("%d",&x);
add(lis,p,x);
}
fin(lis,p);
}
rewrite your code
function init delete as it will create nodes that are not used.
Changed to the node between the maximum and minimum values since it
is sufficient to simply replace the value.
like this
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int num;
struct node *next;
} NODE;
NODE* add(NODE **head, NODE **tail, int x){
NODE *temp;
temp = (NODE*)malloc(sizeof(NODE));
temp->num = x;
if(*head == NULL){
temp->next = temp;
*tail = *head = temp;
} else {
temp->next = *head;
(*tail)->next = temp;
*tail = temp;
}
return *head;
}
void print(NODE *p){
NODE *top =p;
do{
printf("%d ", p->num);
p=p->next;
}while(p != top);
printf("\n");
}
void drop(NODE *head, NODE *tail){
NODE *p = head;
tail->next = NULL;
while(p){
NODE *temp = p;
p = p->next;
free(temp);
}
}
void minmax(NODE *head, NODE *tail){
NODE *p, *maxp, *minp;
int temp;
maxp = minp = p = head;
do{
if(maxp->num < p->num){
maxp = p;
}
if(minp->num > p->num){
minp = p;
}
p = p->next;
}while(p != head);
temp = maxp->num; maxp->num = tail->num; tail->num = temp;
if(tail == minp)//exchanged minp
minp = maxp;//fixed
temp = minp->num; minp->num = head->num; head->num = temp;
}
int main(void){
int i, x;
NODE *head, *tail;
tail = head = NULL;
for(i=0;i<7;i++){
printf("%d>", i+1);
scanf("%d", &x);
add(&head, &tail, x);
}
//print(head);
minmax(head, tail);
print(head);
drop(head, tail);
return 0;
}