📜  正交链表

📅  最后修改于: 2021-09-28 10:03:19             🧑  作者: Mango

正交链表是一种由称为节点(类似于链表)的基本元素组成的数据结构。正交链表中的每个节点都指向另外4个节点,分别是上、下、左、右。本质上,就像矩阵是数组的二维版本一样,正交链表是线性链表的二维版本。

将矩阵转换为正交链表的算法:

  1. 为矩阵中的每个单元格创建一个节点。在映射中,还存储单元格的值和指向为单元格创建的节点的指针。
  2. 如果当前行(i)不是矩阵的第 0行,则将当前节点的向上指针设置为它正上方单元格的节点(使用映射获取正确的指针)并将上面节点的向下指针设置为当前节点。  
  3. 同理,如果当前列(j)不是矩阵的第0列,则将当前节点的左指针设置为当前节点左边的单元格的节点,将左边的节点设置为当前节点的右指针节点
  4. 对矩阵中的每个单元格重复过程 1 到 3
  5. return map[matrix[0][0]] 返回指向正交链表左上节点的指针

下面是上述算法的一个实现。

Input:
    matrix = {
    {1, 2, 3},
    {4, 5, 6},
    {7, 8, 9}
    }

Output: 
    A Node pointing to the top-left corner of the orthogonal linked list.
    
       ^      ^      ^
       |      |      |
    <--1 <--> 2 <--> 3-->
       ^      ^      ^
       |      |      |
       v      v      v
    <--4 <--> 5 <--> 6-->
       ^      ^      ^
       |      |      |
       v      v      v
    <--7 <--> 8 <--> 9-->
       |      |      |
       v      v      v
C++
#include 
using namespace std;
  
struct MatrixNode
{
    int _val;
    MatrixNode* _u; // pointer to node above
    MatrixNode* _d; // pointer to node below
    MatrixNode* _l; // pointer to node towrads left
    MatrixNode* _r; // pointer to node towards righ
  
    // Constructor for MatrixNode
    MatrixNode( int val = 0, 
                MatrixNode* u = nullptr,
                MatrixNode* d = nullptr,
                MatrixNode* l = nullptr,
                MatrixNode* r = nullptr )
        {
            _val = val;
            _u = u;
            _d = d;
            _l = l;
            _r = r;
        }
};
  
MatrixNode* BuildOrthogonalList(int matrix[][3], int r, int c)
{
    // an unordered_map to store the {value, pointers} pair
    // for easy access while building the list
    unordered_map mp;
  
    for(int i = 0; i < r; i++)
    {
        for(int j = 0; j < c; j++)
        {
            // create a newNode for each entry in the matrix
            MatrixNode* newNode = new MatrixNode(matrix[i][j]);
            // store the pointer of the new node
            mp[matrix[i][j]] = newNode; 
  
            // set the up and down pointing pointers correctly
            if(i != 0)
            {
                newNode->_u = mp[matrix[i - 1][j]];
                mp[matrix[i - 1][j]]->_d = newNode;
            }
  
            // similarly set the left and right pointing pointers
            if(j != 0)
            {
                newNode->_l = mp[matrix[i][j - 1]];
                mp[matrix[i][j - 1]]->_r = newNode;
            }
        }
    }
  
    // return the start of the list
    return mp[matrix[0][0]];
}
  
void PrintOrthogonalList(MatrixNode* head)
{
    MatrixNode* curRow; // will point to the begin of each row
    MatrixNode* cur; // will traverse each row and print the element
    for(curRow = head; curRow != nullptr; curRow = curRow->_d)
    {
        for(cur = curRow; cur != nullptr; cur = cur->_r)
        {
            cout << cur->_val << " ";
        }
        cout << endl;
    }
}
  
int main()
{
    int matrix[3][3] = {
        {1, 2, 3},
        {4, 5, 6},
        {7, 8, 9}
    };
  
    MatrixNode* list = BuildOrthogonalList(matrix, 3, 3);
    PrintOrthogonalList(list);
  
    return 0;
}


应用:
正交链表最常见的应用是稀疏矩阵表示。简而言之,稀疏矩阵是其中大部分元素为零(或任何已知常数)的矩阵。它们经常出现在科学应用中。将稀疏矩阵表示为二维数组是一种巨大的内存浪费。相反,稀疏矩阵表示为正交链表。我们仅为矩阵中的非零元素创建一个节点,在每个节点中,我们存储值、行索引和列索引以及指向其他节点的必要指针。这节省了大量的性能开销,并且是实现稀疏矩阵的最节省内存的方式。