如何使用链接列表在C中表示稀疏矩阵(包括零元素)?

发布于 2025-01-23 10:36:56 字数 2121 浏览 2 评论 0原文

我想要一个代表稀疏矩阵的代码,包括使用链接列表的零元素,我基本上希望输出是这样的:

1  0  0  0  


0  6  1  0  

我已经有一个执行表示的代码,但仅作为输出作为输出,类似的非零元素:

输入:

2  0  0

0  0  0

0  0  0
      

输出:

行:1 Col:1 值:2

这是代码:

// C program for Sparse Matrix Representation
// using Linked Lists

#include<stdio.h>

#include<stdlib.h>

 
// Node to represent sparse matrix

struct Node

{

    int value;

    int row_position;

    int column_postion;

    struct Node *next;

};
 

// Function to create new node

void create_new_node(struct Node** start, int non_zero_element,

                     int row_index, int column_index )

{

    struct Node *temp, *r;

    temp = *start;

    if (temp == NULL)

    {

        // Create new node dynamically

        temp = (struct Node *) malloc (sizeof(struct Node));

        temp->value = non_zero_element;

        temp->row_position = row_index;

        temp->column_postion = column_index;

        temp->next = NULL;

        *start = temp;

 
    }

    else

    {

        while (temp->next != NULL)

            temp = temp->next;

 
        // Create new node dynamically

        r = (struct Node *) malloc (sizeof(struct Node));

        r->value = non_zero_element;

        r->row_position = row_index;

        r->column_postion = column_index;

        r->next = NULL;

        temp->next = r;

 
    }

}

 
// This function prints contents of linked list
// starting from start

void PrintList(struct Node* start)

{

    struct Node *temp, *r, *s;

    temp = r = s = start;

 
    printf("row_position: ");

    while(temp != NULL)

    {

 
        printf("%d ", temp->row_position);

        temp = temp->next;

    }

    printf("\n");

 
    printf("column_postion: ");

    while(r != NULL)

    {

        printf("%d ", r->column_postion);

        r = r->next;

    }

    printf("\n");

    printf("Value: ");

    while(s != NULL)

    {

        printf("%d ", s->value);

        s = s->next;

    }

    printf("\n");

}

I want a code that represents a sparse matrix including zero elements using linked list, I basically want the output to be like this:

1  0  0  0  


0  6  1  0  

I already have a code that does the representation but it only gives as an output the non-Zero elements like so :

input :

2  0  0

0  0  0

0  0  0
      

output :

row : 1
col : 1
value : 2

Here is the code :

// C program for Sparse Matrix Representation
// using Linked Lists

#include<stdio.h>

#include<stdlib.h>

 
// Node to represent sparse matrix

struct Node

{

    int value;

    int row_position;

    int column_postion;

    struct Node *next;

};
 

// Function to create new node

void create_new_node(struct Node** start, int non_zero_element,

                     int row_index, int column_index )

{

    struct Node *temp, *r;

    temp = *start;

    if (temp == NULL)

    {

        // Create new node dynamically

        temp = (struct Node *) malloc (sizeof(struct Node));

        temp->value = non_zero_element;

        temp->row_position = row_index;

        temp->column_postion = column_index;

        temp->next = NULL;

        *start = temp;

 
    }

    else

    {

        while (temp->next != NULL)

            temp = temp->next;

 
        // Create new node dynamically

        r = (struct Node *) malloc (sizeof(struct Node));

        r->value = non_zero_element;

        r->row_position = row_index;

        r->column_postion = column_index;

        r->next = NULL;

        temp->next = r;

 
    }

}

 
// This function prints contents of linked list
// starting from start

void PrintList(struct Node* start)

