【问题标题】:Order in linked lists sometimes works and sometimes doesn't. Very weird链表中的顺序有时有效,有时无效。很奇怪
【发布时间】:2020-09-11 03:04:27
【问题描述】:

此代码只是尝试创建字符的链接列表。奇怪的是,有时它有效,有时则无效。我真的不知道为什么。

#include <stdio.h>
#include <stdlib.h>


struct mychar {
    char value;
    struct mychar *nextPtr;
};

typedef struct mychar Mychar;


void insert(Mychar **, char );
void printlist(Mychar *);

int main(){
    Mychar *startPtr = NULL;

    while (1) {
        char letter;
        printf("\nScrivi il carattere da aggiungere: ");
        scanf("\n%c", &letter);

        insert(&startPtr, letter);

        printlist(startPtr);
    }
}


void insert(Mychar **sPtr, char newvalue){
    Mychar *newnodePtr = calloc(1, sizeof(Mychar));
    if (!newnodePtr){
        printf("\n\nError in memory allocation.\n\n");
        return;
    }
    newnodePtr->value = newvalue;

    Mychar *previousPtr = NULL;
    Mychar *currentPtr = *sPtr;

    while ( currentPtr!=NULL && newvalue > (currentPtr->value) ){
        previousPtr = currentPtr;
        currentPtr = currentPtr->nextPtr;
    }

    if (previousPtr==NULL){
        newnodePtr->nextPtr = NULL;
        *sPtr = newnodePtr;
    } else {
        previousPtr->nextPtr = newnodePtr;
        newnodePtr->nextPtr = currentPtr;
    }
}

void printlist(Mychar *sPtr){
    Mychar *currentPtr = sPtr;
    while (currentPtr!=NULL){
        printf("%c", currentPtr->value);
        currentPtr = currentPtr->nextPtr;
    }
}

Output1(似乎不起作用,添加小写字母后所有节点都消失了):

Write the char to add: a
a
Write the char to add: b
ab
Write the char to add: c
abc
Write the char to add: z
abcz
Write the char to add: a
a
Write the char to add: b
ab
Write the char to add: z
abz
Write the char to add: a
a
Write the char to add: ^C

输出 2(似乎有效):

Write the char to add: A
A
Write the char to add: B
AB
Write the char to add: C
ABC
Write the char to add: a
ABCa
Write the char to add: z
ABCaz
Write the char to add: a
ABCaaz
Write the char to add: b
ABCaabz
Write the char to add: Z
ABCZaabz
Write the char to add: ^C

另外,我想释放退出程序时创建的所有节点(例如使用 Ctrl+c)..

如何释放所有动态分配的节点?

【问题讨论】:

  • 与您的问题无关,但在您验证newnodePtr 不为空之前,您不应分配newnodePtr-&gt;value = newvalue;
  • 您的新节点的nextPtr 值在进行中间或头部位置插入时未正确设置。而且仅供参考,在解决您的问题时,插入可以变得相当简单。顺便说一句,简单的复制案例。只是重复添加'a'
  • @MOehm 好吧,你是对的。编辑它!
  • @WhozCraig 怎么样?
  • 遍历列表和free(p)内存。但请注意不要将地毯从脚下拉开:您应该将下一个链接存储在临时变量中,以便在删除 p 后访问 p-&gt;next

标签: c pointers data-structures struct linked-list


【解决方案1】:

如果节点将成为新的列表头,您的代码没有正确连接新节点的nextPtr 成员。您可以通过这样做来解决这个问题,并显着简化插入:

void insert(Mychar **sPtr, char newvalue)
{
    while (*sPtr && (*sPtr)->value < newvalue)
        sPtr = &(*sPtr)->nextPtr;

    Mychar *newPtr = malloc(sizeof *newPtr);
    if (!newPtr)
    {
        perror("Failed to allocate new node");
        return;
    }
    newPtr->value = newvalue;
    newPtr->nextPtr = *sPtr;
    *sPtr = newPtr;
}

这种技术的额外好处是可以隐式处理所有插入情况,包括头部、中间和尾部位置。

既然你问过如何释放列表,上面的代码应该会给你一些见解,但它可能看起来像这样:

void freelist(Mychar **sPtr)
{
    while (*sPtr)
    {
        Mychar *tmp = *sPtr;
        *sPtr = tmp->nextPtr;
        free(tmp);
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-05-03
    • 1970-01-01
    • 2015-02-11
    • 2012-08-02
    • 2015-03-31
    • 1970-01-01
    • 1970-01-01
    • 2023-03-19
    相关资源
    最近更新 更多