【问题标题】:Linked List - how to tail insert without moving head node链表 - 如何在不移动头节点的情况下进行尾部插入
【发布时间】:2015-09-26 01:51:20
【问题描述】:

所以我遇到了问题。我知道它是什么。我只是想不出一种方法来解决它允许做什么..

首先是我的尾部插入函数

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 是 struct Node 的公共版本。

这是头文件

#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;
}

【问题讨论】:

  • 有无数的链表实现运行良好;为什么要自己写?或者,如果您真的想/需要自己编写,为什么不看看现有的实现之一?
  • 我没有自己写这是我老师给我的,所以我必须使用这个骨架。
  • head 存储在一个临时的head_ptr 中并使用它。
  • ^ 你意识到我已经这样做了

标签: c linked-list queue


【解决方案1】:

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

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

现在,好吧,就是这样。您不必为了在最后添加而遍历整个列表。唯一的问题是,在插入(和删除)时,您必须保持 tailhead 向上,如下所示。

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;
}

希望这会有所帮助。

【讨论】:

  • 你用那个替换了什么结构?在这种情况下我如何跟踪尾巴? MY_QUEUE 没有数据或下一个。它是一个公共版本。它不完整,因为它需要结构节点才能工作。不知道你对不透明物体有多熟悉
  • 我添加了一个示例,说明如何附加新元素(即在尾部插入),以跟踪尾部。如您所见,一点也不难。
【解决方案2】:

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

您可以使用临时变量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);
  } 

【讨论】:

  • 谢谢。有效。我可以得到有关销毁功能的提示吗?
  • 你能像append的好尝试一样提供你的destroy函数代码吗?:)
  • 大声笑好的,我会将其编辑到原始帖子中。它的崩溃。我不是这个领域的天才,但这是我最好的尝试。
  • 哦,还有一件事。在struct my_queue_public 中,void(*destroy)(MY_QUEUE* phMy_queue); 需要MY_QUEUE pointer 参数。但是在void destroy(MY_QUEUE queue)的实现中,是传入了MY_QUEUE参数(不是指针)。这就是原因。
  • 它仍然崩溃。老实说,我不知道为什么
猜你喜欢
  • 2021-06-03
  • 1970-01-01
  • 2018-06-19
  • 1970-01-01
  • 2021-05-23
  • 2015-12-14
  • 2016-01-29
  • 2010-12-31
相关资源
最近更新 更多