void AlternatingSplit(struct Node* source, struct Node** aRef,
struct Node** bRef)
{
/* split the nodes of source to these 'a' and 'b' lists */
struct Node* a ;
struct Node* b;
struct Node* current = source;
if(current){
a=current;
b=current->next;
current=b->next;
a->next=NULL;
b->next=NULL;
}
while(current) {
a->next=current;
b->next=current->next;
if(b)
current=b->next;
b=b->next;
a=a->next;
}
*aRef = a;
*bRef = b;
}
I am getting segmentaton fault here i dont know why pls help.
This question is to alternating split linkedlist nodes. I m using two pointers a and b and adding to it alternatingly but its giving error . pls help me
Like most linked-list rearrangement exercises, pointers to pointers make the job much, much easier. The point of this exercise it to flex your ability to change the next pointers without ever changing the data values of said-same. Pointers to pointers are an excellent way to do that in C.
This is especially trivial because you were already provided the target pointer-to-pointer arguments that we can reuse for building each list. How that works is best understood by demonstrating a technique for building a forward-chained linked list using a single head pointer and a pointer to pointer p:
struct Node *head, **pp = &head;
for (int i = 1; i <= 20; ++i)
{
*pp = malloc(sizeof **pp);
(*pp)->data = i;
pp = &(*pp)->next;
}
*pp = NULL;
Yes, it needs error checking, but the algorithm is what to focus on here. This code uses only pp to build the actual list. The rule is this: pp is a pointer to pointer to Node, and always holds the address of the next pointer to Node to populate. That's what pointers to pointers do: hold addresses of pointers. In this case pp initially holds the address of the head pointer. With each new node added pp takes the address of the next pointer of the previously just-added node. Makes sense, right? That will be the next pointer where we want to hang the next node. This process continues until we finish the loop. At that pointer pp holds the address of the last node's next pointer, which we set to NULL to terminate the list.
Now, knowing what we learned above, consider this:
void AlternatingSplit(struct Node* source, struct Node** a, struct Node** b)
{
while (source)
{
*a = source;
a = &(*a)->next;
source = source->next;
if (source)
{
*b = source;
b = &(*b)->next;
source = source->next;
}
}
*a = *b = NULL;
}
Example
A short example using both the forward-chaining build algorithm I showed first, and the split algorithm I showed after, appears below. Some utility functions for printing the list are included. I leave freeing the lists (there are two now, remember to walk both and free each node) as an exercise for you:
#include <stdio.h>
#include <stdlib.h>
struct Node
{
int data;
struct Node *next;
};
void AlternatingSplit(struct Node* source, struct Node** a, struct Node** b)
{
while (source)
{
*a = source;
a = &(*a)->next;
if ((source = source->next))
{
*b = source;
b = &(*b)->next;
source = source->next;
}
}
*a = *b = NULL;
}
void PrintList(struct Node const *p)
{
while (p)
{
printf("%d ", p->data);
p = p->next;
}
fputc('\n', stdout);
}
int main(void)
{
struct Node *head, **pp = &head;
for (int i = 1; i <= 20; ++i)
{
*pp = malloc(sizeof **pp);
(*pp)->data = i;
pp = &(*pp)->next;
}
*pp = NULL;
PrintList(head);
struct Node *a = NULL, *b = NULL;
AlternatingSplit(head, &a, &b);
PrintList(a);
PrintList(b);
return EXIT_SUCCESS;
}
Output
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
1 3 5 7 9 11 13 15 17 19
2 4 6 8 10 12 14 16 18 20
There are few errors in your code -
Trying to access node->next , without checking whether node exists or not .
Not tackling the corner cases depending on the length of linked list (i.e. if length (linked list) < 3 )
And then comes the blunder , you are trying to make the new linked lists and then in the end aRef and bRef is assigned to the last node in their respective linked lists.
Try to deal with these problems and for reference you can see the code below.
void AlternatingSplit(struct Node* source, struct Node** aRef,
struct Node** bRef)
{
struct Node* a,b;
struct Node* current = source;
if(current){
a=current;
b=current->next;
// moving 'current' one step at a time will secure the code from crashing for corner cases
current = current->next;
if(b)
current=b->next;
a->next=NULL;
b->next=NULL;
//link aRef bRef right here
*aRef = a;
*bRef = b;
}
else {
*aRef = source; // Null
*bRef = source; // Null
return;
}
while(current)
{
a->next=current;
a=a->next;
b->next=current->next;
b=b->next;
current=current->next;
if(b){
current = b->next;
}
}
b->next = NULL;
a->next = NULL;
}
Hope this will help .
Keep asking , keep growing :)
Related
I'd like to know if there is a way to access every variable of type INT so that I may perform a function on all of them.
In the example below, incrementing n number of integers.
Rudimentarily, my code would look something like this:
typedef int INT;
main()
{
INT a = 1;
INT b = 2;
INT c = 3;
// increment all variables of type INT by 1
printf("%d %d %d\n", a, b, c);
}
The expected result would output 2 3 4.
Perhaps there is a way to use malloc or calloc for this?
Maybe I'm doing this entirely wrong and if so, please call me out on it.
How could I do the same with structs, if possible?
I am guessing that you are looking for something like this!
Let us first define our struct that contains the three ints
typedef struct int_arr
{
int first_int;
int second_int;
int third_int;
}int_arr;
Now we are going to write a function that will simply initialize the struct to the value we want and return a pointer to a newly allocated int_arr;
int_arr * init_int_arr(int first, int second, int third)
{
int_arr * new_arr = malloc(sizeof(int_arr));
new_arr->first_int = first;
new_arr->second_int = second;
new_arr->third_int = third;
return new_arr;
}
And here is the function we will use to print the contents of the struct
void print_int_arr(int_arr * arr)
{
printf("first: %d, second: %d, thrid: %d \n",arr->first_int,arr->second_int,arr->third_int);
}
You have also mentioned that you potentially do not know the size of the wanted array from the begging. Well the best way to have a dynamic array in C, that looks like the one in python is to use linked lists! To understand them well I suggest you first understand how pointers and addressing works in C, but here is a potential example!
Firstly what is a linked list?
Now let us remember that a linked list with a sentinel is easier to loop through and use in general, so that is the approach we will take!
Sentinel node
Here is our linked_list struct:
typedef struct linked_list
{
int_arr * arr;
linked_list * next;
}linked_list;
Now lets write the function that will build the sentinel
linked_list *linked_list_sentinel_build()
{
int_arr *sentinel_arr = init_int_arr(-1, -1, -1);
linked_list *my_list = malloc(sizeof(linked_list));
my_list->next = NULL;
my_list->arr = sentinel_arr;
return my_list;
}
Let us not forget about a custom free
void linked_list_free(linked_list* head)
{
linked_list* previous;
while (head)
{
previous = head;
head = head->next;
free(previous->arr);
free(previous);
}
}
And here are the two functions allowing you to add values
// Inserts a value right after the head
/*
HEAD -> A -> B -> ..... -> Z
linked_list_insert_beg(HEAD,C );
HEAD -> C -> A -> B -> ..... -> Z
*/
void linked_list_insert_beg(linked_list *head, int_arr *arr)
{
linked_list *tmp = malloc(sizeof(linked_list));
tmp->arr = arr;
tmp->next = head->next;
head->next = tmp;
}
// Inserts a value right after the head
/*
HEAD -> A -> B -> ..... -> Z
linked_list_insert_end(HEAD, C);
HEAD -> A -> B -> ..... -> Z -> C
*/
void linked_list_insert_end(linked_list *head, int_arr *arr)
{
linked_list *tmp = malloc(sizeof(linked_list));
for (; head->next != NULL; head = head->next)
{
// This loop runs to the last node and quits with head being that last node
continue;
}
tmp->arr = arr;
tmp->next = head->next;
head->next = tmp;
}
And to end here is the print for your dynamic array
//Prints the contents of a linked list
void linked_list_print(linked_list* head)
{
while(head->next)
{
head = head->next;
print_int_arr(head->arr);
}
}
I'm still learning how to program in C and I've stumbled across a problem.
Using a char array, I need to create a linked list, but I don't know how to do it. I've searched online, but it seems very confusing. The char array is something like this char arr[3][2]={"1A","2B","3C"};
Have a look at this code below. It uses a Node struct and you can see how we iterate through the list, creating nodes, allocating memory, and adding them to the linked list. It is based of this GeeksForGeeks article, with a few modifications. I reccommend you compare the two to help understand what is going on.
#include <stdio.h>
#include <stdlib.h>
struct Node {
char value[2];
struct Node * next;
};
int main() {
char arr[3][2] = {"1A","2B","3C"};
struct Node * linked_list = NULL;
// Iterate over array
// We calculate the size of the array by using sizeof the whole array and dividing it by the sizeof the first element of the array
for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++) {
// We create a new node
struct Node * new_node = (struct Node *)malloc(sizeof(struct Node));
// Assign the value, you can't assign arrays so we do each char individually or use strcpy
new_node->value[0] = arr[i][0];
new_node->value[1] = arr[i][1];
// Set next node to NULL
new_node->next = NULL;
if (linked_list == NULL) {
// If the linked_list is empty, this is the first node, add it to the front
linked_list = new_node;
continue;
}
// Find the last node (where next is NULL) and set the next value to the newly created node
struct Node * last = linked_list;
while (last->next != NULL) {
last = last->next;
}
last->next = new_node;
}
// Iterate through our linked list printing each value
struct Node * pointer = linked_list;
while (pointer != NULL) {
printf("%s\n", pointer->value);
pointer = pointer->next;
}
return 0;
}
There are a few things the above code is missing, like checking if each malloc is successful, and freeing the allocated memory afterwards. This is only meant to give you something to build off of!
I'm trying to write a linked list, with the restriction being that the pointer inside of a node has to point to the next node's pointer. With this restriction, how would I ever access a variable inside of a node?
Say the node is defined
struct Node {
int val;
void *next;
}
but for every Node, say we have currentNode and nextNode, we make the void *next value
currentNode.next = &(nextNode.next);
How would you go about creating this and efficiently accessing each node?
You can get a pointer to the Node by subtracting the offset of next, using the offsetof operator.
struct Node *nextNode = (struct Node *)((char *)currentNode.next - offsetof(Node, next));
int nextVal = nextNode->val;
If you're using C99, which doesn't have offsetof() built in, you can use this traditional macro:
#define offsetof(st, m) ((size_t)&(((st *)0)->m))
It's technically undefined behavior (see Does &((struct name *)NULL -> b) cause undefined behaviour in C11?) but it generally works.
Use an appropriate struct so that the restriction is inherently satisfied:
struct Node {
void *next;
int val;
}
No explicit pointer arithmetic required.
I am implementing a link list as per your requirement. Hope this will help your. In this link list every pointer inside the node pointing to the next node pointer.
Please add these 3 header file at the top of your program stdio.h, memory.h and stdlib.h
struct Node {
int val;
void *next;
};
void main(void)
{
typedef struct Node NODE;
NODE *f,*p,*q = NULL;
int i = 1;
/* First create your first node here */
f = (NODE *)malloc(sizeof(NODE));
f->next = f;
f->val = 0;
p = f;
/* now lets create link list with 10 nodes */
while( i < 10 )
{
q = (NODE *)malloc(sizeof(NODE));
q->next = q;
q->val = i++;
p->next = q->next; /* first node is pointing to the next node pointer */
p = q;
}
/* search the link list and print its value */
p = f; /* now p is pointing to the first node of the link list */
i = 0;
/* first print the value of first node here */
printf("Node :%d and val = %d\n", i, p->val);
while(p->next != p)
{
printf("Node :%d and val = %d\n", i++, ((NODE *)(p->next))->val);
p = p->next;
}
}
output of this program;
Node :0 and val = 0
Node :1 and val = 1
Node :2 and val = 2
Node :3 and val = 3
Node :4 and val = 4
Node :5 and val = 5
Node :6 and val = 6
Node :7 and val = 7
Node :8 and val = 8
Node :9 and val = 9
This was an remote coding test I got a few days ago, and I've already submitted the answers so I'm not cheating here.
The question is fairly simple: implement a function to delete an item from a linked list. But with one catch: the linked list is in the form of an array.
typedef struct _Node{
int val;
struct _Node* next;
} Node;
Test input provided by the interviewer, which we can modify slightly
void printLL(Node* root){
Node* current = root;
while (current){
printf("%d\n", current->val);
current = current->next;
}
}
int main(){
Node list[6];
list[0].value =1; list[0].next = list+1;
list[1].value =2; list[1].next = list+2;
list[2].value =3; list[2].next = list+3;
list[3].value =4; list[3].next = list+4;
list[4].value =5; list[4].next = list+5;
list[5].value =6; list[5].next = 0;
delete(&list, 3) // this gives segmentation error with my implementation;
printLL(list);
return 0;
}
My answer, which is standard for linked list deletion:
void delete(Node** root, int val){
Node* current = *root;
Node* prev = NULL;
if ((*root)->val == val){
*root = (*root)->next;
//free(current); // test case not dynamically allocated
return;
}
while (current && (current->val != val)){
prev = current;
current = current->next;
}
if (!current){
printf("value not found\n");
return ;
}
else{
prev->next = current->next;
//free(current);
}
}
However, if I use pointers instead, then the function works
Node* p = list;
delete(&p, 3);
I think I understand the difference between &list and &p as function argument:
**Variable name | Variable value | Variable address**
list | address of first elem | address of first elem
p | address of first elem | some random address of the pointer
But since in the delete function we are operating with *list and *p respectively, their value should also be the same.
My guess now is because of in
*root = (*root)->next;
if *root is an array name, then it's illegal as we cannot reassign it. But if *root is a pointer, then we are freely to reassign them. Am I correct on this?
Thank you for reading through this long and messy post.
I tried to do implementation of queue by using linked list, but there always occurred error: incompatible types in assignment and assignment makes pointer from integer without a cast.
Here is my code:
#include <stdlib.h>
#include <stdio.h>
#include "Queue.h"
struct QUEUE_ELEMENT{
int element;
struct QUEUE_ELEMENT *next;
};
int size;
struct QUEUE_ELEMENT *head, *tail;
void initQueue(){
head = NULL;
tail = NULL;
size = 0;
} // void initQueue()
int queueEmpty(void) {
return (head == NULL && tail == NULL);
} // int queueEmpty(void)
int enqueue(QUEUE_ELEMENT e) {
struct QUEUE_ELEMENT *temp;
if (tail == NULL){
tail -> next = NULL;
tail -> element = e;
head = tail;
}
else {
temp = malloc(sizeof(QUEUE_ELEMENT));
tail -> next = temp;
temp -> element = e;
temp -> next = NULL;
tail = temp;
}
return size++;
} // int enqueue(QUEUE_ELEMENT e)
int dequeue(QUEUE_ELEMENT *e){
struct QUEUE_ELEMENT *temp;
temp = malloc(sizeof(QUEUE_ELEMENT));
if (queueEmpty() != 0 ){
temp = head;
if(temp -> next != NULL){
temp = temp -> next;
free(head);
head = temp;
}
else{
free(head);
head = NULL;
tail = NULL;
}
}
return size--;
} // int dequeue(QUEUE_ELEMENT *e)
I revised my code a lot.
Why 'tail -> element = e;' in enqueue() occurs error 'incompatible types in assignment'? How can I fix it?
Is it a homework or for a real need? For the first one I won't say anything. But if you need it in practice, it's better to use already implemented solution.
There is a popular style where, in a linked list, head looks like a usual entry and the only thing which distinguishes it is the head pointer value itself. The first good example is Linux linked lists implementation (a description). Its specifics is a trick to get the whole entry address from its link member. This one is trivial to study and can answer your goals immediately.
The second good example is BSD list and queue macro set (a manpage; particularly, you could start with TAILQ macro set). It's more cumbersome due to some tricks (e.g. forward pointers address link field but backward pointers address the whole structure) but still efficient.
I hope both can satisfy you and prevent reinventing a wheel :)
You are assigning tail->element, which is an int, to e which is a QUEUE_ELEMENT. if you want to access the element in e you have to deference it like you did with tail first.
so tail->element = e->element