【问题标题】:How to build a singly linked list from array in C如何从C中的数组构建单链表
【发布时间】:2020-01-31 11:14:51
【问题描述】:

我正在学习 C 中的单链表并尝试链接数组的组件。我已经写了几行代码,但它没有给出所需的结果,即从数组中制作和打印链表。有人可以解释为什么它不起作用吗?谢谢

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

typedef struct list
{
int data;
struct list *next;
}
list;

list *createlinkedlist(int *arr);

void printlist(list * head);

int main(void)
{
    int arr[]={1,2,3,4,5};
    list *head=NULL;
    head = createlinkedlist(arr);
    printlist(head);

}

list *createlinkedlist(int *arr)
{
    list *head=NULL;
    list *temp=NULL;
    list *p=NULL;

    for (int j=0, O=sizeof(arr); j<O; j++)
        {
            temp= (list*)malloc(sizeof(list));
            temp->next = NULL;

        if(head == NULL)
            head=temp;
        else
        {
            p=head;
            while(p->next!=NULL)
            {
                p=p->next;
            }
            p->next = temp;
        }
    }
return head;
}


void printlist(list *head)
{
    list * p = head;
    while (p !=NULL)
    {
        printf("%d\n", p->data);
        p = p->next;
    }
}

【问题讨论】:

    标签: c arrays singly-linked-list


    【解决方案1】:

    两个问题,

    1. 传递给函数的数组衰减为指针。

      for (int j=0, O=sizeof(arr); j<O; j++)
      

      在这里你循环直到 sizeof 指针而不是实际数组的大小。

      main 本身传递数组大小。

       list *createlinkedlist(int *arr, int length); //prototype becomes
       head = createlinkedlist(arr, sizeof (arr)); // function call becomes
       for (int j=0; j<length; j++) //for loop becomes
      
    2. 您没有将数组内容存储到链表中。

          temp= (list*)malloc(sizeof(list));
          temp->data = arr[j]; //store the content into list
          temp->next = NULL;
      

    【讨论】:

    • 以下是修改后的输出,请分享为什么会显示额外的结果。 1 2 3 4 5 32764 0 0 4335920 0 -1407104105 32652 1 0 -1273182248 32764 0 1 4334304 0
    【解决方案2】:
    #include <stdio.h>
    #include <stdlib.h>
    
    typedef struct list
    {
        int data;
        struct list* next;
    }
    list;
    
    list* createlinkedlist(int* arr, int length);
    
    void printlist(list* head);
    
    void deleteList(list* _list, int length);
    
    int main(void)
    {
        int arr[] = { 1,2,3,4,5 };
        list* head = NULL;
        head = createlinkedlist(arr, 5);
    
        // Result is '1\n,2\n,3\n,4\n,5\n'
        printlist(head);
        deleteList(head, 5);
    
        // Below value is garbage
        printf("%p\n", head->next);
    }
    
    void deleteList(list* p, int length)
    {
        list** nodeArr = (list **)malloc(sizeof(list*) * length);
    
        for (int i = 0; p != NULL; i++, p = p->next)
        {
            nodeArr[i] = p;
        }
    
        for (int i = 0; i <= sizeof(nodeArr); ++i)
        {
            free(nodeArr[i]);
        }
    
        free(nodeArr);
    }
    
    list* createlinkedlist(int* arr, int length)
    {
        list* head = NULL;
        list* temp = NULL;
        list* p = NULL;
    
        // repeat until j == length
        for (int j = 0; j < length; j++)
        {
            temp = (list*) malloc(sizeof(list));
    
            // assign value of arr[j]
            temp->data = arr[j];
    
            temp->next = NULL;
    
            if (head == NULL)
                head = temp;
            else
            {
                p = head;
                while (p->next != NULL)
                {
                    p = p->next;
                }
                p->next = temp;
            }
        }
        return head;
    }
    
    
    void printlist(list* head)
    {
        list* p = head;
        while (p != NULL)
        {
            printf("%d\n", p->data);
            p = p->next;
        }
    }
    
    

    首先,您还没有将数组的值分配到列表中。

    第二,While语句必须重复到arr的长度,而你还没有通过arr的长度。

    ('arr' 是指向数组第一个元素(地址为 1)的 int 指针。并且 sizeof(arr) 是 'int 指针大小',而不是 arr 的长度。)

    因此,您需要将长度放入“createdlinkedlist”的第二个参数中。

    如果你像上面的代码那样修复它,它就可以工作。



    补充一点,你必须调用'free'函数在使用堆内存后返回使用的内存。

    (即使用malloc后)

    在这种情况下,您可以定义“deleteList”函数来释放列表中的所有“下一个”。


    或者,如果你会使用c++,你可以在列表中定义析构函数

    typedef struct list
    {
        int data;
        struct list* next;
    
        ~list (){
            delete next;
        }
    }
    list;
    

    调用列表头的delete调用一系列delete调用链。

    在这种情况下,您必须使用“删除”关键字而不是“免费”功能

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-07-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多