繁体   English   中英

将元素插入到双向链接列表的末尾

[英]Inserting an element to the end of the doubly-linked list

我正在编写一个程序,该程序可以将元素插入列表的末尾,并显示其中之一。 它可以正确插入,但是我可以显示指定的一个。

typedef struct Node
{
        int data;
        struct Node *next;
        struct Node *prev;
} node;

void insert(node *head, int data)
{
        node *newNode = (node*) malloc(sizeof(node));
        newNode->data = data;
        newNode->next = NULL;

        if(head == NULL)
        {
            head = newNode;
        }
        else
        {
            while(head != NULL)
                head = head->next;

            head->next = newNode;
            (head->next)->prev = head;
        }
}

void print(node *head, int element)
{
    node *temp = head;
    int count = 0, i = 1;
    while(i < element)
    {
        temp = temp->next;
        i++;
    }
    printf("%d", temp->data);
}

int main()
{
        node *start = (node*) malloc(sizeof(node));
        start = NULL;

        int data1 = 4, data2 = 5;
        insert(start,data1);
        insert(start,data2);

        print(start, 1);
}

为什么不起作用? 另外,您能告诉我我是否做得正确吗?

这是因为您通过value传递了start指针。 这意味着insert函数内部对其所做的任何更改都将在该函数返回后丢失。

您可以通过引用传递指针:

void insert(node **head, int data)
{
    /* ... */
    if (*head == NULL)
        *head = newNode;
    else
    {
        /* ... */
    }
}

int main(void)
{
    node *start = NULL;
    insert(&start, 1);
    /* ... */
}

或从函数返回指针:

node *insert(node *head, int data)
{
    /* ... */
    return head;
}

int main(void)
{
    node *start = NULL;
    start = insert(start, 1);
    insert(start, 2);  /* Do not get the returned pointer, as the returned pointer no longer points to the start of the list */
    /* ... */
}

这两个解决方案的问题在于,如果head NULL不是NULL ,则将其更改为指向最后一个节点之前的节点。 insert循环中,您应该使用临时指针。


为安全起见,应检查print功能循环中是否没有NULL节点。 考虑如果传递的数字大于列表中节点的数目,将会发生什么情况。

编辑:我跳过了几行。

请在与您的main()代码段内联的地方查看我的修订注释:

node *start = (node*) malloc(sizeof(node));//You allocate memory here. Good.
start = NULL;//Memory leak. 

//Instead of the above two lines use this
node* start=NULL;

int data1 = 4, data2 = 5;
start=insert(start,data1);//If you want to do it statically, why not write insert(start,4)?
insert(start,data2);
....

我建议在print()函数中添加一个NULL检查。

void print(node *head, int element)
{
    //Null check for the start pointer.
    //If you would have had this here, you'd have never faced such problem.
    if(head == NULL)
    {
      //Handle null
    }
    node *temp = head;
    int count = 0, i = 1;
  ....
}

加上您的insert()我建议:

node* insert(node *head, int data)
{
        node *newNode = (node*) malloc(sizeof(node));
        newNode->data = data;
        newNode->next = NULL;

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

            head->next = newNode;
            (head->next)->prev = head;
            return NULL;
        }
}

希望能帮助到你。

有一个技巧可以使事情变得简单得多,并使您的代码更高效!

诀窍是使用循环列表,并使“ head”节点成为前哨值。 空列表是由既具有单个节点表示prevnext指向其自身。 您永远不需要NULL,并且这种样式大大减少了所需的特殊外壳。 它还使您可以O(1)访问列表的开头和结尾。 磁头的data字段从不使用。 在Knuth的“计算机编程艺术”中对此进行了描述。

通过这种样式,您会得到如下所示:[unested]

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

typedef struct Node {
   int data;
   struct Node *next, *prev;
} node;

void insert_list(node *head, int data) {
  node d = {data, head, head->prev};
  node *new_node = malloc(sizeof(node));
  /* TODO: handle malloc failure */
  *new_node = d;
  head->prev->next = new_node;
  head->prev = new_node;
}

node *get_list(node *head, int n) {
  node *node = head;
  int i;
  for (i = 0; i <= n; i++) {
    node = node->next;
    if (node == head) {
      /* TODO: handle out-of-bounds index */
    }
  }
  return node;
}

void print_list(node *head, int i) {
   printf("%d\n", get_list(head, i)->data);
}

node *new_list(void) {
  node *head = malloc(sizeof(node));
  /* TODO: handle malloc failure */
  head->next = head->prev = head;
  return head;
}

int main(int argc, char**argv) {
  node *list = new_list();
  insert_list(list, 10);
  insert_list(list, 20);
  print_list(list, 0);
  print_list(list, 1);
  return 0;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM