Sum of all elements of a list in C - c

I need to get the sum of a list that only contains doubles.
For some reason that doesn't work, though:
double sum(DoubleList* list) {
DoubleNode *next = NULL;
double sum = 0;
for (DoubleNode *n = list->first; n != NULL; n = next) {
sum += n->value;
}
return sum;
}

You should fix your loop as follows.
double sum(DoubleList* list) {
double sum = 0;
for (DoubleNode *n = list->first; n != NULL; n = n->next) {
sum += n->value;
}
return sum;
}
The sample code above assumes DoubleNode has an attribute named next and is of type DoubleNode*, that stores the pointer to the next element.

You need to ensure you get the next element in your loop. I am guessing that the next pointer is n->next:
for (DoubleNode *n = list->first; n != NULL; n = n->next) {
sum += n->value;
}

Change
for (DoubleNode *n = list->first; n != NULL; n = next)
to
for (DoubleNode *n = list->first; n != NULL; n = n->next)

Related

C program to partitition a simply linked list

so i've been working on a small function(part of a bigger program) that basically does the following:
define a list and the number of elements N, then input N elements. after this, input a value X;
I have to 'split' / re-order the list in a way so that its elements with value < X are in the beginning, in their relative order and the ones with higher value than X come after; eg.:
Input:
list 6
2 5 6 4 3 1
X 3
Output:
2 3 1 5 6 4
my code and list structure are down below:
(the partition function is at the bottom, just above the main function)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_STRING_SIZE 64
typedef struct ll_node_t
{
void* data;
struct ll_node_t* next;
} ll_node_t;
typedef struct linked_list_t
{
ll_node_t* head;
unsigned int data_size;
unsigned int size;
} linked_list_t;
linked_list_t*
ll_create(unsigned int data_size)
{
linked_list_t* list = malloc(sizeof(list));
// err handle
list->head = NULL;
list->data_size = data_size;
list->size = 0;
return list;
}
void
ll_add_nth_node(linked_list_t* list, unsigned int n, const void* new_data)
{
if(n < 0) exit(0);
ll_node_t* new_node = malloc(sizeof(ll_node_t*));
new_node->data = malloc(list->data_size);
// err handle
memcpy(new_node->data, new_data, list->data_size);
if(n == 0 || list->size == 0) {
new_node->next = list->head;
list->head = new_node;
list->size++;
return;
}
if(n < list->size)
{
ll_node_t* current = list->head;
for(int i = 0; i < n - 1; i++)
{
current = current->next;
}
new_node->next = current->next;
current->next = new_node;
list->size++;
return;
}
if(n >= list->size)
{
ll_node_t* current = list->head;
for(unsigned int i = 0; i < list->size - 1; i++)
{
current = current->next;
}
new_node->next = current->next;
current->next = new_node;
list->size++;
return;
}
}
ll_node_t*
ll_remove_nth_node(linked_list_t* list, unsigned int n)
{
if(n < 0) exit(0);
ll_node_t* removedNode = NULL;
if(n == 0)
{
removedNode = list->head;
list->head = list->head->next;
list->size--;
return removedNode;
}
if(n < list->size)
{
ll_node_t* current = list->head;
// err handle
for(int i = 0; i < n - 1; i++)
{
current = current->next;
}
removedNode = current->next;
current->next = current->next->next;
list->size--;
return removedNode;
}
if(n >= list->size)
{
ll_node_t* current = list->head;
// err handle
for(int i = 0; i < n - 1; i++)
{
current = current->next;
}
removedNode = current->next;
current->next = NULL;
list->size--;
return removedNode;
}
}
unsigned int
ll_get_size(linked_list_t* list)
{
return list->size;
}
void
ll_free(linked_list_t** pp_list)
{
ll_node_t* current = (*pp_list)->head;
for(int i = 0; i < (*pp_list)->size; i++)
{
(*pp_list)->head = current->next;
free(current->data);
free(current);
current = (*pp_list)->head;
}
free(*pp_list);
}
void
ll_print_int(linked_list_t* list)
{
if(!list->size) exit(0);
ll_node_t* current = list->head;
for(int i = 0; i < list->size; i++)
{
printf("%d ", *(int*)current->data);
current = current->next;
}
printf("\n");
}
void
ll_print_string(linked_list_t* list)
{
if(!list->size) exit(0);
ll_node_t* current = list->head;
for(int i = 0; i < list->size; i++)
{
printf("%s ", (char*)current->data);
current = current->next;
}
printf("\n");
}
void partition(linked_list_t* list, int x)
{
ll_node_t* current = list->head;
ll_node_t* tail = list->head;
for(int i = 0; i < list->size; i++)
{
tail = tail->next;
}
//special case for the first element of the list
if(*(int*)current->data > x)
{
tail->next = current;
list->head = current->next;
tail = current;
}
// loop that finds elements > X
for(int i = 0; i < list->size - 1; i++)
{
if(*(int*)current->data > x)
{
// assigning the element to the end
tail->next = current->next;
// linking the previous element to the one after the element
current->next = current->next->next;
tail = tail->next;
tail->next = NULL;
// moving on to next element
current = current->next;
}
else current = current->next;
// moving on to next element
}
}
int main()
{
linked_list_t* linkedList;
while (1) {
char command[16];
long size, num;
scanf("%s", command);
if (strcmp(command, "list") == 0) {
linkedList = ll_create(sizeof(int));
scanf("%ld", &size);
long int curr_nr;
for (int i = 0; i < size; ++i) {
scanf("%ld", &curr_nr);
ll_add_nth_node(linkedList, size, &curr_nr);
}
}
if (strcmp(command, "X") == 0) {
scanf("%ld", &num);
partition(linkedList, num);
ll_print_int(linkedList);
break;
}
}
ll_free(&linkedList);
return 0;
}
so since i have list size as well, which is the number of elements in the list i thought the following:
before looping through the list, check if the head(first element) needs to be shifted at the end (if > X) and then have a loop that loops list->size - 1 times and when the condition inside is met, do the following:
it'd basically loop through elements and look at their next's, so when an element's next is > X, it would be shifted:
assign the tail's next element to be the element > X(current->next), then link current elements next to the one after the element. after that the new tail would be the element that was added at the end.
currently I get a Segmentation fault at the first line inside the condition in the for loop, on this line:
tail->next = current->next;
disclaimer: the main program, as i've tested it, works just fine for adding elements, and so on.
I going to offer an answer that is not exactly a solution to your existing code, but instead presents a different way of thinking about organizing your data as you work through it.
What if, instead of trying to reorder the list in place (managing head, current, and tail) while iterating through it, we deconstruct the list and construct two new lists? Our result becomes the concatenation of these two lists.
Visualized in pseudocode this would work like:
Q is [2 5 6 4 3 1]
part Q <= 3
L is []
R is []
Q eql [2 5 6 4 3 1]
^ -> L eql [2]
Q eql [5 6 4 3 1]
^ -> R eql [5]
Q eql [6 4 3 1]
^ -> R eql [5 6]
Q eql [4 3 1]
^ -> R eql [5 6 4]
Q eql [3 1]
^ -> L eql [2 3]
Q eql [1]
^ -> L eql [2 3 1]
Q eql []
Q is L concat R
Q eql [2 3 1 5 6 4]
By doing this, our partitioning function gets utilize the same logic we used to build our list in the first place.
Here is an example of what this might look like in C, using a very simple linked list:
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
struct node *next;
int value;
} node;
typedef struct {
node *head;
} list;
void list_append_node(list *l, node *n) {
node *root = l->head;
if (root) {
while (root->next)
root = root->next;
root->next = n;
} else
l->head = n;
}
void list_append_value(list *l, int v) {
node *n = calloc(1, sizeof *n);
n->value = v;
list_append_node(l, n);
}
void list_part(list *l, int v) {
list lower = { 0 };
list upper = { 0 };
for (node *curr = l->head, *temp; curr; curr = temp) {
temp = curr->next;
curr->next = NULL;
list_append_node(curr->value <= v ? &lower : &upper, curr);
}
list_append_node(&lower, upper.head);
l->head = lower.head;
}
int main(void) {
int inputs[] = { 2, 5, 6, 4, 3, 1 };
size_t len = sizeof inputs / sizeof *inputs;
list l = { 0 };
for (size_t i = 0; i < len; i++)
list_append_value(&l, inputs[i]);
list_part(&l, 3);
for (node *n = l.head, *t; n; n = t) {
t = n->next;
printf("%d ", n->value);
free(n);
}
putchar('\n');
}
stdout:
2 3 1 5 6 4
Note, the use of a node *tail member for each list could be implemented to improve the performance of list_append_node from O(N) to O(1).

