当前位置: 首页 > 知识库问答 >
问题:

链表-如何在不移动头部节点的情况下进行尾部插入

宋鸿德
2023-03-14

所以我遇到了一个问题。我知道那是什么。我就是想不出一个办法来解决这个问题。。

首先是我的尾部插入函数

Status append(MY_QUEUE queue, int item)
{
    Node_ptr temp;
    Head_ptr head = (Head_ptr) queue;

    //create a new node

    temp = (Node_ptr)malloc(sizeof(Node));
    if (temp == NULL) {
        printf("malloc failed\n");
        return FAILURE;
    }

    temp->data = item;
    temp->next = NULL;
    if (head->head == NULL){
        head->head = temp;
    }
    else{
        while(head->head->next) {
            head->head = head->head->next;
        }
        head->head->next = temp;
    }
    return SUCCESS;
}

如你所见。它很简单。如果头节点为空。它将新节点添加到头。如果不是。它一直移动头直到它达到空,然后它添加节点。这就是问题所在。我移动头节点指针,我不应该做。但我似乎想不出另一种方法来做。因为我在传递MY_QUEUE。我将包括头文件和声明,以了解这些是什么。

struct node
{
    int data;
    Node_ptr next;

};

struct head_node;
typedef struct head_node Head_node;
typedef Head_node *Head_ptr;

struct head_node
{
    struct my_queue_public methods;
    Node_ptr head;
};

void destroy(MY_QUEUE queue);
Status append(MY_QUEUE queue, int item);
Status service(MY_QUEUE queue);
int* front(MY_QUEUE queue);
Bool empty(MY_QUEUE stack);

void init_functions(MY_QUEUE queue)
{
    //queue->destroy = destroy;
    queue->empty = empty;
    queue->service = service ;
    queue->append = append;
    queue->front = front;
}
MY_QUEUE my_queue_init_default(void)
{
    Head_ptr head;
    head = malloc(sizeof(Head_node));

    if (head != NULL)
    {
        head->head = NULL;
        init_functions((MY_QUEUE)head);
    }
    return (MY_QUEUE)head;
}

插入尾部函数是追加函数。我不能改变我的参数或我返回的内容。我只需要改变函数内部的内容。

MY_QUEUE是结构节点的公共版本。

这是头文件

#include "status.h"
struct my_queue_public;
typedef struct my_queue_public* MY_QUEUE;

struct my_queue_public
{
    void(*destroy)(MY_QUEUE* phMy_queue);
    Status(*service)(MY_QUEUE hMy_queue);
    Status(*append)(MY_QUEUE hMy_queue, int item);
    Bool(*empty)(MY_QUEUE hMy_queue);
    int* (*front)(MY_QUEUE hMy_queue);
};

MY_QUEUE my_queue_init_default(void);

顺便说一下,这是一个队列。在最后添加。从前面获取项目。总而言之,头在动,我失去了节点。我知道如何避免它,但我知道的唯一方法是改变我传递的内容。而不是MY_QUEUE。我会通过MY_QUEUE*。有没有另一种方法可以用我所拥有的来做

销毁功能

    void destroy(MY_QUEUE queue)
{

    Head_ptr head = (Head_ptr)queue;

    Node_ptr tmp;

    if (head->head == NULL) {

        return;
    }


    while (head->head !=NULL){
        tmp = head->head;
        head->head = head->head->next;
        free(tmp);
    }

    head->head = NULL;
}

共有2个答案

卢阳泽
2023-03-14

这就是问题所在。我移动头节点指针,我不应该这样做。但我似乎想不出另一种方法来做到这一点。

您可以使用临时变量tail来跟踪链接,而不是移动头部节点,

    Node_ptr tail;
    if (head->head == NULL){
        head->head = temp;
    }
    else{
        //while(head->head->next) {
        //  head->head = head->head->next;
        //  }
        //head->head->next = temp;
        tail = head->head;
        while(tail->next) {
            tail = tail->next;
        }
        tail->next = temp;
    }

