Programming This 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.
Are you new to LinuxQuestions.org? Visit the following links:
Site Howto |
Site FAQ |
Sitemap |
Register Now
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.
 |
GNU/Linux Basic Guide
This 255-page guide will provide you with the keys to understand the philosophy of free software, teach you how to use and handle it, and give you the tools required to move easily in the world of GNU/Linux. Many users and administrators will be taking their first steps with this GNU/Linux Basic guide and it will show you how to approach and solve the problems you encounter.
Click Here to receive this Complete Guide absolutely free. |
|
 |
03-22-2008, 10:42 AM
|
#1
|
|
Member
Registered: Jun 2004
Posts: 233
Rep:
|
C Lists
Hi, i'm revising my old self referential structures, basically a two way list. I'm at a point where i'm rewriting 'add' into 'append' and i'm thinking I can avoid returning a structure. However if I do and then try to access the last element it returns the one before, yet if I print the whole list then the last element is there... (why?)
main.c
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "rclist.h"
int main()
{
int i;
struct rclist *root;
root = NULL;
char *directions[64] = { "N", "NE", "E", "SE", "S", "SW", "W", "NW" };
// ADD MORE NODES
for(i=0;i<8;i++)
{
root = add_node(directions[i], root);
}
// PRINT LIST
struct rclist *r = find_first_node(root);
print_list(r);
printf("\n");
r = find_last_node(root);
print_node(r);
printf("\n");
r = find_first_node(root);
print_node(r);
printf("\n");
r = find_node_at(root, 3);
print_node(r);
printf("\n");
//root = rclist_append("hello", root);
rclist_append("hello", r);
r = find_last_node(r);
printf("> ");
print_node(r);
printf("\n");
/*
r = find_first_node(root);
print_list(r);
printf("\n");
*/
return 0;
}
rclist.h
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct rclist
{
char *s;
struct rclist *down;
struct rclist *up;
};
struct rclist *add_node(char * s, struct rclist *last);
void rclist_append(char *s, struct rclist *root);
//struct rclist *rclist_append(char *s, struct rclist *root);
struct rclist *find_next_node(struct rclist *root);
struct rclist *find_node_at(struct rclist *root, int pos);
struct rclist *find_first_node(struct rclist *root);
struct rclist *find_last_node(struct rclist *root);
void print_node(struct rclist *root);
void print_list(struct rclist *root);
void rclist_append(char *s, struct rclist *root)
//struct rclist *rclist_append(char *s, struct rclist *root)
{
root = find_last_node(root);
struct rclist *r;
if((r = (struct rclist*) malloc(sizeof(struct rclist))) != NULL)
{
if((r->s = (char*) malloc(strlen(s) + 1)) != NULL)
{
strcpy(r->s, s);
r->up = NULL;
root->up = r;
r->down = root;
}
}
//return r;
}
struct rclist *add_node(char *s, struct rclist *last)
{
struct rclist *this;
if((this = (struct rclist*) malloc(sizeof(struct rclist))) != NULL)
{
if((this->s = (char*) malloc(strlen(s) + 1)) != NULL)
{
strcpy(this->s, s);
if(last != NULL)
{
this->up = NULL;
last->up = this;
this->down = last;
//struct rclist *x = this->up;
//x->down = this;
}
else
{
this->down = NULL;
this->up = this;
}
}
else
{
printf("Memory allocation error!\n");
exit(-1);
}
}
else
{
printf("Memory allocation error!\n");
exit(-1);
}
return this;
}
struct rclist *find_next_node(struct rclist *root)
{
if ( (root != NULL) )
{
if (root->up == NULL)
{
return NULL;
}
return root->up;
}
}
struct rclist *find_node_at(struct rclist *root, int pos)
{
int i = 0;
root = find_first_node(root);
while( (root) != NULL)
{
if(pos==i)
{
return root;
}
root = root->up;
i++;
}
return NULL;
}
struct rclist *find_first_node(struct rclist *root)
{
if ( (root != NULL) )
{
if (root->down == NULL)
{
return root;
}
root = find_first_node(root->down);
}
return root;
}
struct rclist *find_last_node(struct rclist *root)
{
if ( (root != NULL) )
{
if (root->up == NULL)
{
return root;
}
root = find_first_node(root->up);
}
return root;
}
void print_node(struct rclist *root)
{
if ( (root != NULL) )
{
printf("%s \n", root->s);
}
}
void print_list(struct rclist *root)
{
if ( (root != NULL) )
{
printf("%s \n", root->s);
if (root->up == NULL)
{
return;
}
print_list(root->up);
}
}
|
|
|
|
03-22-2008, 11:20 AM
|
#2
|
|
Member
Registered: Jun 2004
Posts: 233
Original Poster
Rep:
|
Yip, a copy typo!
This function now reads as:
Code:
struct rclist *find_last_node(struct rclist *root)
{
if ( (root != NULL) )
{
if (root->up == NULL)
{
return root;
}
root = find_last_node(root->up);
}
return root;
}
|
|
|
|
03-22-2008, 11:21 AM
|
#3
|
|
Member
Registered: Oct 2005
Posts: 970
Rep: 
|
Code:
void rclist_append(char *s, struct rclist *root)
//struct rclist *rclist_append(char *s, struct rclist *root)
{
root = find_last_node(root);
struct rclist *r;
if((r = (struct rclist*) malloc(sizeof(struct rclist))) != NULL)
{
if((r->s = (char*) malloc(strlen(s) + 1)) != NULL)
{
strcpy(r->s, s);
r->up = NULL;
root->up = r;
r->down = root;
}
}
//return r;
}
Why are you finding the last node and then inserting at the head?
|
|
|
|
03-22-2008, 11:23 AM
|
#4
|
|
Member
Registered: Jun 2004
Posts: 233
Original Poster
Rep:
|
It's surely not? It creates new, then points last to it!
|
|
|
|
03-22-2008, 11:31 AM
|
#5
|
|
Member
Registered: Oct 2005
Posts: 970
Rep: 
|
Sorry that was incorrect but it does look funky.
Code:
void rclist_append(char *s, struct rclist *root)
//struct rclist *rclist_append(char *s, struct rclist *root)
{
/*root becomes the last node or null as root may have been null*/
root = find_last_node(root);
struct rclist *r;
if((r = (struct rclist*) malloc(sizeof(struct rclist))) != NULL)
{
if((r->s = (char*) malloc(strlen(s) + 1)) != NULL)
{
strcpy(r->s, s);
/*new node's previous is null*/
/*which says to me that it is now the root*/
r->up = NULL;
/*old last node previous is now the new*/
/*what happened to it previous that was there before*/
root->up = r;
/*new node which has no previous now sets its next as the node which was the last */
r->down = root;
}
else/*oops memory leak need to free r*/
{
}
}
//return r;
}
Last edited by dmail; 03-22-2008 at 11:32 AM.
|
|
|
|
03-22-2008, 11:36 AM
|
#6
|
|
Member
Registered: Jun 2004
Posts: 233
Original Poster
Rep:
|
Yes, the error checking will be similar to 'add_node()' (in original e.g.).
Cheers
|
|
|
|
03-22-2008, 11:41 AM
|
#7
|
|
Member
Registered: Oct 2005
Posts: 970
Rep: 
|
Maybe it is just me or you can not see what i am saying. If I rename the nodes maybe it will help
Code:
void rclist_append(char *s, struct rclist *root)
{
struct rclist * old_end_node = find_last_node(root);
struct rclist *new_node;
...
new_node->up = NULL;
old_end_node->up = new_node;
new_node->down = old_end_node;
...
}
edit: anyway why traverse list to insert at the end when a list is an unsorted structure, just take pass the address of the head of the list and insert at the head.
Last edited by dmail; 03-22-2008 at 11:44 AM.
|
|
|
|
03-22-2008, 11:54 AM
|
#8
|
|
Member
Registered: Jun 2004
Posts: 233
Original Poster
Rep:
|
That's basically the same code as it is?
The append will also have an alias named 'push', and other functions such as pop, insert_at, remove_at, foreach(funcp), qsort. Maybe this doesn't fit the true name of a list, but since i'm self taught it's descriptive, what would you call it? P.S. This is very loosely based on the glist.h spec...
|
|
|
|
03-22-2008, 12:03 PM
|
#9
|
|
Member
Registered: Oct 2005
Posts: 970
Rep: 
|
Quote:
|
That's basically the same code as it is?
|
REALLY? (yes caps are meant)
Quote:
|
Maybe this doesn't fit the true name of a list, but since i'm self taught it's descriptive, what would you call it
|
Personally I would call it a "messed up list which drops nodes for no good reason, is meant to be a double linked yet will not get to the root if you traverse from the end node".
Reread what you first said:
Quote:
|
However if I do and then try to access the last element it returns the one before
|
Hmmm I wonder why that could be????
Code:
...
old_end_node->up = new_node;
...
|
|
|
|
03-22-2008, 12:16 PM
|
#10
|
|
Member
Registered: Jun 2004
Posts: 233
Original Poster
Rep:
|
Quote:
|
Personally I would call it a "messed up list which drops nodes for no good reason, is meant to be a double linked yet will not get to the root if you traverse from the end node".
|
For that I have a looped list, also have a specific stack and tree.
Also:
Quote:
|
old_end_node->up = new_node;
|
Is the same as:
The actual error (solution) was as stated somewhere between here and there, all works fine now! I'd added a 'count' function which after appending told me a nine element list only had two elements.
|
|
|
|
03-22-2008, 12:22 PM
|
#11
|
|
Member
Registered: Oct 2005
Posts: 970
Rep: 
|
Quote:
Originally Posted by rubadub
For that I have a looped list, also have a specific stack and tree.
Also:
Is the same as:
The actual error (solution) was as stated somewhere between here and there, all works fine now! I'd added a 'count' function which after appending told me a nine element list only had two elements.
|
Ok here is a tip for you, actually read what is being posted. I have not posted any new code until this point, it has just been your code which I have just "...rename(d) the nodes..."
Psuedo for what you want
Code:
append at end(node*)
old_end = find last node
new_end
fill new_end with details
set the old end nodes next pointer to the new node
set the new end node previous pointer to the old end node
set the new ends node to NULL
and the actual code without error checking
Code:
void rclist_append_to_end(char *s, struct rclist *root)
{
struct rclist *old_end = find_last_node(root);
struct rclist *new_end = malloc(sizeof(struct rclist));
new_end->s = malloc(strlen(s) + 1));
strcpy(new_end->s, s);
old_end->down = new_end;
new_end->up = old_end;
new_end->down = 0;
}
Last edited by dmail; 03-22-2008 at 12:23 PM.
|
|
|
|
03-22-2008, 12:43 PM
|
#12
|
|
Member
Registered: Jun 2004
Posts: 233
Original Poster
Rep:
|
The only difference I can see between your code and mine is that you go down and I build up, which beyond semantics is irrelevant? I first used lists with gl transform lists (which are basically stacks) so I find it natural to build up and not build down. Or is there another difference that i'm missing?
|
|
|
|
| Thread Tools |
Search this Thread |
|
|
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
All times are GMT -5. The time now is 10:24 AM.
|
|
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.
|
Latest Threads
LQ News
|
|