Add 2 Numbers using linked lists - fail with large numbers - C

On leetcode I have found the problem of adding two numbers using singly linked lists.
I'm still a beginner. I have written a code, which works for the first few testcases, but it fails with larger ones e.g.
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1]
[5,6,4]
my output:
[-3,-4,-3,-5,-7,-7,-4,-5,-8,-6,-3,0,-2,-7,-3,-3,-2,-2,-9]
expected:
[6,6,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1]
my code:
struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2)
{
//extracting value of first list
int cnt1 = -1;
long long int sum1 = 0;
struct ListNode *q = l1;
while (q != NULL) {
cnt1++;
sum1 = sum1 + q->val * pow(10, cnt1);
q = q->next;
}
printf("%d, %d\n", cnt1, sum1);
//extracting value of second list
int cnt2 = -1;
long long int sum2 = 0;
struct ListNode *p = l2;
while (p != NULL) {
cnt2++;
sum2 = sum2 + p->val * pow(10, cnt2);
p = p->next;
}
printf("%d, %d\n", cnt2, sum2);
long long int finalSum = sum1 + sum2;
printf("%d\n", finalSum);
struct ListNode *retRoot = malloc(sizeof(struct ListNode));
struct ListNode *t = malloc(sizeof(struct ListNode));
//putting the final sum into the list
long long int newSum;
retRoot->val = finalSum % 10;
retRoot->next = malloc(sizeof(struct ListNode));
newSum = finalSum / 10;
if (newSum == 0) {
retRoot->next = NULL;
return retRoot;
}
t = retRoot->next;
while (newSum != 0) {
//printf("newSum: %d\n", newSum);
t->val = newSum % 10;
newSum = newSum / 10;
if (newSum == 0) break;
t->next = malloc(sizeof(struct ListNode));
t = t->next;
}
t->next = NULL;
return retRoot;
}
Your function initially is wrong at least because a list can contain a too big number that can not be stored in any fundamental integer type. So for example in this statement
sum1 = sum1 + q->val * pow(10, cnt1);
there can be an overflow.
Or the memory allocation in this declaration
struct ListNode *t = malloc(sizeof(struct ListNode));
produces a memory leak.
And moreover this code snippet
t = retRoot->next;
while (newSum != 0) {
//printf("newSum: %d\n", newSum);
t->val = newSum % 10;
//...
results in undefined behavior.
The function can look the following way
struct ListNode * addTwoNumbers( const struct ListNode *l1, const struct ListNode *l2 )
{
const int Base = 10;
struct ListNode *head = NULL;
struct ListNode **current = &head;
int overflow = 0;
for ( ; l1 != NULL || l2 != NULL; current = &( *current )->next )
{
*current = malloc( sizeof( struct ListNode ) );
int sum = overflow;
if ( l1 != NULL )
{
sum += l1->val;
l1 = l1->next;
}
if ( l2 != NULL )
{
sum += l2->val;
l2 = l2->next;
}
( *current )->val = sum % Base;
overflow = sum / Base;
( *current )->next = NULL;
}
if ( overflow )
{
*current = malloc( sizeof( struct ListNode ) );
( *current )->val = overflow;
( *current )->next = NULL;
}
return head;
}

How to move certain elements from linked list at the end of that list?

Today i was trying to make a program that would enter 15 random values (from 100 to 120) into linked list.
That part works like a charm. Then I went to find the max and the min values from that list, and find the average.
I want to move all values greater than average to the end of that list which I tried to realise using function prebaci.
Function unos puts all elements into the list, and function unosK puts all elements at the end of the list. Program goes into infinite loop, and I don't know why. Can you help me to move all values greater than average (107) to the end of the list?
My CODE:
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
typedef struct lista* Pozicija;
struct lista {
int el;
Pozicija next;
};
void unos(Pozicija P, int el);//input front
void ispis(Pozicija P);//print
int mini(Pozicija P);//find min
int maxi(Pozicija P);//find max
void prebaci(Pozicija P,int x);//function for transfering at the end
void unosK(Pozicija P,int x);//input end
int main() {
srand(time(0));
struct lista L;
L.next = NULL;
int min,max, i,j;
int prvi[21], drugi[15];
int avg;
for (i = 0;i < 21;i++) {
prvi[i] = i + 100;
printf("%d ", prvi[i]);
}
for (i = 0;i < 15;i++) {
int temp = prvi[i];
int random = rand() % 15;
prvi[i] = prvi[random];
prvi[random] = temp;
}
printf("\n\n");
for (i = 0;i < 15;i++) {
//printf("%d ",prvi[i]);
unos(&L, prvi[i]);
}
printf("Ispis\n");
ispis(L.next);
printf("\n\n");
min = mini(L.next);
printf("Minqi:%d\n", min);
printf("\n\n");
max = maxi(L.next);
printf("Miaxi:%d\n", max);
printf("\n\n");
avg = (min + max) / 2;
printf("avg:%d\n", avg);
printf("\n\n");
printf("Prebacaj:\n");
prebaci(&L, avg);
ispis(L.next);
}
void unos(Pozicija P, int el) {
Pozicija q;
q = (Pozicija)malloc(sizeof(struct lista));
q->el = el;
q->next = P->next;
P->next = q;
}
void ispis(Pozicija P) {
while (P != NULL) {
printf("%d ", P->el);
P = P->next;
}
}
int mini(Pozicija P) {
int min;
min = INT_MAX;
while (P != NULL) {
if (min > P->el) {
min = P->el;
}
P = P->next;
}
return min;
}
int maxi(Pozicija P) {
int max;
max = INT_MIN;
while (P != NULL) {
if (max< P->el) {
max = P->el;
}
P = P->next;
}
return max;
}
void prebaci(Pozicija P,int x) {
P = P->next;
Pozicija t;
t = P;
while (t != NULL) {
if (t->el > x)
{
unosK(P, t->el);
t = t->next;
}
else if (t->el <= x) {
unos(P, t->el);
t = t->next;
}
}
}
void unosK(Pozicija P,int x) {
Pozicija q=NULL;
q = (Pozicija)malloc(sizeof(struct lista));
q->el = x;
while (P->next != NULL)
P = P->next;
q->next = P->next;
P->next = q;
}
Here is a working, drop-in replacement for the original prebaci function. It still has the dummy node at the start of the list, but does not allocate any new elements.
Rather than calling unos and unosK which allocate new elements, it manipulates the pointers in the original list to move the elements greater than the average value to the end of the list.
It first moves the greater than average elements from the original list onto a new, initially empty list (q), and then links the last element of the original list to the first element of the new list so that all the greater than average elements are now at the end of the original list.
The new list (q) has been implemented as a pointer instead of a dummy node.
The function makes use of pointers to pointers (pp and pq) to manipulate the links in the original list and the new list.
void prebaci(Pozicija P,int x) {
Pozicija *pp = &P->next; /* pointer to link in original list */
Pozicija q = NULL; /* new list for elements greater than average */
Pozicija *pq = &q; /* pointer to end link of new list */
while (*pp != NULL) {
if ((*pp)->el > x) {
/* move element from original list to end of new list */
*pq = *pp; /* end of new list points to moved element */
*pp = (*pp)->next; /* remove element from original list */
pq = &(*pq)->next; /* update pointer to end link of new list */
}
else {
/* do not move this element */
pp = &(*pp)->next; /* advance to next link in original list */
}
}
*pq = NULL; /* terminate the new list */
*pp = q; /* append the new list to the end of the original list */
}

C.....Shufling values of linked list

I am writing a war cards game. I need to shufle first few elements of players hand (linked list).
That`s what i have:
void tasowanie(llist_t** head, int warsize) {
llist_t** temp = head;
Card_t temp_card;
int random;
while (warsize > 0) {
random = rand() % warsize;
for (int j = 0; j < random; j++)
if ((*temp)!=NULL && (*temp)->next != NULL)
*temp = (*temp)->next;
temp_card = (*head)->card;
(*head)->card = (*temp)->card;
(*temp)->card = temp_card;
*head = (*head)->next;
*temp = *head;
warsize--;
}
}
The problem is that I am losing elements of this list.
I was thinking about puting these elements into array, then shufling it and puting it back to the list, although I imagine there has to be more elegant solution.
You should not be writing to *temp, as this is a pointer to the real list next pointer.
The same applies to moving head: unless you intend to update the list you should not be touching *head.
Instead, when you want to update temp you should set it with temp = &((*temp)->next), and reset with temp=head.
void tasowanie(llist_t** head, int warsize) {
llist_t** temp = head;
Card_t temp_card;
int random;
while (warsize > 0) {
random = rand() % warsize;
for (int j = 0; j < random; j++)
if ((*temp)!=NULL && (*temp)->next != NULL)
temp = &((*temp)->next);
temp_card = (*head)->card;
(*head)->card = (*temp)->card;
(*temp)->card = temp_card;
head = &((*head)->next);
temp = head;
warsize--;
}
}

Swap kth position from start and end in a single traverse linked list

I have come across the following implementation for swapping the kth position from start and end in a linked list in single traverse.
node *list;
node *p, *q, *r;
p = q = r = list;
i = 1;
while(p != NULL)
{
if(i != k)
{
q = q->next;
i++;
}//q will eventually point to kth node from starting
if(i == k)
{
r = r->next
}//r will eventually point to kth node from end
p = p->next;
}
Swap q & r elements
But I feel it's not the right implementation, could anyone look at it and verify if it's correct?
If it's wrong, what changes would I have to make?
This question is majorly associated with finding right nodes and respective previous node.
Then essentially there are 2 cases when nodes are starting and ending node or they are intermediate nodes.
First adjust previous pointer to point swap targets and then swap next pointers of targets. That is all ... following is complete java code for reference ->
JAVA Code
public class SwapKthNodeTest {
public static void main(String[] args) {
Test10Node();
System.out.println();
Test2Node();
}
private static void Test2Node() {
Node head = Node.getNodeListHead(2);
Node.ToString(head);
int k = 1;
head = Node.SwapKthNodeFromStartNEnd(head, k);
Node.ToString(head);
k = 2;
head = Node.SwapKthNodeFromStartNEnd(head, k);
Node.ToString(head);
}
public static void Test10Node(){
Node head = Node.getNodeListHead(10);
Node.ToString(head);
int k = 2;
head = Node.SwapKthNodeFromStartNEnd(head, k);
Node.ToString(head);
k=1;
head = Node.SwapKthNodeFromStartNEnd(head, k);
Node.ToString(head);
k=3;
head = Node.SwapKthNodeFromStartNEnd(head, k);
Node.ToString(head);
k=4;
head = Node.SwapKthNodeFromStartNEnd(head, k);
Node.ToString(head);
k=5;
head = Node.SwapKthNodeFromStartNEnd(head, k);
Node.ToString(head);
}
}
class Node {
int val;
Node next;
Node(int val, Node next) {
this.val = val;
this.next= next;
}
public static int length(Node head){
Node trav = head;
int count = 0;
while(trav != null){
count++;
trav = trav.next;
}
return count;
}
public static void ToString(Node head) {
// just print the list which we created
Node trav = head;
while(trav != null){
System.out.print(trav.val+" ");
trav = trav.next;
}
}
public static Node SwapKthNodeFromStartNEnd(Node head, int k) {
System.out.println();
int len = Node.length(head);
if( k > len) return head;
// would be the same thing just making it reverse
// to make process more cleaner
if( k == len) k = 1;
Node x = head, y = head, t = head;
Node xp = null, yp = null;
int i = 1;
while (i++ < k) {
xp = x;
x = x.next;
t = t.next;
}
while(t.next != null){
yp = y;
y = y.next;
t = t.next;
}
// System.out.println("x= "+x.val+" y= "+ y.val);
// if(xp != null) System.out.println("xp= "+xp.val);
// if(yp != null) System.out.println("yp= "+yp.val);
// first adjust previous pointer of two nodes
// later swap the next pointers of both nodes
// CASE-1: case nodes have previous pointer
// and they are not start and end node
if(xp != null && yp != null ){
xp.next = y;
yp.next = x;
}
// CASE-2: x and y nodes are first and last
// this case xp is null
else if (xp == null && yp != null){
head = y;
yp.next = x;
}
t = y.next;
y.next = x.next;
x.next = t;
return head;
}
public static Node getNodeListHead(int nodes){
int idx = nodes-1;
Node head = new Node(nodes, null);
while(idx >= 1){
head = new Node(idx, head);
idx--;
}
return head;
}
}
Refer to geeks4geeks for all boundary cases:
http://www.geeksforgeeks.org/swap-kth-node-from-beginning-with-kth-node-from-end-in-a-linked-list/
For singly linked list of size N, find the Kth element and then N-K+1 th element and exchange their values
And as Jonathan said, you have to take care of special cases and keep track of additional pointers to do the swap. But the crux is you have to swap the Kth element with the N-K+1th element

Resources