为了毁灭功能,

//void destroy(MY_QUEUE queue);
void destroy(MY_QUEQUE *p_queue);//change to this 
                                 //to keep consistent in struct my_queue_public

 void destroy(MY_QUEUE *p_queue)
 {
    Head_ptr head;
    Node_ptr tmp;

   if(p_queue == NULL){
     return;
   }

   if((head = (Head_ptr)*p_queue) == NULL){
     return;
   }    

   if (head->head == NULL) {
     return;
   }

   while (head->head !=NULL){
      tmp = head->head;
      head->head = head->head->next;
      free(tmp);
   }

   free(head);
  } 
寿和通
2023-03-14

我认为问题在于您正在使用struct节点作为队列的数据结构。为什么不使用更专用的版本?

typedef struct queue_struct {
    Node * head;
    Node * tail;
} * MY_QUEUE;

现在,好了,就这样。您不必为了在末尾添加而在整个列表中运行。唯一的问题是插入(和移除)时,您必须保持尾部以及头部向上,如下所示。

Status append(MY_QUEUE queue, int item)
{
    Node_ptr temp;

    // create a new node
    temp = (Node_ptr)malloc(sizeof(Node));
    if (temp == NULL) {
        printf("malloc failed\n");
        return FAILURE;
    }

    temp->data = item;
    temp->next = NULL;

    if (queue->head == NULL){
        queue->head = temp;
        queue->tail = temp;
    }
    else {
        queue->tail->next = temp;
        queue->tail = temp;
    }

    return SUCCESS;
}

希望这能有所帮助。

 类似资料:
  • 我第一次使用链表,必须创建一个可以在双链表末尾插入节点的函数。到目前为止我 Node类按顺序接受要存储的值、要指向的下一个指针的值和上一个指针的值。每当我试图在这里插入节点时,我都会得到一个错误,说有一个未处理的异常,并且在写入位置0x00000008时有访问冲突。 我不完全确定这里出了什么问题,但我认为这与根据错误消息取消引用空指针有关。我真的很感激有人帮忙解决这个问题。

  • 我正在玩一个链接列表类项目的指针,我不知道如何创建到新节点的链接。我有一个类,它包含像这样的方法来操作数据结构。我希望这些节点是从csv文件中读取的出价。 当我从CSV加载所有数据时,我想 创建一个新的出价 将新的出价传递给函数 设置Bid对象的nextBid指针,并更新链接列表的尾部 我将不胜感激为每个出价对象创建新地址的任何指针,因为现在尾节点只'记得'第一个出价的地址。 我复制了下面的代码,

  • 我用C语言编写了双重链接列表的代码,它从头到尾的遍历很好,但从尾(end)到头的遍历陷入了无限循环,只打印最后一个节点的数据,我不知道出了什么问题。

  • 我的插入方法解释:我分配了尾巴的“下一个变量”来保存旧节点的地址。我分配了尾部,并将新节点插入列表。 我试着从尾部开始显示列表,然后遍历列表,直到列表到达头部。 问题:但是输入显示C,这不是我想要的。显示方法应显示C、B、A。 我甚至在纸上调试我的代码。我不知道为什么显示器没有检索链接列表中链接的节点的最后地址。它仅检索列表中的最后一个节点,并仅显示列表中的最后一个节点。

  • 问题内容: 我需要用Java编写一个将链表中的第一个元素移动到最后位置的方法。 为此,我相信我必须设置一个节点以引用head之后的第一个元素,然后将下一个节点设置为null。我尝试使用我的方法执行此操作,但是在运行该方法时,输出不正确。 我所剩的班级太多了,无法在此处发布,但是我认为我只需要在概念化如何将第一个元素移到列表末尾方面提供帮助。 我写的方法是: 问题答案: 您要删除列表的开头并使其成为

  • 而这是我的主课,有没有其他方法做得更有效率?