ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
In a popular on-line C-programming monograph on pointers (Nick Parlante, “Linked List Problems”, Stanford U.), I’m running into the following dilemma with a suggested solution in the text, which I cannot make compile.
Though I have produced a satisfactory working solution, I’m wondering if anyone can identify if I’ve made a coding error while trying to employ the suggested solution, or is the suggested solution erroneous.
[I note that I still had to rem the last two code lines of AlternateSplit() to accomplish compiling-------don’t understand why those code lines were even included in the original]
The Problem, as stated, is:
Write a function AlternatingSplit() that takes one list and divides up its nodes to make two smaller lists. The sublists should be made from alternating elements in the original list. So if the original list is {a, b, a, b, a}, then one sublist should be {a, a, a} and the other should be {b, b}. You may want to use MoveNode() as a helper. The elements in the new lists may be in any order.
/*
Given the source list, split its nodes into two shorter lists.
If we number the elements 0, 1, 2, ... then all the even elements
should go in the first list, and all the odd elements in the second.
The elements in the new lists may be in any order.
*/
#include <stdio.h>
#include <stdlib.h>
struct node
{
int i;
struct node* next;
};
void AlternatingSplit(struct node* source,struct node** aRef,struct node** bRef);
void MoveNode(struct node** destRef,struct node** sourceRef);
void Push(struct node** headref,int i);
int main(void)
{
int i;
struct node* head=NULL;
struct node* tail;
struct node *a, *b;
Push(&head,0); //build list
tail=head;
for(i=1;i<9;i++)
{
Push(&(tail->next),i);
tail=tail->next;
}
AlternatingSplit(head,&a,&b); //split into lists a and b
}
void AlternatingSplit(struct node* source,struct node** aRef,struct node** bRef)
{
struct node* a = NULL;
struct node* b = NULL;
while (source != NULL)
{
MoveNode(aRef, &source); // Move node from source to 'a'
if (source != NULL)
{
MoveNode(bRef, &source); // Move node from source to 'b'
}
}
*aRef = a;
*bRef = b;
}
void MoveNode(struct node** destRef,struct node** sourceRef)
{
struct node* current;
current = *sourceRef;
*sourceRef = current->next;
current->next = *destRef;
*destRef = current;
}
void Push(struct node** headref,int i)
{
struct node* temp=malloc(sizeof(struct node));
temp->i = i;
temp->next = *headref;
*headref = temp;
}
Thought the above correction (which compiled) was suitable, but I find that it leaves "a" and "b" empty. Is it valid to pass uninitialized pointers *a and *b in main() as arguments to AlternatingSplit() ?
I remain uncertain as to the whole "solution" listed by the author of the monograph.
Thought the above correction (which compiled) was suitable, but I find that it leaves "a" and "b" empty. Is it valid to pass uninitialized pointers *a and *b in main() as arguments to AlternatingSplit() ?
I remain uncertain as to the whole "solution" listed by the author of the monograph.
I don't see why NevemTeve uncommented the lines
Code:
//*aRef = a;
//*bRef = b;
I think those lines were correctly commented out in the original.
Adding the missing declaration of a and b in main was obviously needed. Beyond that, I didn't test and didn't desk check carefully.
Anyway, in answer to your question, it is perfectly valid to pass the addresses of uninitialized pointers. Something needs to initialize those before use, but that can be (probably should be) inside the function, rather than outside, such as:
Code:
void AlternatingSplit(struct node* source,struct node** aRef,struct node** bRef)
{
*aRef = NULL;
*bRef = NULL;
while (source != NULL)
{
MoveNode(aRef, &source); // Move node from source to 'a'
if (source != NULL)
{
MoveNode(bRef, &source); // Move node from source to 'b'
}
}
}
Johnsfine:
Thanks for your info regarding passing uninitialized variables.
No, I was the one who commented out the lines
Code:
*aRef = a;
*bRef = b;
as there was no need for a return value in my working solution: in fact, my version would not compile properly with those return values present, and I would get following errmsg on compilation:
Quote:
prob12.c:68:9: error: use of undeclared identifier 'a'
*aRef = a;
^
prob12.c:69:9: error: use of undeclared identifier 'b'
*bRef = b;
With NevemTeve's code, if I try using the following function to evaluate what is contained in a and b lists:
Code:
void Length_Vals(struct node* head)
{
struct node* current = head;
int count = 0;
while(current!=NULL)
{
count++;
printf("%3d",current->i);
current = current->next;
}
printf("\n# of nodes in list is %d\n",count);
}
I get the following terminal output:
Quote:
0 1 2 3 4 5 6 7 8 9
# of nodes in [original] list is 10
# of nodes in list [a] is 0
# of nodes in list [b] is 0
I remain completely befuddled by the "suggested" solution.
Last edited by atlantis43; 11-06-2014 at 04:32 PM.
Reason: addnl info
I believe NevemTeve has a typo in his AlternatingSplit():
Code:
while (source != NULL)
{
MoveNode(aRef, &source); // Move node from source to 'a'
if (source != NULL)
{
MoveNode(bRef, &source); // Move node from source to 'b'
}
}
I believe NevemTeve has a typo in his AlternatingSplit():
Code:
while (source != NULL)
{
MoveNode(aRef, &source); // Move node from source to 'a'
if (source != NULL)
{
MoveNode(bRef, &source); // Move node from source to 'b'
}
}
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.