c - 双向链表C,在特定位置插入

标签 c struct linked-list doubly-linked-list

我真的需要一些关于我已经努力了几天的地址簿程序的帮助。我正在使用 C 中的双向链表。我试图在用户输入的位置处将节点添加到列表中,从位置 0 开始。位置不会输入超出范围。 (在位置 0 处的某些内容之前没有在位置 1 处插入,等等)但是这些位置可以重复:将新节点插入到前一个位置占用者之前的位置中。 (例如:如果位置 1 有 x,并且新节点在位置 1 处插入 y,则位置 1 现在有 y,位置 2 有 x)

我需要获取用户输入的职位编号并检索该职位的当前人员,但我不能完全正确。另外,如果您也想看看我的插入功能,我已经包含了它,因为它也无法正常工作。感谢您的帮助!

编辑:现在的主要问题是,当位置 == 1 时,我查找 pPersonCur 的代码失败。此外,插入函数没有按正确的顺序输入内容(位置中的最新插入不会取代旧的插入)正确插入)。然而,损坏的 pPersonCur 代码使得很难诊断到底为什么会这样。

addressbook.h 摘录:

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

addressbook.c 摘录:

#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 摘录:

#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 */

最佳答案

看来您从未给 pFirst 赋值.
当位置不是0时线路pPersonCur = pFirst->pNext;被执行并且 pFirst这个地方依然是NULL

向插入函数添加一个条件,以检查列表的头部是否已分配。

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);
}

尽管如此,如果您碰巧调用InsertPersonNULL参数,您的代码将添加新的 Person在第一个之后并删除列表的其余部分。

放置新的Person当使用 NULL 调用时到列表末尾你可以在你的 InsertPerson 中使用类似的东西功能:

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

如果您给出的位置索引高于列表中的节点,则根据位置索引插入也可能会失败。还应该添加某种安全检查。

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

此实现将添加新的 Person如果位置索引太高,则移至列表末尾。

关于c - 双向链表C,在特定位置插入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27258925/

相关文章:

c++ - socket::send 后程序在没有核心文件的情况下退出

c - asm 中的不可能约束

c - 以下函数中s1->top的移动和起点,push、display和pop

c - 为 char 分配额外内存而不是为已分配结构中的 int 分配额外内存?

在每个数据字段中复制一个数组到链表

c - 使用双指针将字符串转换为链表

c - 严格混叠警告和tcpdump示例代码

c++ - 编译器会偷偷增加结构的对齐吗?

c# - 摆脱不安全的代码,从字节编码 uint 数组?

c - 链表辅助