【问题标题】:sparse matrix using linked list C++使用链表 C++ 的稀疏矩阵
【发布时间】:2012-09-25 02:03:43
【问题描述】:

我正在编写使用链表存储稀疏矩阵的程序。首先,我创建了一个“节点”类,其中包含条目索引、条目值以及指向下一行和下一列的两个指针。其次,我在 Google 上发现我需要像下面的代码一样创建类 Matrix,但我不明白 Node **rowListnode** columnList 的含义。为什么他们在那里使用指向指针的指针,我如何从中实现矩阵?非常感谢。

class Node
{
public:
    int iValue, jValue;
    float value;
    Node *rowPtr;
    Node *colPtr;
};

class Matrix
{
    Node **rowList;     // rowList is the pointer to the array of rows
    Node **columnList;  // columnList is the pointer to the array of columns
    int rows, cols;     // number of rows and columns
}

【问题讨论】:

    标签: c++ linked-list sparse-matrix


    【解决方案1】:

    这似乎正是评论所说的。它们是数组。大概rowList 将是rows 元素的数组,columnList 将是cols 元素的数组。它是Node** 的原因是数组中的每个项目都是Node*。指向数组的指针总是有一个额外的间接级别(额外的*)。这意味着当您从该数组中索引单个元素时,您会再次获得 Node* 类型的值。

    数组是这样创建的:

    rowList = new Node* [rows];
    columnList = new Node* [cols];
    
    // Don't forget to initialise the values to NULL!  Here's the dull way:
    for( int i = 0; i < rows; i++ ) rowList[i] = NULL;
    for( int i = 0; i < cols; i++ ) columnList[i] = NULL;
    

    当您需要删除它们时(在Matrix 的析构函数中):

    delete [] rowList;
    delete [] colList;
    

    至于您关于如何从中实现矩阵的问题,这完全取决于您。大概当您在位置(i, j) 创建一个节点时,您将该节点附加到每个rowListcolumnList

    Node * node = new Node(i, j, 123.0);
    rowList[i] = node;
    columnList[j] = node;
    

    但这并不是那么简单,因为节点显然必须同时链接到行列表和列列表中。在最基本的层面上,使用您提供的结构,这是一种方法:

    // Inserts newNode at the head of the list and modifies the head pointer.
    void insert_row( Node* & r, Node *newNode )
    {
        newNode->rowPtr = r;
        if( r != NULL ) r->rowPtr = newNode;
        r = newNode;
    }
    
    // Similarly with insert_col()...
    

    现在将上面的内容与我原来的示例一起使用:

    Node * node = new Node(i, j, 123.0);
    insert_row( rowList[i], node );
    insert_col( columnList[j], node );
    

    对于有序插入

    既然你已经有了代码,我会提出我的看法。但是你还是需要自己做一些工作。

    我只是试图理解这个概念,但这让我很困惑。

    让我们从一开始就清理干净。这是一门课,你正在使用 C++,所以请使用你的 C++ 知识:

    class Node
    {
    public:
        Node( int i, int j, int val );
    
        void InsertRowAfter( Node* node );
        void InsertColAfter( Node* node );
    
        int iValue, jValue;  // Row and column index, 1-based
        float value;         // Element value
        Node *rowPtr;        // Next element in this row (sorted by jValue)
        Node *colPtr;        // Next element in this column (sorted by iValue)
    };
    
    Node::Node( int i, int j, int val )
        : iValue(i)
        , jValue(j)
        , value(val)
        , rowPtr(NULL)
        , colPtr(NULL)
    {}
    
    // Inserts the given node to follow this node in the row list
    void Node::InsertRowAfter( Node* node )
    {
        // [go on, you do it]
    }
    
    // Inserts the given node to follow this node in the column list
    void Node::InsertColAfter( Node* node );
    {
        // [go on, you do it]
    }
    

    所以,现在你需要实现Matrix::inputData 函数...基本上你做你朋友想做的事,但没有错误和内存泄漏。这意味着你可以这样开始:

    // Use 'horz' and 'vert' to search through the row and column lists.  If a
    // node needs to be created, it will be stored in 'node'.
    Node *horz = rowList[iValue - 1];
    Node *vert = columnList[jValue - 1];
    Node *node;
    
    // If there is no row list or smallest jValue, insert at the head.
    // Otherwise, search for an insert point.
    if( !horz || horz->jValue > jValue )
    {
        // [go on, you do it]
    }
    else
    {
        // Move 'horz' pointer to position at which we will append a node.
        Node *next = horz->rowPtr;
        while( next && next->jValue <= jValue ) {
            horz = next;
            next = next->rowPtr;
        }
    
        // If replacing an existing value, there's nothing else to do.
        if( horz->jValue == jValue ) {
            horz->value = value;
            return;
        }
    
        // Otherwise append a new node.
        // [go on, you do it]
    }
    

    现在,你完成了功能,别忘了做列索引...

    【讨论】:

    • 我只是更新我的代码和问题。你能回答一下吗?
    • 在我的示例中,我只是插入了值,但我确实提到它非常基本。您的朋友正在执行有序插入 - ie 搜索列表,以便按顺序保持行(和列)索引。他的代码令人困惑,因为它几乎完全没有注释,而且它所拥有的 cmets 也无济于事。不要复制你朋友的代码。他至少在做一件愚蠢的事情,还有一堆多余的事情。自己解决就行了。
    • 我认为他也做了很多多余的事情。我没有复制他的代码,我只是试图理解这个概念,但这对我来说太混乱了。我花了大约 72 个小时在这上面,但仍然无法解决。我尝试运行我朋友的代码,它可以工作,但如果你能展示一个更短的方法来做到这一点,那就太好了,我真的很感激。
    • 已编辑。在这种情况下,我给了你一些代码。我认为如果这仍然令人困惑,那么您需要绘制列表的图片以可视化您正在尝试做的事情。
    • 我无法表达我对您花时间并认为您在帖子中的感谢。感谢您添加的信息,它真的让我朝着正确的方向前进! :D
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-19
    • 1970-01-01
    • 2012-01-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多