c - 我的链表代码有什么问题?

标签 c linked-list

问题已解决:)

我希望你能帮助解释我做错了什么。

提前致谢!

代码:

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

typedef struct node {
    char *data;
    struct node * previous;
    struct node * next;
} node, *nodePTR;

/* Insert into list */
void insert(char * buf, nodePTR tail) {
    nodePTR myNode;
    myNode = (node *)malloc(sizeof(node));

    myNode->data = malloc(sizeof(char) * 10);
    strcpy(myNode->data,buf);
    myNode->next = NULL;
    myNode->previous = tail;
    tail->next = myNode;
    //tail = tail->next;
}

void printlist(nodePTR head, int numElements) {
    nodePTR tmpNode;
    tmpNode = head;

    printf("\n\n");

    while(tmpNode!=NULL) {
        printf("Node data: %s\n", tmpNode->data);
        tmpNode = tmpNode->next;
    }
}

int main(void) {
    /* Variables */
    int numElements;
    int i;
    char buf[10];

    nodePTR head, tail;

    tail = (node *)malloc(sizeof(node));
    head = (node *)malloc(sizeof(node));

    tail->data = "EMPTY\0";
    tail->next = NULL;
    tail->previous = NULL;

    head = tail;

    printf("Please enter the number of elements:\n");
    scanf("%d", &numElements);

    /* Build the list */
    for(i = 0; i < numElements; i++) {
        printf("Please enter the data:");
        scanf("%s", buf);
        insert(buf, tail);
        tail = tail->next;
    }

    printlist(head, numElements);

    return 0;
}

这是我的输出:
请输入元素数量:
3
请输入数据:n1
请输入数据:n2
请输入数据:n3

节点数据:空
节点数据:n3

最佳答案

我通常尝试将头部和尾部保留为 NULL,直到插入元素,而不是尝试检测整个位置的空节点。其中包括我使用的一个非常简单的链表的示例。请注意,此版本适用于微 Controller ,因此我在列表函数之外分配/释放内存(有时来自预分配的节点池):

struct ListNodeStruct
{
  struct ListNodeStruct* Next;
  int Value;
};
typedef struct ListNodeStruct ListNode;

struct ListStruct
{
  ListNode* Head;
  ListNode* Tail;
  int Count;
};
typedef struct ListStruct List;

List CreateList()
//creates a new List
{
  List R;
  R.Head = NULL;
  R.Tail = NULL;
  R.Count = 0;
  return(R);
}

void ListInsertFirst(List* L, ListNode* V)
//insert the object at the start of the list
{
  V->Next = L->Head;
  L->Head = V;
  if (L->Count == 0)
    L->Tail = V;
  L->Count ++;
}

void ListInsertLast(List* L, ListNode* V)
//insert the object at the end of the list
{
  V->Next = NULL;
  if (L->Tail)
    L->Tail->Next = V;
  else
    L->Head = V;
  L->Tail = V;
  L->Count++;
}

ListNode* ListRemoveFirst(List* L)
//remove the first object in the list (no memory is freed)
{
  ListNode* R = L->Head;

  if (L->Head == NULL)
    return(R);

  L->Head = L->Head->Next;
  L->Count--;
  if (L->Count == 0)
    L->Tail = L->Head;
  return(R);  
}

具体到您的代码,当您将对象视为黑盒时,除了允许看到内部的函数之外,可以避免一些问题。具体来说,主函数的开头以及第 69 行直接操作列表成员。我通常尝试有一个专用于初始化对象的函数,因为当您使用列表时,您必须在许多地方再次执行此操作。

在第 54 行,您将指向字符串文字的指针插入结构中。该指针仅在当前堆栈帧上有效,这意味着当函数退出时该指针将不再包含“EMPTY\0”。您应该调用 malloc 并将其存储在那里,并且不要忘记释放。另请注意,C 会自动以 null 终止字符串文字,因此您不需要在末尾添加\0。

最后,它可能无法在打印函数中正确迭代的原因是因为您从尾部而不是头部开始打印迭代器。

关于c - 我的链表代码有什么问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10466597/

相关文章:

c - 实现线性搜索

C-Linux-如何将C参数值发送给awk脚本?

c - 此代码正在生成段核心转储

java - Java 中克隆列表元素

java - 节点 "dynamic"是变量吗?

c - kernel hashtable.h 哈希表的动态大小

c++ - HDF5:如果 Fletcher32 校验和过滤器在数据输入时失败会怎样?

c - 在 Linux 内核中赋值两个值

java - 将项目移动到 LinkedList 的前面

java - 如何读/写文件中具有链表的对象