【问题标题】:C - passing array to node of a linked listC - 将数组传递给链表的节点
【发布时间】:2013-06-05 13:45:23
【问题描述】:

我有一个已经用整数填充的二维数组,准备被切割成行并进行处理,我需要将每一行(一维数组)传递给链表的一个节点。每个节点如下所示:

struct node {
    int *val;
    struct node *next;
};

以这种方式添加和链接新节点:

struct node *addnode(int *val, struct node *next, int columns)
{
    struct node *tnode;
    tnode = (struct node*)malloc(sizeof(*tnode));
    if(tnode != NULL) {
        tnode->val = malloc(sizeof(int) * columns);
        memcpy(tnode->val, val, sizeof(int) * columns);
        tnode->val = val;
        tnode->next = next;
    };
    return tnode;
}

将填充每个节点的程序片段大致如下:

int table[rows][columns], i, j;
for (i = 0; i < rows; i++){
    head = addnode(*table, head, columns);
    for (j = 0; j < columns; j++){
        scanf("%d",&table[i][j]);
        head->val[j] = table[j];
        printf("%d ",head->val[j]);
    };
    puts("\n");
};  

我不确定如何在指定的地方进行:

  1. 这是整个节点的malloc,但是val的malloc怎么办呢?我知道应该在每个节点中的表的长度,它是columns,在主函数中获得。我应该在哪里为其分配内存?
  2. 这一行上方是我为单行整数分配足够 (columns) 内存的地方。这是一个不错的选择吗?
  3. 这与前面的循环应该用足够的二维数组table 的i 行填充当前head-&gt;val[j],但它看起来好得令人难以置信。我可以这样吗?

编辑:我在某些地方更正了它,但是在尝试对其进行排序后,它返回垃圾。我将在这里转储大部分代码:

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

struct node {
    int *val;
    struct node *next;
};

struct node *addnode(int *val, struct node *next, int columns);
struct node *mergesort(struct node *head, int column);
struct node *merge(struct node *head_one, struct node *head_two, int column);

int main(int argc, char *argv[])
{

    struct node *head;
    struct node *current;
    struct node *next;
    int symbol = 0;
    int columns = 0;
    //int columns = atoi(argv[1]); //until sorting works, I'll keep it at 0
    int rows = 0;
    head = NULL;
    int column = 0; //temporary until I find the way to send one argument during executing it under linux like so 'name_of_program columns < test.txt'
    int lastSpace = 0;

    do {
        symbol = fgetc(stdin);

        if (rows == 0 && (lastSpace == 0 && (isspace(symbol) || feof(stdin)))) {
            columns++;
            lastSpace = 1;
        } else if (!isspace(symbol)) {
            lastSpace = 0;
        }
        if (symbol == '\n' || feof(stdin)) {
            rows++;
        };      
    } while (symbol != EOF);

    if (ferror(stdin))
    {
        printf("Error on reading from file.\n");
    } else {
        printf("The file contains %d row(s) and %d column(s).\n", rows, columns);
    };

    rewind(stdin); //I have heard conflicting opinions on that, but in this case it works, and in the end it's a school project, not commercial code

    int table[rows][columns], i, j;
    for (i = 0; i < rows; i++){
        head = addnode(*table, head, columns);
        for (j = 0; j < columns; j++){
            scanf("%d",&table[i][j]);
            head->val[j] = table[i][j];
            printf("%d ",head->val[j]);
        };
        puts("\n");
    };  


    head = mergesort(head, column);

    for(current = head; current != NULL; current = current->next){
        for (j = 0; j < columns; j++){
            printf("%d ", current->val[j]);
        };
        puts("\n");
    };

    for(current = head; current != NULL; current = next)
      next = current->next, free(current);
    return 0;
};


struct node *addnode(int *val, struct node *next, int columns)
{
    struct node *tnode;
    tnode = (struct node*)malloc(sizeof(*tnode));
    if(tnode != NULL) {
        tnode->val = malloc(sizeof(int) * columns);
        memcpy(tnode->val, val, sizeof(int) * columns);
        tnode->val = val;
        tnode->next = next;
    };
    return tnode;
}

struct node *mergesort(struct node *head, int column)
{
    struct node *head_one;
    struct node *head_two;
    if((head == NULL) || (head->next == NULL))
        return head;
    head_one = head;
    head_two = head->next;
    while((head_two != NULL) && (head_two->next != NULL)) {
        head = head->next;
        head_two = head->next->next;
    };
    head_two = head->next;
    head->next = NULL;
    return merge(mergesort(head_one, column), mergesort(head_two, column), column);
}

struct node *merge(struct node *head_one, struct node *head_two, int column)
{
    struct node *head_combined;
    if(head_one == NULL)
        return head_two;
    if(head_two == NULL)
        return head_one;
    if(head_one->val[column] < head_two->val[column]) {
        head_combined = head_one;
        head_combined->next = merge(head_one->next, head_two, column);
    } else {
        head_combined = head_two;
        head_combined->next = merge(head_one, head_two->next, column);
    };
    return head_combined;
}

我在 Unix 中这样运行它:

name_of_program < test.txt

test.txt 具有这种结构 http://pastebin.com/WL5brutf

【问题讨论】:

  • head 来自哪里?
  • @wildplasser struct node *head; 如果这就是您的要求。
  • 在新片段中 rowscolumns 在 main() 中未定义。 ALSO int main(int column_to_sort) 是使用 argc 的一种奇怪方式...
  • 如果你包含一个完整的程序,编译时不会出错。
  • int main(int column_to_sort) 完全错误。如果将 printf("column_to_sort %d\n", column_to_sort) 放在 main() 的开头,会得到什么?此外,省略部分程序会使其他人难以提供有用的建议。

标签: c arrays list linked-list malloc


【解决方案1】:

1) 您将int *val 传递给函数,在节点中使用它本身。如果要丢弃传递给函数的val 并希望保留它的另一个副本,则需要malloc 内存。正如您所说,您知道数组中有多少元素,因此您可以分配那么多元素,然后将内存从val 复制为

 tnode->val = malloc(sizeof(int) * num_of_elements); //replace num_of_elements with appropriate variable/constant
    memcpy(tnode->val, val, sizeof(int) * num_of_elements);

2) 是的,这是正确的地方。

3) 是的,您可以为head 指向的当前节点分配值。您可能希望在j for 循环结束后移动到下一个节点并在其val 中分配新值。

【讨论】:

  • 我更正了代码,但是在对其进行排序后,我只得到了未排序列表的最后一个元素的数组。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多