簡體   English   中英

在 C 中以相反的順序將鏈表的元素復制到另一個鏈表

[英]Copying elements of a linked list to another linked list in reverse order in C

我是 C 編程並參加課程的新手。 我在練習的一項任務中遇到了麻煩。 我應該編寫一個程序來創建一個包含 10 個字符的鏈接列表,然后以相反的順序創建列表的副本。 我已經編寫(主要是復制)一個代碼,但它只會反轉我的鏈表的內容,不會以相反的順序將它們復制到新的鏈表中。 即使我使用的是 char 數據類型,它也不適用於字母。 適用於數字。

這是我的代碼:

#include <stdio.h>
#include <malloc.h>

struct Node
{
    char data;
    struct Node *next;
};

static void reverse(struct Node **head_ref)
{
    struct Node *previous = NULL;
    struct Node *current = *head_ref;
    struct Node *next;
    while (current != NULL)
    {
        next = current->next;
        current->next = previous;
        previous = current;
        current = next;
    }
    *head_ref = previous;
}

void push(struct Node **head_ref, char new_data)
{
    struct Node *new_node =
        (struct Node *)malloc(sizeof(struct Node));
    new_node->data = new_data;
    new_node->next = (*head_ref);
    (*head_ref) = new_node;
}

void printList(struct Node *head)
{
    struct Node *temp = head;
    while (temp != NULL)
    {
        printf("%d ", temp->data);
        temp = temp->next;
    }
}

int main()
{
    struct Node *head = NULL;
    char element = NULL;
    printf("Enter 10 characters:\n");
    for (int i = 0; i <= 9; i++)
    {
        scanf_s("%d", &element);
        push(&head, element);
    }
 
    printf("Given linked list\n");
    printList(head);
    reverse(&head);
    printf("\nReversed Linked list \n");
    printList(head);
    getchar();
}

要以相反的順序創建副本,請創建一個與原始列表具有相同值的新列表,但使用push function 在新節點前面添加。

這是修改后的版本:

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

struct Node {
    char data;
    struct Node *next;
};

void prepend(struct Node **head_ref, char new_data) {
    struct Node *new_node = (struct Node *)malloc(sizeof(struct Node));
    new_node->data = new_data;
    new_node->next = (*head_ref);
    (*head_ref) = new_node;
}

void append(struct Node **head_ref, char new_data) {
    struct Node *new_node = (struct Node *)malloc(sizeof(struct Node));
    struct Node *node = *head_ref;
    new_node->data = new_data;
    new_node->next = NULL;
    if (!node) {
        *head_ref = new_node;
    } else {
        while (node->next)
            node = node->next;
        node->next = new_node;
    }
}

void printList(const struct Node *head) {
    const struct Node *temp = head;
    while (temp != NULL) {
        printf("%c ", temp->data);
        temp = temp->next;
    }
    printf("\n");
}

struct Node *copy_reverse(struct Node *list) {
    struct Node *new_list = NULL;
    while (list) {
        prepend(&new_list, list->data);
        list = list->next;
    }
    return new_list;
}

void freeList(struct Node *list) {
    while (list) {
        struct Node *node = list;
        list = list->next;
        free(node);
    }
}

int main() {
    struct Node *head = NULL;
    char element;
    printf("Enter 10 characters:\n");
    for (int i = 0; i < 10; i++) {
        scanf_s("%c", &element);
        push(&head, element);
    }
 
    printf("Given linked list\n");
    printList(head);

    struct Node *copy = copy_reverse(head);
    printf("\nReversed Linked list \n");
    printList(copy);
    freeList(head);
    freeList(copy);
    getchar();
}

您快到了。 它所需要的只是一個調整。 reverse ,您需要創建current節點的新副本並使用它。 此外,由於您將得到第二個列表並且不會更改原始列表,因此您應該從reverse中返回新列表。

static struct Node* reverse(const struct Node* head_ref)
{
    struct Node* previous = NULL;
    const struct Node* current = head_ref;
    struct Node* copy;

    while (current != NULL) {
        copy = malloc(sizeof(*copy));
        if (copy == NULL) {
            // handle error
        }
        copy->data = current->data;
        copy->next = previous;
        previous = copy;
        current = current->next;
    }

    return previous;
}

您還可以通過將其轉換為for循環來使循環更漂亮。

for (current = head_ref; current != NULL; current = current->next) {

最后,當您打印出列表時,您使用的是printf格式字符串中的%d %d會將char打印為 integer。 要打印出實際字符,請改用%c

這個for循環

for (int i = 0; i <= 9; i++)
{
    scanf_s("%d", &element);
    push(&head, element);
}

調用未定義的行為,因為使用了不正確的轉換說明符%dchar類型的 object ,

你需要寫

for (int i = 0; i <= 9; i++)
{
    scanf_s( " %c", &element, 1 );
    push(&head, element);
}

注意格式字符串中轉換說明符%c前的空格。 這允許跳過輸入 stream 中的空白字符。

至於 function 然后可以使用您已經定義的 function push聲明和定義以下簡單方法

struct Node * reverse_copy( const struct Node *head )
{
    struct Node *new_head = NULL;

    for ( ; head != NULL; head = head->next )
    {
        push( &new_head, head->data );
    }

    return new_head;
}

主要是你可以寫類似的東西

struct Node *second_head = reverse_copy( head );

考慮到 function push會更安全,如果它能夠處理 memory 節點分配失敗的情況。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM