Thread: C Structures and Linked Lists.

  1. #1
    Registered User
    Join Date
    Apr 2003
    Posts
    7

    C Structures and Linked Lists.

    Hi,

    I want to create a C program that will do two functions as a part of a hospital waiting list.
    Data storage must be dynamic, so linked lists are the way to go.

    typedef structure
    {
    int rank;
    char name;
    structure *next;
    } PATIENTS;

    1: Record Patient.
    This is accept one interger (the rank) and one string (the name).
    The string is added to the list in priority order. '1' being the highest. You can have multiple people on the same rank.

    2: Consult Patient.
    This will accept a single interger (the rank).
    This will remove the patient from the list with the highest priority value from the list. When there are more then one patient with the same rank, the earliest patient to arrive will be consulted.
    Eg: each rank will act like FIFO list.
    The function will return a patient's name.

    I hope someone can help me.

  2. #2
    Registered User Vber's Avatar
    Join Date
    Nov 2002
    Posts
    807
    >>This is accept one interger (the rank) and one string
    No, no, no you're getting a char, not a string, for getting a string declare it as char *name, or char name[SIZE], your just declaring it as a char... char name.

  3. #3
    Registered User
    Join Date
    Apr 2003
    Posts
    7

    C structures and linked list

    hello again:

    typedef structure
    {
    int rank;
    char name[40];
    structure *next;
    } PATIENTS;


    I have some knowledge of linked lists, but I can't get the int (rank) passed properly and correctly entered into the structure.

    How do you pass a interger into a structure?

    enter patient(int *rank, char[] )
    {
    PATIENTS current

    current.rank->rank
    current.name->name;
    }

  4. #4
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Code:
    struct mystruct
    {
        signed short int myssint;
    };
    
    ...stuff...
    
    struct mystruct myInstance, *myPtr;
    
    /* Accessing members directly: */
    myInstance.myssint = 10;
    
    /* Accessing members via pointer: */
    myPtr = &myInstance;
    
    myPtr->myssint = 11;
    Is that what you were looking for?

    Quzah.
    Hope is the first step on the road to disappointment.

  5. #5
    bobthebuilder
    Guest

    my program so far:

    hello.

    each 'rank' in the patients will be in FIFO list.
    so, here is an example of the order of structure would be:

    1 Gary
    1 Fred
    1 Luke
    2 Benny
    4 Henry
    7 Daniel
    7 Clyde
    9 Ned

    create patient(int rank, char *name, head etc)
    {

    PATIENT list;


    // if the 'rank' entered is smaller than the first head 'rank' make the new rank the head.

    (if rank < head->rank)
    {
    temp = head;
    head = list;
    list->rank = rank;
    list->name = name;
    list->next = temp;
    }

    //if the rank is bigger we need to loop until we find its correct position in the field.

    //we need to temp store the previous patients record so we can link the next address to the start of the new patients record.

    while ( list->next != NULL && list->rank <= rank)
    {
    list = list->next;
    }
    temp = list; //temp store patient that goes before new patient
    list->rank = rank;
    list->string = string;
    list->next = temp;

    //if the patients rank is equal is the stored rank, it will have to find the last rank of the same number and be added to the list after that one but before the start of the next rank.

    while (list->rank == rank)
    {
    list=list->next;
    }
    temp = list; //temp store patient that goes before new patient
    list->rank = rank;
    list->string = string;
    list->next = temp;

    ----------------

    i am beginning to think that i may need a *prev pointer in the structure to go back one record....

    am i doing this correctly, or am i way off in my coding?

    cheers.

  6. #6
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    i am beginning to think that i may need a *prev pointer in the structure to go back one record....
    You don't need a previous pointer, but double linked lists are infinitely easier than single linked lists when it comes to node removal, insertion, etc. I always use double linked lists over single.

    Quzah.
    Hope is the first step on the road to disappointment.

  7. #7
    Registered User
    Join Date
    Apr 2003
    Posts
    7

    new nodes are deleted

    hello,

    i've tried inserting the new nodes without a great success.

    when i put a new record in, to make it the new head, it simply re-writes over the previous head:


    NEWMEM *temp;
    NEWMEM *member;
    NEWMEM *temp2;
    if (*head == (NEWMEM *)0)
    {
    printf("\nCreate First Header\n");
    *head = member;
    member = *head;
    member->rank = (int)malloc(sizeof(num));
    member->rank = num;
    member->string = (char *)malloc(strlen(string)+1);
    strcpy(member->string, string);
    member->next = (NEWMEM *)0;
    loop = 1;
    }

    member = *head;
    if (loop ==0 && num < member->rank)
    {
    temp = *head;
    printf("\nNEW HEADER! Store current head as temp\n");
    temp = *head;
    temp->rank == member->rank;
    temp->string== member->string;

    printf("\Storing the new head in temp2\n");
    temp2 = *head;
    *head = temp;
    temp2->rank = (int)malloc(sizeof(num));
    temp2->rank = num;
    temp2->string = (char *)malloc(strlen(string)+1);
    strcpy(temp2->string, string);
    temp2->next = temp;
    temp2 = temp->next;
    temp2->prev = *head;
    }



    I have tried this logically, and to me it seems to work, but in practice is does not.

    Can you offer any suggestions?

  8. #8
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    You probably either need to use a global list pointer, or pass the address of the list pointer (via pointer to a pointer) to your program so you can update the list.

    Or you could just append to the list rather than prepend.

    I tend to use the following:

    Node * newNode( ...data to be in new node );
    Node * getNode( ...data to find... );
    void addNode( Node *toAdd, Node**list );

    [edit]
    There are other functions occasionally, but these three are primarily what you'll probably need. Then do something like:

    n = newNode( somedata );
    addNode( n, &list );

    Or you could shorten it:

    addNode( newNode( somedata ), &list );
    [/edit]

    The second argument of addNode is usually left off, because I tend to use global list pointers. (IE: When all I need is a single linked list for small programs, I just use a global pointer because it's easier.)

    Quzah.
    Last edited by quzah; 04-14-2003 at 07:09 PM.
    Hope is the first step on the road to disappointment.

  9. #9
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    I considered editing my last post, but a new one is really needed here.

    1) Use code tags. Read the nice little sticky post if you don't know how.

    2) What the hell are you doing:
    Code:
    if (*head == (NEWMEM *)0)
    {
        printf("\nCreate First Header\n");
    
        /*A*/
        *head = member;
        member = *head;
    
        /*B*/
        member->rank = (int)malloc(sizeof(num));
        member->rank = num;
    
        member->string = (char *)malloc(strlen(string)+1);
        strcpy(member->string, string);
        member->next = (NEWMEM *)0;
        loop = 1;
    }
    A - Here you're making the node point to itself.

    Make pointer A point to pointer B.
    Make pointer B point to pointer A, which is pointing to pointer B.

    That's what you're doing. That's wrong.

    B - What is 'num'? If it's a pointer, why is it a pointer? You don't need a pointer. It shouldn't be a pointer if it's just an integer of some sort. There's no reason for it to be a pointer.

    If it's a string, you're doing it wrong and you're creating a memory leak.

    [edit]
    Prepending a list to a node works like this:

    newNode->next = listHeader;
    listHeader = newNode;

    If you use a double linked list, you want to set the listHeader's 'prev' pointer to point to 'newNode' inserted between the two steps.

    This code assumes a global pointer called 'listHeader' and a new node called 'newNode'. If you aren't using a global pointer, pass a pointer to a pointer for your listNode, and dereference properly.

    The two steps above need to be done in that order or you'll screw up your list.
    [/edit]

    Quzah.
    Last edited by quzah; 04-14-2003 at 07:19 PM.
    Hope is the first step on the road to disappointment.

  10. #10
    Registered User
    Join Date
    Apr 2003
    Posts
    7

    follow up

    hi quzah,

    thanks for a quick reply.

    part a:
    should go to the start of the list.
    member= *head;

    part b:
    num is the rank of the list.
    the nodes will be placed in ascending order.

    if more than one node has the same number, then the node will be placed after the last node with the same number.

    is this what i should do for part b?


    newmember->rank = (int)malloc(sizeof(num));
    newmember->rank = num;

    newmember->string = (char *)malloc(strlen(string)+1);
    strcpy(newmember->string, string);
    newmember->next = head;
    head = newmember;

  11. #11
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826

    Re: follow up

    Originally posted by bobthebuilder20
    part a:
    should go to the start of the list.
    member= *head;
    No. I already said what you should do.

    Originally posted by bobthebuilder20

    part b:
    num is the rank of the list.
    the nodes will be placed in ascending order.

    if more than one node has the same number, then the node will be placed after the last node with the same number.

    is this what i should do for part b?


    newmember->rank = (int)malloc(sizeof(num));
    newmember->rank = num;

    newmember->string = (char *)malloc(strlen(string)+1);
    strcpy(newmember->string, string);
    newmember->next = head;
    head = newmember;
    Please show me the structure definition for 'member'. Also show me the prototype for the function you're writing.

    Quzah.
    Hope is the first step on the road to disappointment.

  12. #12
    Registered User
    Join Date
    Apr 2003
    Posts
    7

    prototype and structure

    hello quzah,

    my structure is as follows:

    struct list
    {
    int rank;
    char *string;
    struct list *prev;
    struct list *prev_rank;
    struct list *next;

  13. #13
    Registered User
    Join Date
    Apr 2003
    Posts
    7

    prototype and structure

    hello quzah,

    my structure is as follows:

    struct list
    {
    int rank;
    char *string;
    struct list *prev;
    struct list *prev_rank;
    struct list *next;
    struct list *next_rank;
    } LIST;

    prototype:


    LIST *all_mem(int, char *, LIST **head);



    Cheers.

  14. #14
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826

    Re: prototype and structure

    Originally posted by bobthebuilder20
    hello quzah,

    my structure is as follows:

    struct list
    {
    int rank;
    char *string;
    struct list *prev;
    struct list *prev_rank;
    struct list *next;
    struct list *next_rank;
    } LIST;

    prototype:


    LIST *all_mem(int, char *, LIST **head);



    Cheers.
    Previously, you had done the following:
    Code:
     newmember->rank = (int)malloc(sizeof(num));
    newmember->rank = num;
    Since in your function, 'rank' is not a pointer, but is a standard member of said structure, you do not allocate space for it. You only allocate space for items you're dynamicly creating. That is to say, if you have a pointer, and you want it to point to something that hasn't been created, you allocate for it.

    Since every single list structure you create has an integer set aside called rank, you do not allocate space for it. The structure does that automaticly since rank is not a pointer.

    Thus, all you have to do is:
    Code:
    newmember->rank = num;
    For the second answer, I've already given it. Since you're using a pointer to a pointer to update the head of your list, all you do is, in this order:
    Code:
    newmember->next = *listhead;
    *listhead = newmember;
    What this does is first, it makes the next member of the new node point to whatever node is the top of the list.

    Second, it sets the top of the list to be the new node.

    You have to do those two steps in that order. If you don't, this will happen:
    Code:
    *listhead = newmember;
    newmember->next = *list;
    This makes the top of the list be the new node. Since you didn't keep track of what used to be the top first, the old list is lost.

    Second, it then makes the next member of the new node point back at itself.

    That is what you were doing. That is why your list was disapearing.

    Quzah.
    Hope is the first step on the road to disappointment.

  15. #15
    Registered User
    Join Date
    Apr 2003
    Posts
    7

    thankyou for your help

    thankyou for your help it was much appriciated.


Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 8
    Last Post: 12-05-2008, 02:18 AM
  2. problems with structures and linked lists
    By jwillisoa in forum C Programming
    Replies: 7
    Last Post: 07-01-2007, 05:23 PM
  3. C Linked Lists and Structures help!
    By Yorae in forum C Programming
    Replies: 0
    Last Post: 03-07-2006, 09:55 AM
  4. Can i do this: Structures and linked lists help
    By satory in forum C Programming
    Replies: 4
    Last Post: 04-25-2005, 07:49 AM
  5. Linked Lists 101
    By The Brain in forum C++ Programming
    Replies: 5
    Last Post: 07-24-2004, 04:32 PM