通过函数内部的指针更新链表

时间:2019-04-11 09:54:31

标签: c linked-list

我不知道链表,而是试图创建一个函数,该函数将从链接中取出所有奇数,并使用它们创建一个新的链表。

重点是,我不了解如何通过指向函数的指针来更新原始列表,实际上到目前为止,我所做的是使用奇数创建了一个新列表,但我并不真正理解如何从列表中“删除”它们。原始列表,并将其余所有链接在一起,然后将其发送回主列表。

Node *build_odd_list(Node *oldlst, Node *newlst) {
    Node *temp, *curheadNew;
    temp = (Node*)malloc(sizeof(Node));

    if (oldlst->value % 2 != 0) {
        temp->next = NULL;
        temp->value = oldlst->value;
        newlst = temp;
        curheadNew = newlst;
        oldlst = oldlst->next;
        printf("Passed %d\n", curheadNew->value);
    }
    else {
        oldlst = oldlst->next;
    }
    while (oldlst) {
        if (oldlst->value % 2 != 0) {
            temp = (Node*)malloc(sizeof(Node));
            temp->value = oldlst->value;
            temp->next = NULL;
            curheadNew->next = temp;
            curheadNew = curheadNew->next;
            oldlst = oldlst->next;
            printf("Passed %d\n", curheadNew->value);
        }
        else {
            oldlst = oldlst->next;
        }
    }
    return newlst;
}

非常感谢!

1 个答案:

答案 0 :(得分:1)

由于您需要返回包含奇数的新列表,并由于去除了奇数而修改了原始列表,因此需要将两个值传递回调用者:指向更新后的原始第一个元素的指针列表,以及指向“奇数”列表的第一个元素的指针。

由于您仍然需要将原始列表传递给该函数,因此该函数最简单的选择是:

  • 传递一个指向原始列表第一个元素的指针的指针;
  • 通过指针修改原始列表;
  • 返回一个指针,该指针指向从原始列表中提取的“奇数”列表的第一个元素。

由于“奇数”元素可以从一个列表移动到另一个列表,因此无需为“奇数”列表分配任何新元素。

值得学习“指向指针的指针”技巧,因为它是操作列表指针的常用方法。

这是一个示例程序,用于说明上述方法。请特别注意extract_odd_list()函数以及从main()对该函数的调用。

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

typedef struct _Node {
    int value;
    struct _Node *next;
} Node;

/* Move odd numbers in *list to returned list. */
Node *extract_odd_list(Node **list) {
    Node *oddstart = NULL;      /* start of returned list */
    Node **oddend = &oddstart;  /* pointer to final link of returned list */

    while (*list) {
        if ((*list)->value % 2 != 0) {
            /* Current element of original *list is odd. */
            /* Move original *list element to end of returned list. */
            *oddend = *list;
            /* Bypass moved element in original list. */
            *list = (*list)->next;
            /* Update pointer to final link of returned list. */
            oddend = &(*oddend)->next;
        }
        else {
            /* Current element of original *list is even. */
            /* Skip to next element of original *list. */
            list = &(*list)->next;
        }
    }
    /* Terminate the returned list. */
    *oddend = NULL;
    /* And return it. */
    return oddstart;
}

void *printlist(Node *list) {
    while (list) {
        printf(" %d", list->value);
        list = list->next;
    }
}

int main(void) {
    int i;
    Node *list = NULL;
    Node *end = NULL;
    Node *oddlist;
    Node *temp;

    /* Construct a list containing odd and even numbers. */
    for (i = 1; i <= 10; i++) {
        temp = malloc(sizeof(*temp));
        temp->value = i;
        if (end == NULL) {
            list = temp;
        }
        else {
            end->next = temp;
        }
        end = temp;
    }
    end->next = NULL;
    printf("Original list:");
    printlist(list);
    printf("\n");

    /* Move the "odd number" elements from the original list to a new list. */
    oddlist = extract_odd_list(&list);

    printf("Updated list:");
    printlist(list);
    printf("\n");

    printf("Odd list:");
    printlist(oddlist);
    printf("\n");
    return 0;
}