【问题标题】:Creating a linked list to implement a queue创建链表实现队列
【发布时间】:2014-10-07 15:53:11
【问题描述】:

我是 C 的新手,我正在尝试编写一个链表,其中每个节点只包含一个 int。结构体的定义是可以的,但是我也想写方法来更新这个链表(在尾部添加元素并删除头部元素)。 (我希望能够读取最近添加的元素)

我写了下面的函数,但是我不知道free应该在哪里以及如何实现。谁能帮我解决这个问题?

typedef struct Node{
    Node next = NULL;
    int number;
} Node;

void add_node(Node *LL,int val){ 
    // add node to the end of the linked list
    new_node = (struct Node *)malloc(1*sizeof(struct Node));
    new_node->number = val;
    Node n = *LL;
    while (n.next != NULL){
        n = n.next;
    }
    n.next = new_node;
}

void delete_head(Node *LL){
     // update the head
    *LL = LL->next;
    //free?
}

void update_LL(*LL,int val){
    add_node(*LL,val);
    delete_head(*LL);
}

【问题讨论】:

  • Node next = NULL; --> struct Node *next; in C.
  • 正如所写,无法从delete_head 中更新头部:它传递了一个指向头部节点的指针,但不知道该值存储在哪里,因此无法更新它.您可以(正如许多人所解释的那样)删除该节点,但是跟踪头的任何内容都需要更新为新头。

标签: c linked-list


【解决方案1】:

我这样重命名你的数据结构:

struct pointer
            {
            int field; 

            struct pointer *link; 
            };
typedef struct pointer cell;  

那么我们可以根据您的需要使用这个功能:

void ad_an_element_at_the_end_of_the_list()
         {
         cell *p=NULL;
         cell *ptr=head;

         int value;

         cout<<" Integer number to insert at the end of the list: ";
         cin>>value;
         p=(cell*)malloc(sizeof(cell));
         p->field=value;
         p->link=NULL;
         if(ptr==NULL) 
            {
            ptr=p;
            head=ptr;

            }else
                {
                if(ptr->link==NULL)  t
                  {
                  ptr->link=p;
                  head=ptr;

                  }else
                     {
                      while(ptr->link!=NULL) 
                        {
                        ptr=ptr->link;
                        }
                     ptr->link=p;

                    }
            }
    }

【讨论】:

    【解决方案2】:

    尝试将*LL = LL-&gt;next; 更改为Node *nextNode = LL-&gt;next;。 然后您可以拨打free(LL),然后拨打LL = nextNode。

    void delete_head(Node *LL){
        Node *nextNode = LL->next;
        free(LL);
        LL = nextNode;
    }
    

    然后释放头部的Node 并将指针移动到链接列表中的下一个。

    【讨论】:

    • 由于LL 实际上是一个局部变量,这将不会移动头部。
    • @ScottHunter 自从我使用 C 以来已经有一段时间了,但这是否可以通过传递引用来解决(在将变量传递给函数时,在变量前使用 &amp; 符号)?跨度>
    • 我认为你应该回顾一下“通过引用”和“通过值”是如何完成的。如果一个指针作为参数传递,它指向一个内存位置,无论哪个范围内的任何函数对该内存位置执行的任何操作都是永久性的。
    • @MurtazaZaidi ^ 这是我最初的理解
    • @AeroX:不;那么你将传递一个指向节点的指针,并且类型不匹配。但是,如果LL 被声明为Node **LL,并且代码引用*LL 作为指向Node 的指针,那么这将起作用。
    【解决方案3】:

    在删除当前节点之前,您需要保存指向下一个节点的链接。否则,您将无法引用链表的任何节点。现在,当您将链接备份到下一个节点时,您可以释放 LL 指向的当前节点,然后将 LL 指针分配给您之前在 temp 指针中备份的下一个节点。

    Node *temp = LL->next;
    free(LL);
    LL = temp;
    

    【讨论】:

    • 由于LL 实际上是一个局部变量,这将不会移动头部。
    • @ScottHunter 请查看此nongnu.org/c-prog-book/online/x641.html
    • 如果一个指针作为参数传递,它指向一个内存位置,无论在哪个范围内的任何函数对该内存位置执行的任何操作都是永久的。
    • 但是传递的指针指向一个节点,因此您可以更改该节点,但不能更改指向它的原始变量(这就是 head )。要做到,您需要分配给*LL;在此函数内对LL 的更改对函数外没有影响。
    • 我认为你需要回顾一下你的指针知识。如果 p 是一个指针,它指向某个内存位置,我们使用 p 直接在该内存位置进行更改。现在这种变化是永久性的。如果我释放该内存位置,则存储在那里的所有数据现在都会丢失,如果我在该位置更新值,则新值将是永久的,而不是特定于功能范围。
    【解决方案4】:

    可能是这个问题的重复LinkedList - How to free the memory allocated using malloc

    基本上,您必须存储指向要删除的节点的指针,否则您将泄漏该内存,因为在您的代码中的任何地方都不会引用该内存位置。

    在你的 delete_head 函数中试试这个:

    节点 *temp = LL;

    *LL = LL->下一个;

    免费(LL);

    希望这会有所帮助!

    【讨论】:

    • temp 和 *LL 的类型不同;就此而言,*LL 和 LL-&gt;next 也不行。
    • 别相信我;询问编译器。
    • 好的,因为它在 Node 类中被声明为 Node 而不是节点指针,所以我把事情搞混了。假设将其更改为 Node 指针以便可以编译,则此解决方案应该可以工作
    猜你喜欢
    • 2018-05-17
    • 1970-01-01
    • 2011-06-28
    • 2021-05-20
    • 2020-04-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多