{

    struct Node *temp, *r, *s;

    temp = r = s = start;

 
    printf("row_position: ");

    while(temp != NULL)

    {

 
        printf("%d ", temp->row_position);

        temp = temp->next;

    }

    printf("\n");

 
    printf("column_postion: ");

    while(r != NULL)

    {

        printf("%d ", r->column_postion);

        r = r->next;

    }

    printf("\n");

    printf("Value: ");

    while(s != NULL)

    {

        printf("%d ", s->value);

        s = s->next;

    }

    printf("\n");

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

与之呼应 2025-01-30 10:36:56

您的代码不完整。

它可以/应该按行/列排序顺序插入新节点。但是,看来它只是附加到列表的尽头。这使得矩阵的有序打印困难。而且,它不允许[true]随机访问(例如,相同的节点多次更新一次)。

因此,我必须重构代码。

扫描列表并寻找按顺序排序的插入点不再是额外的时间。这是因为插入新节点必须检查已经存在的节点以使稀疏矩阵像真实矩阵一样工作的函数。

我包括了其他一些扫描/匹配功能,并创建了一个矩阵“ Pretty”打印功能。

可以重写打印代码,因为它可以多次调用nodefind函数。可以重写该打印,以循环浏览所有节点,然后将其打印在其正确的列中。

该代码注释:

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

// node control
typedef struct node {
    int node_row;
    int node_col;
    int node_val;
    struct node *node_next;
} node_t;

// matrix control
typedef struct {
    node_t *mtx_head;                   // head of list

    // insertion temporaries
    node_t *mtx_bef;                    // node before node to insert
    node_t *mtx_aft;                    // node after node to insert

    // printing temporaries
    int mtx_rowmin;                     // minumum row
    int mtx_rowmax;                     // maximum row
    int mtx_colmin;                     // minumum column
    int mtx_colmax;                     // maximum column
    int mtx_valmax;                     // maximum matrix value
} mtx_t;

#define MAXOF(_lhs,_rhs) \
    if (_rhs > _lhs) \
        _lhs = _rhs

#define MINOF(_lhs,_rhs) \
    if (_rhs < _lhs) \
        _lhs = _rhs

#define SEPOUT(_sep) \
    for (int idx = 0;  idx < xwid;  ++idx) \
        fputc(_sep,stdout)

// colscan -- scan a given row for column insertion point
// RETURNS: add pointer (or NULL)
node_t *
colscan(mtx_t *mtx,node_t *cur,node_t *add)
{

    for (;  cur != NULL;  cur = cur->node_next) {
        // stop if row changes -- we are beyond the insertion point
        if (cur->node_row > add->node_row) {
            mtx->mtx_aft = cur;
            break;
        }

        // duplicate node -- just update existing value and release new node
        if (cur->node_col == add->node_col) {
            cur->node_val = add->node_val;
            free(add);
            add = NULL;
            break;
        }

        // point to node _after_ insertion point
        mtx->mtx_aft = cur;

        // stop if column becomes higher
        if (cur->node_col > add->node_col)
            break;

        // point to node _before_ insertion point
        mtx->mtx_bef = cur;
    }

    return add;
}

// nodenew -- add new node to matrix
void
nodenew(mtx_t *mtx,int row,int col,int val)
{

    // get new node to insert
    node_t *add = calloc(1,sizeof(*add));
    add->node_row = row;
    add->node_col = col;
    add->node_val = val;

    mtx->mtx_bef = NULL;
    mtx->mtx_aft = NULL;

    // scan all nodes looking for place to insert row
    for (node_t *cur = mtx->mtx_head;  cur != NULL;  cur = cur->node_next) {
        // found start of matching row -- scan for matching column
        if (cur->node_row == add->node_row) {
            add = colscan(mtx,cur,add);
            break;
        }

        // went beyond row -- stop -- we insert before this node
        if (cur->node_row > add->node_row) {
            mtx->mtx_aft = cur;
            break;
        }

        // remember node that is lower than the one to insert
        mtx->mtx_bef = cur;
    }

    // insert new node
    do {
        // node is a duplicate -- value has already been updated (by colscan)
        if (add == NULL)
            break;

        node_t *prev = mtx->mtx_bef;

        // insert/append the new node
        if (prev != NULL) {
            add->node_next = prev->node_next;
            prev->node_next = add;
            break;
        }

        // add to empty list or before start of existing list
        add->node_next = mtx->mtx_aft;
        mtx->mtx_head = add;
    } while (0);
}

// nodefind -- find existing node
node_t *
nodefind(mtx_t *mtx,int row,int col)
{
    node_t *cur = mtx->mtx_head;

    for (;  cur != NULL;  cur = cur->node_next) {
        if ((cur->node_row == row) && (cur->node_col == col))
            break;
    }

    return cur;
}

// nodedel -- delete existing node
// RETURNS: 1=found, 0=no match
int
nodedel(mtx_t *mtx,int row,int col)
{
    node_t *cur = mtx->mtx_head;
    node_t *prev = NULL;
    node_t *next;
    int match = 0;

    for (;  cur != NULL;  prev = cur, cur = next) {
        next = cur->node_next;

        if ((cur->node_row == row) && (cur->node_col == col)) {
            if (prev != NULL)
                prev->node_next = next;
            else
                mtx->mtx_head = next;
            free(cur);
            match = 1;
            break;
        }
    }

    return match;
}

// mtxdimset -- get matrix dimensions
void
mtxdimset(mtx_t *mtx)
{
    node_t *cur = mtx->mtx_head;

    // NOTE: with some effort, nodenew/nodedel could keep the dimensions up to
    // date (but, currently, they don't)
    do {
        // empty matrix
        if (cur == NULL) {
            mtx->mtx_rowmin = -1;
            mtx->mtx_rowmax = -2;

            mtx->mtx_colmin = -1;
            mtx->mtx_colmax = -2;

            mtx->mtx_valmax = 0;
            break;
        }

        mtx->mtx_rowmin = cur->node_row;
        mtx->mtx_rowmax = cur->node_row;

        mtx->mtx_colmin = cur->node_col;
        mtx->mtx_colmax = cur->node_col;

        mtx->mtx_valmax = cur->node_val;

        cur = cur->node_next;

        for (;  cur != NULL;  cur = cur->node_next) {
            MAXOF(mtx->mtx_valmax,cur->node_val);

            MINOF(mtx->mtx_rowmin,cur->node_row);
            MAXOF(mtx->mtx_rowmax,cur->node_row);

            MINOF(mtx->mtx_colmin,cur->node_col);
            MAXOF(mtx->mtx_colmax,cur->node_col);
        }
    } while (0);
}

// mtxprint -- print matrix
void
mtxprint(mtx_t *mtx,const char *who)
{
    node_t *cur = mtx->mtx_head;
    char fmt[100];

    // get row/column/value ranges
    mtxdimset(mtx);

    // get maximum number size (pretty print)
    int xwid = 0;
    int rwid = sprintf(fmt,"%d",mtx->mtx_rowmax);
    int cwid = sprintf(fmt,"%d",mtx->mtx_colmax);
    int vwid = sprintf(fmt,"%d",mtx->mtx_valmax);
    MAXOF(xwid,rwid);
    MAXOF(xwid,cwid);
    MAXOF(xwid,vwid);

    // get the format for printing
    sprintf(fmt," %%%dd",xwid);

    if (who != NULL)
        printf("MATRIX R:%d-%d C:%d-%d (from %s)\n",
            mtx->mtx_rowmin,mtx->mtx_rowmax,
            mtx->mtx_colmin,mtx->mtx_colmax,
            who);

    // output column headers
    printf(" ");
    SEPOUT(' ');
    for (int col = mtx->mtx_colmin;  col <= mtx->mtx_colmax;  ++col)
        printf(fmt,col);
    printf("\n");

    // output all rows
    for (int row = mtx->mtx_rowmin;  row <= mtx->mtx_rowmax;  ++row) {
        // output row number
        printf(fmt,row);

        // output all rows in the column
        // NOTE: this is very slow due to the repeated calls to nodefind
        for (int col = mtx->mtx_colmin;  col <= mtx->mtx_colmax;  ++col) {
            cur = nodefind(mtx,row,col);

            if (cur != NULL) {
                printf(fmt,cur->node_val);
                continue;
            }

            SEPOUT(' ');
            fputc('*',stdout);
        }

        printf("\n");
    }
}

// mtxdump -- dump out matrix nodes in linear order
void
mtxdump(mtx_t *mtx)
{

    for (node_t *cur = mtx->mtx_head;  cur != NULL;  cur = cur->node_next)
        printf("DMP: [%d,%d] = %d\n",
            cur->node_row,cur->node_col,cur->node_val);
}

int
main(void)
{

    mtx_t *mtx = calloc(1,sizeof(*mtx));

    enum {
        ROWMAX = 20,
        COLMAX = 7
    };

    // ordinary matrix (for cross check)
    int arr[ROWMAX][COLMAX];
    for (int rowcur = 0;  rowcur < ROWMAX;  ++rowcur) {
        for (int colcur = 0;  colcur < COLMAX;  ++colcur)
            arr[rowcur][colcur] = -1;
    }

    // add random row/column/data
    for (int idx = 0;  idx < (ROWMAX * COLMAX) / 2;  ++idx) {
        int rowcur = rand() % ROWMAX;
        int colcur = rand() % COLMAX;
        int valcur = rand() % (COLMAX * ROWMAX);

#if DEBUG
        printf("\n");
#endif
        int valold = arr[rowcur][colcur];
        printf("%s: [%d,%d] = %d\n",
            (valold < 0) ? "ADD" : "UPD",rowcur,colcur,valcur);
        arr[rowcur][colcur] = valcur;
        nodenew(mtx,rowcur,colcur,valcur);

#if DEBUG
        mtxdump(mtx);
#endif
    }

    printf("\n");
    mtxprint(mtx,"FIN");

    // cross check
    printf("\n");
    printf("cross check ...\n");
    int miss = 0;
    for (int rowcur = 0;  rowcur < ROWMAX;  ++rowcur) {
        for (int colcur = 0;  colcur < COLMAX;  ++colcur) {
            int valexp = arr[rowcur][colcur];

            node_t *cur = nodefind(mtx,rowcur,colcur);

            int valact;
            if (cur != NULL)
                valact = cur->node_val;
            else
                valact = -1;

            if (valact != valexp) {
                printf("DIF: [%d,%d] = %d/%d\n",rowcur,colcur,valexp,valact);
                miss = 1;
            }
        }
    }
    if (! miss)
        printf("all values match\n");

    return 0;
}

这是程序输出:

ADD: [3,4] = 37
ADD: [15,1] = 115
ADD: [6,2] = 29
ADD: [1,2] = 47
ADD: [10,4] = 83
ADD: [6,3] = 106
ADD: [12,2] = 31
ADD: [8,5] = 9
ADD: [2,5] = 82
ADD: [3,1] = 75
ADD: [9,0] = 122
ADD: [18,3] = 107
ADD: [13,0] = 51
ADD: [2,1] = 53
ADD: [1,0] = 104
ADD: [17,6] = 44
UPD: [15,1] = 73
ADD: [6,0] = 120
ADD: [16,2] = 102
ADD: [10,1] = 101
ADD: [5,6] = 4
ADD: [7,3] = 5
ADD: [6,4] = 73
ADD: [17,5] = 115
ADD: [2,3] = 94
ADD: [7,4] = 84
ADD: [3,0] = 7
UPD: [8,5] = 98
ADD: [8,4] = 63
ADD: [11,1] = 99
ADD: [12,4] = 96
ADD: [8,0] = 92
ADD: [6,6] = 74
ADD: [19,4] = 70
ADD: [14,0] = 127
UPD: [1,0] = 62
ADD: [17,0] = 132
ADD: [16,4] = 100
UPD: [6,6] = 105
ADD: [9,6] = 99
ADD: [0,3] = 31
ADD: [17,3] = 11
ADD: [1,5] = 29
UPD: [7,4] = 136
UPD: [17,5] = 106
ADD: [5,1] = 43
ADD: [19,5] = 28
ADD: [11,4] = 109
UPD: [3,4] = 10
ADD: [8,3] = 115
ADD: [0,2] = 116
UPD: [3,4] = 5
ADD: [6,5] = 81
ADD: [15,4] = 8
ADD: [4,0] = 41
ADD: [10,0] = 20
ADD: [14,2] = 4
ADD: [14,3] = 36
UPD: [3,0] = 87
ADD: [5,3] = 56
UPD: [12,4] = 77
ADD: [8,2] = 107
ADD: [14,1] = 98
ADD: [15,0] = 137
ADD: [15,2] = 38
UPD: [8,5] = 31
ADD: [8,1] = 76
ADD: [4,4] = 23
ADD: [13,2] = 126
ADD: [0,4] = 58

MATRIX R:0-19 C:0-6 (from FIN)
       0   1   2   3   4   5   6
   0   *   * 116  31  58   *   *
   1  62   *  47   *   *  29   *
   2   *  53   *  94   *  82   *
   3  87  75   *   *   5   *   *
   4  41   *   *   *  23   *   *
   5   *  43   *  56   *   *   4
   6 120   *  29 106  73  81 105
   7   *   *   *   5 136   *   *
   8  92  76 107 115  63  31   *
   9 122   *   *   *   *   *  99
  10  20 101   *   *  83   *   *
  11   *  99   *   * 109   *   *
  12   *   *  31   *  77   *   *
  13  51   * 126   *   *   *   *
  14 127  98   4  36   *   *   *
  15 137  73  38   *   8   *   *
  16   *   * 102   * 100   *   *
  17 132   *   *  11   * 106  44
  18   *   *   * 107   *   *   *
  19   *   *   *   *  70  28   *

cross check ...
all values match

Your code was incomplete.

It could/should do the insertion of a new node in row/column sorted order. But, it appears it just appended to the end of the list. This makes the ordered printing of the matrix difficult. And, it does not allow for [true] random access (e.g. the same node is updated more than once).

So, I had to refactor the code.

It's no more extra time to scan the list and look for an insertion point that is in sorted order. That's because the function that inserts a new node must check for an already existing node to make the sparse matrix work like a real matrix.

I've included some other scan/match functions and created a matrix "pretty" print function.

The print code could be rewritten as it makes many calls to a nodefind function. The print could be rewritten to just loop through all nodes and print them in their correct columns.

The code is annotated:

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

// node control
typedef struct node {
    int node_row;
    int node_col;
    int node_val;
    struct node *node_next;
} node_t;

// matrix control
typedef struct {
    node_t *mtx_head;                   // head of list

    // insertion temporaries
    node_t *mtx_bef;                    // node before node to insert
    node_t *mtx_aft;                    // node after node to insert

    // printing temporaries
    int mtx_rowmin;                     // minumum row
    int mtx_rowmax;                     // maximum row
    int mtx_colmin;                     // minumum column
    int mtx_colmax;                     // maximum column
    int mtx_valmax;                     // maximum matrix value
} mtx_t;

#define MAXOF(_lhs,_rhs) \
    if (_rhs > _lhs) \
        _lhs = _rhs

#define MINOF(_lhs,_rhs) \
    if (_rhs < _lhs) \
        _lhs = _rhs

#define SEPOUT(_sep) \
    for (int idx = 0;  idx < xwid;  ++idx) \
        fputc(_sep,stdout)

// colscan -- scan a given row for column insertion point
// RETURNS: add pointer (or NULL)
node_t *
colscan(mtx_t *mtx,node_t *cur,node_t *add)
{

    for (;  cur != NULL;  cur = cur->node_next) {
        // stop if row changes -- we are beyond the insertion point
        if (cur->node_row > add->node_row) {
            mtx->mtx_aft = cur;
            break;
        }

        // duplicate node -- just update existing value and release new node
        if (cur->node_col == add->node_col) {
            cur->node_val = add->node_val;
            free(add);
            add = NULL;
            break;
        }

        // point to node _after_ insertion point
        mtx->mtx_aft = cur;

        // stop if column becomes higher
        if (cur->node_col > add->node_col)
            break;

        // point to node _before_ insertion point
        mtx->mtx_bef = cur;
    }

    return add;
}

// nodenew -- add new node to matrix
void
nodenew(mtx_t *mtx,int row,int col,int val)
{

    // get new node to insert
    node_t *add = calloc(1,sizeof(*add));
    add->node_row = row;
    add->node_col = col;
    add->node_val = val;

    mtx->mtx_bef = NULL;
    mtx->mtx_aft = NULL;

    // scan all nodes looking for place to insert row
    for (node_t *cur = mtx->mtx_head;  cur != NULL;  cur = cur->node_next) {
        // found start of matching row -- scan for matching column
        if (cur->node_row == add->node_row) {
            add = colscan(mtx,cur,add);
            break;
        }

        // went beyond row -- stop -- we insert before this node
        if (cur->node_row > add->node_row) {
            mtx->mtx_aft = cur;
            break;
        }

        // remember node that is lower than the one to insert
        mtx->mtx_bef = cur;
    }

    // insert new node
    do {
        // node is a duplicate -- value has already been updated (by colscan)
        if (add == NULL)
            break;

        node_t *prev = mtx->mtx_bef;

        // insert/append the new node
        if (prev != NULL) {
            add->node_next = prev->node_next;
            prev->node_next = add;
            break;
        }

        // add to empty list or before start of existing list
        add->node_next = mtx->mtx_aft;
        mtx->mtx_head = add;
    } while (0);
}

// nodefind -- find existing node
node_t *
nodefind(mtx_t *mtx,int row,int col)
{
    node_t *cur = mtx->mtx_head;

    for (;  cur != NULL;  cur = cur->node_next) {
        if ((cur->node_row == row) && (cur->node_col == col))
            break;
    }

    return cur;
}

// nodedel -- delete existing node
// RETURNS: 1=found, 0=no match
int
nodedel(mtx_t *mtx,int row,int col)
{
    node_t *cur = mtx->mtx_head;
    node_t *prev = NULL;
    node_t *next;
    int match = 0;

    for (;  cur != NULL;  prev = cur, cur = next) {
        next = cur->node_next;

        if ((cur->node_row == row) && (cur->node_col == col)) {
            if (prev != NULL)
                prev->node_next = next;
            else
                mtx->mtx_head = next;
            free(cur);
            match = 1;
            break;
        }
    }

    return match;
}

// mtxdimset -- get matrix dimensions
void
mtxdimset(mtx_t *mtx)
{
    node_t *cur = mtx->mtx_head;

    // NOTE: with some effort, nodenew/nodedel could keep the dimensions up to
    // date (but, currently, they don't)
    do {
        // empty matrix
        if (cur == NULL) {
            mtx->mtx_rowmin = -1;
            mtx->mtx_rowmax = -2;

            mtx->mtx_colmin = -1;
            mtx->mtx_colmax = -2;

            mtx->mtx_valmax = 0;
            break;
        }

        mtx->mtx_rowmin = cur->node_row;
        mtx->mtx_rowmax = cur->node_row;

        mtx->mtx_colmin = cur->node_col;
        mtx->mtx_colmax = cur->node_col;

        mtx->mtx_valmax = cur->node_val;

        cur = cur->node_next;

        for (;  cur != NULL;  cur = cur->node_next) {
            MAXOF(mtx->mtx_valmax,cur->node_val);

            MINOF(mtx->mtx_rowmin,cur->node_row);
            MAXOF(mtx->mtx_rowmax,cur->node_row);

            MINOF(mtx->mtx_colmin,cur->node_col);
            MAXOF(mtx->mtx_colmax,cur->node_col);
        }
    } while (0);
}

// mtxprint -- print matrix
void
mtxprint(mtx_t *mtx,const char *who)
{
    node_t *cur = mtx->mtx_head;
    char fmt[100];

    // get row/column/value ranges
    mtxdimset(mtx);

    // get maximum number size (pretty print)
    int xwid = 0;
    int rwid = sprintf(fmt,"%d",mtx->mtx_rowmax);
    int cwid = sprintf(fmt,"%d",mtx->mtx_colmax);
    int vwid = sprintf(fmt,"%d",mtx->mtx_valmax);
    MAXOF(xwid,rwid);
    MAXOF(xwid,cwid);
    MAXOF(xwid,vwid);

    // get the format for printing
    sprintf(fmt," %%%dd",xwid);

    if (who != NULL)
        printf("MATRIX R:%d-%d C:%d-%d (from %s)\n",
            mtx->mtx_rowmin,mtx->mtx_rowmax,
            mtx->mtx_colmin,mtx->mtx_colmax,
            who);

    // output column headers
    printf(" ");
    SEPOUT(' ');
    for (int col = mtx->mtx_colmin;  col <= mtx->mtx_colmax;  ++col)
        printf(fmt,col);
    printf("\n");

    // output all rows
    for (int row = mtx->mtx_rowmin;  row <= mtx->mtx_rowmax;  ++row) {
        // output row number
        printf(fmt,row);

        // output all rows in the column
        // NOTE: this is very slow due to the repeated calls to nodefind
        for (int col = mtx->mtx_colmin;  col <= mtx->mtx_colmax;  ++col) {
            cur = nodefind(mtx,row,col);

            if (cur != NULL) {
                printf(fmt,cur->node_val);
                continue;
            }

            SEPOUT(' ');
            fputc('*',stdout);
        }

        printf("\n");
    }
}

// mtxdump -- dump out matrix nodes in linear order
void
mtxdump(mtx_t *mtx)
{

    for (node_t *cur = mtx->mtx_head;  cur != NULL;  cur = cur->node_next)
        printf("DMP: [%d,%d] = %d\n",
            cur->node_row,cur->node_col,cur->node_val);
}

int
main(void)
{

    mtx_t *mtx = calloc(1,sizeof(*mtx));

    enum {
        ROWMAX = 20,
        COLMAX = 7
    };

    // ordinary matrix (for cross check)
    int arr[ROWMAX][COLMAX];
    for (int rowcur = 0;  rowcur < ROWMAX;  ++rowcur) {
        for (int colcur = 0;  colcur < COLMAX;  ++colcur)
            arr[rowcur][colcur] = -1;
    }

    // add random row/column/data
    for (int idx = 0;  idx < (ROWMAX * COLMAX) / 2;  ++idx) {
        int rowcur = rand() % ROWMAX;
        int colcur = rand() % COLMAX;
        int valcur = rand() % (COLMAX * ROWMAX);

#if DEBUG
        printf("\n");
#endif
        int valold = arr[rowcur][colcur];
        printf("%s: [%d,%d] = %d\n",
            (valold < 0) ? "ADD" : "UPD",rowcur,colcur,valcur);
        arr[rowcur][colcur] = valcur;
        nodenew(mtx,rowcur,colcur,valcur);

#if DEBUG
        mtxdump(mtx);
#endif
    }

    printf("\n");
    mtxprint(mtx,"FIN");

    // cross check
    printf("\n");
    printf("cross check ...\n");
    int miss = 0;
    for (int rowcur = 0;  rowcur < ROWMAX;  ++rowcur) {
        for (int colcur = 0;  colcur < COLMAX;  ++colcur) {
            int valexp = arr[rowcur][colcur];

            node_t *cur = nodefind(mtx,rowcur,colcur);

            int valact;
            if (cur != NULL)
                valact = cur->node_val;
            else
                valact = -1;

            if (valact != valexp) {
                printf("DIF: [%d,%d] = %d/%d\n",rowcur,colcur,valexp,valact);
                miss = 1;
            }
        }
    }
    if (! miss)
        printf("all values match\n");

    return 0;
}

Here is the program output:

ADD: [3,4] = 37
ADD: [15,1] = 115
ADD: [6,2] = 29
ADD: [1,2] = 47
ADD: [10,4] = 83
ADD: [6,3] = 106
ADD: [12,2] = 31
ADD: [8,5] = 9
ADD: [2,5] = 82
ADD: [3,1] = 75
ADD: [9,0] = 122
ADD: [18,3] = 107
ADD: [13,0] = 51
ADD: [2,1] = 53
ADD: [1,0] = 104
ADD: [17,6] = 44
UPD: [15,1] = 73
ADD: [6,0] = 120
ADD: [16,2] = 102
ADD: [10,1] = 101
ADD: [5,6] = 4
ADD: [7,3] = 5
ADD: [6,4] = 73
ADD: [17,5] = 115
ADD: [2,3] = 94
ADD: [7,4] = 84
ADD: [3,0] = 7
UPD: [8,5] = 98
ADD: [8,4] = 63
ADD: [11,1] = 99
ADD: [12,4] = 96
ADD: [8,0] = 92
ADD: [6,6] = 74
ADD: [19,4] = 70
ADD: [14,0] = 127
UPD: [1,0] = 62
ADD: [17,0] = 132
ADD: [16,4] = 100
UPD: [6,6] = 105
ADD: [9,6] = 99
ADD: [0,3] = 31
ADD: [17,3] = 11
ADD: [1,5] = 29
UPD: [7,4] = 136
UPD: [17,5] = 106
ADD: [5,1] = 43
ADD: [19,5] = 28
ADD: [11,4] = 109
UPD: [3,4] = 10
ADD: [8,3] = 115
ADD: [0,2] = 116
UPD: [3,4] = 5
ADD: [6,5] = 81
ADD: [15,4] = 8
ADD: [4,0] = 41
ADD: [10,0] = 20
ADD: [14,2] = 4
ADD: [14,3] = 36
UPD: [3,0] = 87
ADD: [5,3] = 56
UPD: [12,4] = 77
ADD: [8,2] = 107
ADD: [14,1] = 98
ADD: [15,0] = 137
ADD: [15,2] = 38
UPD: [8,5] = 31
ADD: [8,1] = 76
ADD: [4,4] = 23
ADD: [13,2] = 126
ADD: [0,4] = 58

MATRIX R:0-19 C:0-6 (from FIN)
       0   1   2   3   4   5   6
   0   *   * 116  31  58   *   *
   1  62   *  47   *   *  29   *
   2   *  53   *  94   *  82   *
   3  87  75   *   *   5   *   *
   4  41   *   *   *  23   *   *
   5   *  43   *  56   *   *   4
   6 120   *  29 106  73  81 105
   7   *   *   *   5 136   *   *
   8  92  76 107 115  63  31   *
   9 122   *   *   *   *   *  99
  10  20 101   *   *  83   *   *
  11   *  99   *   * 109   *   *
  12   *   *  31   *  77   *   *
  13  51   * 126   *   *   *   *
  14 127  98   4  36   *   *   *
  15 137  73  38   *   8   *   *
  16   *   * 102   * 100   *   *
  17 132   *   *  11   * 106  44
  18   *   *   * 107   *   *   *
  19   *   *   *   *  70  28   *

cross check ...
all values match
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文