C - 将数组传递给链表的节点

时间:2013-06-05 13:45:24

标签: c arrays list linked-list malloc

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

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. 这个,先前的循环应该用当前的head->val[j]填充足够的i-row二维数组table,但它看起来好得令人难以置信。我可以这样离开吗?
  4. 编辑:我在某些地方纠正了它,但是在尝试对其进行排序之后,它又返回了垃圾。我将在这里转储大部分代码:

    #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

1 个答案:

答案 0 :(得分: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中分配新值。