Doubly Linked List C, insertion at specific position

Chase Hill

I could really use some help with an address book program I've been struggling on for days now. I'm working with a doubly linked list in C. I'm trying to add nodes into the list at user-entered positions, starting with position 0. The positions will not be entered out of range. (no inserts at position 1 before something at position 0 etc.) The positions can be repeated though: inserting the new node in the position before the previous position occupant. (for example: if position 1 has x, and new node is inserted at position 1 with y, position 1 now has y and position 2 has x)

I need to take the user entered position number and retrieve the current person in that position, but I can't quite get it right. Also, I have included my insert function if you wanted to take a look at that as well because it isn't working properly either. Thanks for any help!

EDIT: The main problem right now is that my code for finding pPersonCur is failing when position == 1. Also, the insert function is not entering things in the proper order (the newest insertion in a position does not displace the older insertion correctly). The broken pPersonCur code makes it hard to diagnose why exactly this is, however.

addressbook.h excerpt:

typedef struct person Person;
struct person {
    char lastName[255];
    char firstName[255];
    char email[255];
    char phoneNumber[255];
    Person *pNext;
    Person *pPrev;
};

addressbook.c excerpt:

#include "addressbook.h"

Person * InsertPerson(Person * pPersonCur) {
    Person * pPersonNew;

    /* data gathered for CreatePerson() function here */

    pPersonNew = CreatePerson(pLastName, pFirstName, pEmail, pPhoneNumber);

    if (pPersonCur)
    {
        pPersonNew->pNext = pPersonCur;
        pPersonNew->pPrev = pPersonCur->pPrev;
        pPersonCur->pPrev = pPersonNew;
        if (pPersonNew->pPrev)
            pPersonNew->pPrev->pNext = pPersonNew;
    } else
    {
        pPersonNew->pPrev = pFirst;
        pPersonNew->pNext = NULL;
        if (pFirst)
            pFirst->pNext = pPersonNew;
    }
    return (pPersonNew);
}

main.c excerpt:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "addressbook.h"

Person *pFirst;    /* First name in list */

int main(void) {

        Person *pPersonCur = NULL;    /* current Person */ 
        int bDone = 0, position = 0, counter = 0;

        pFirst = NULL;

    printf("Ready\n");

    while (!bDone) {
        char input = getchar();
        switch (input) {
        case 'a':
            counter = 0;
            scanf("%d", &position);    /* Where desired position is entered */
            if (position == 0) {
                if (pFirst) {
                    if (pFirst->pNext) {
                        pPersonCur = pFirst->pNext;
                    }
                } else {
                    pPersonCur = pFirst;
                }
            } else {
                pPersonCur = pFirst->pNext;
                while (counter < position) {
                    pPersonCur = pPersonCur->pNext;
                    counter++;
                }
            }
            InsertPerson(pPersonCur);    /* Takes in person at desired position, return value is new inserted person */
            break;
        /* Some other cases here */
        case 'q':
            bDone = 1;
            break;
        }
    }
/* Rest of code */
Laurynas Lazauskas

It seems so that you never assign a value to pFirst.
When position is not 0 the line pPersonCur = pFirst->pNext; is executed and pFirst in this place is still NULL.

Add a condition to your insert function to check whether list's head is assigned.

Person * InsertPerson(Person * pPersonCur) {
    . . . 
    else
    {
        pPersonNew->pPrev = pFirst;
        pPersonNew->pNext = NULL;
        if (pFirst)
            pFirst->pNext = pPersonNew;
        else
            pFirst = pPersonNew; // If pFirst is not assigned, assign it to newly created person
    }
    return (pPersonNew);
}

Despite that, if you happen to call InsertPerson with NULL argument, your code would put new Person after the first one and cut the rest of the list off.

To put new Person to the end of the list when called with NULL you could use something like this in your InsertPerson function:

if(pFirst) {
    Person *last = pFirst;
    while(last->pNext != NULL) {
        last = last->pNext;
    }
    last->pNext = pPersonNew;
    pPersonNew->pPrev = last;
}
else
    pFirst = pPersonNew;

Insertion according to position index might fail as well if you give a position index that is higher than there are nodes in the list. Some sort of safety check should be added as well.

pPersonCur = pFirst->pNext;
while (counter < position && pPersonCur->pNext != NULL) { // If last node reached, stop the loop
    pPersonCur = pPersonCur->pNext;
    counter++;
}

This implementation would add new Person to the end of the list if position index is too high.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related