I came across this problem while preparing for an interview and curious to know the diffrent ways it can be written. I found this at http://cslibrary.stanford.edu/103/ and have given the problem as it is.
here is a code to build the list {1,2,3}
struct node* BuildOneTwoThree() {
struct node* head = NULL;
struct node* second = NULL;
struct node* third = NULL;
head = malloc(sizeof(struct node)); // allocate 3 nodes in the heap
second = malloc(sizeof(struct node));
third = malloc(sizeof(struct node));
head->data = 1; // setup first node
head->next = second; // note: pointer assignment rule
second->data = 2; // setup second node
second->next = third;
third->data = 3; // setup third link
third->next = NULL;
// At this point, the linked list referenced by "head"
// matches the list in the drawing.
return head;
}
Q: Write the code with the smallest number of assignments (=) which will build the above memory structure. A: It requires 3 calls to malloc(). 3 int assignments (=) to setup the ints. 4 pointer assignments to setup head and the 3 next fields. With a little cleverness and knowledge of the C language, this can all be done with 7 assignment operations (=).
I did it with six assignments. What do I get?
struct node
{
int data;
struct node * next;
};
struct node * build_123()
{
struct node * first = malloc(sizeof(*first));
struct node * second = malloc(sizeof(*second));
struct node * third = malloc(sizeof(*third));
assert(first && second && third);
*first = (struct node){ 1, second };
*second = (struct node){ 2, third };
*third = (struct node){ 3, NULL };
return first;
}
Also, the exercise isn't very useful. If I wanted to build a linked list from a known set of integers, I'd do something like this:
struct node
{
int data;
struct node * next;
};
#define build_list(...) \
_build_list((sizeof((int []){ __VA_ARGS__ }))/(sizeof(int)), \
(int []){ __VA_ARGS__ })
struct node * _build_list(size_t count, int values[count])
{
struct node * next = NULL;
for(size_t i = count; i--; )
{
struct node * current = malloc(sizeof *current);
assert(current);
*current = (struct node){ values[i], next };
next = current;
}
return next;
}
Then, you can build an arbitrary list with
struct node * list = build_list(1, 2, 3);
Here's another version using a single assignment, inspired by codelogic's answer:
struct node * build_123(void)
{
struct node * list = malloc(sizeof(struct node [3]));
return memcpy(
list,
(struct node []){ { 1, list + 1 }, { 2, list + 2 }, { 3, NULL } },
sizeof(struct node [3])
);
}
Finally, I slightly modified MSN's solution - now, there's no assignment at all:
struct node
{
int data;
struct node * next;
};
struct node * make_node(struct node * new_node, int data, struct node * next)
{
return memcpy(new_node, &(struct node){ data, next }, sizeof(*new_node));
}
struct node * create_node(int data, struct node * next)
{
return make_node(malloc(sizeof(struct node)), data, next);
}
struct node * build_123(void)
{
return create_node(1, create_node(2, create_node(3, NULL)));
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With