十字链表用通过两个结构体进行储存,第一个结构体储存 x,y坐标与记录值。
第二个结构体则存储行的头链表与列的头链表,还有关于开辟链表的大小,x,y,z,z为非零值的个数。
然后通过一个函数去实现链表的开辟,实现十字链表。
链表的两个表头为第一个结构体的指针的指针,即其指针指向第一个结构体的指针,利用第一个结构体的指针实现输入功能。
动态建立指针数组的方式如下
p = (OLink )malloc(sizeof(OLink)(m + 1)) 即开辟(m+1)个olink的空间,用p去储存olink的地址
原理图:
#include <iostream>
#include<iomanip>
using namespace std;
typedef struct OLNode {
int i, j;//该非零元的行列下标
int e;//具体数值
struct OLNode *right , *down;//该非零元所在行表、列表的后继链域
}OLNode,*OLink;//建立一个结构,一个结构指针方便建立这个指针的数组。
typedef struct
{
OLink *rhead, *chead;//行和列 链表头指针向量基址 由CreateSMatrix分配
int mu, nu, tu;//行数,列数,非零个数
} CrossList;
void CreateSMatrix_OL(CrossList &M)
{//创建稀疏矩阵M 采用十字链表存储表示
int m, n, t,i,j,e;
cin >> m >> n >> t;; //输入M的行数列数和非零元个数
M.mu = m; M.nu = n; M.tu = t;//写入
if (!(M.rhead = (OLink *)malloc(sizeof(OLink)*(m + 1))))exit(OVERFLOW);//建立二维指针的数组,大小为(m+1)个olink的大小的数组,同时判断是否建立成功
if (!(M.chead = (OLink *)malloc(sizeof(OLink)*(n + 1))))exit(OVERFLOW);
for (int i = 0; i <= m; i++)
M.rhead[i] = NULL;//初始化表头指针为空
for (int i = 0; i <= n; i++)
M.chead[i] = NULL;//初始化表头指针为空指针
for (cin>>i>>j>>e; i != 0; cout<<i<<j<<e)
{//输入行,列,数据
OLNode *p, *q;//建立两个储存结构的指针,方便进行写入与交换功能
if (!(p = (OLNode *)malloc(sizeof(OLNode))))//建立一个p的空对象;
exit(OVERFLOW);
p->i = i;//写入行,列,非零值
p->j = j;
p->e = e;//创建新节点
if (M.rhead[i] == NULL ||M.rhead[i]->j > j)//判断表头是否为空或 行值是否小于表头指向的值;判断是否插入表头?
{
p->right = M.rhead[i];//令表头指向新节点;
M.rhead[i] = p;
}
else //这个部分,派出不插在表头
{
for (q = M.rhead[i]; (q->right) && q->right->j < j; q = q->right)//设初始值为表头,遍历j的插入位置。
{
if(q->right->j==j)
{
q.e=p.e;
break;
}
p->right = q->right;//插入
q->right = p;
}
}//完成行插入
if (M.chead[j] == NULL || M.rhead[j]->i > i)//同理 为列插入
{
p->down = M.chead[j];
M.chead[j] = p;
}
else
{
for (q = M.chead[j]; (q->down) && q->down->i < i; q = q->down)
{
if(q->right->i==i)
{
q.e=p.e;
break;
}
p->down = q->down; q->down = p;//完成列插入
}
}
}
}
int main()
{
CrossList a;
CreateSMatrix_OL(a);
}