今天研究了一下十字链表,当稀疏矩阵的内部元素经常变化时,用三元顺序表操作起来比较麻烦,故用链表来实现对稀疏矩阵的存储,由于矩阵具有二维特性,单链表显然不适用,采用十字链表来实现对稀疏矩阵的存储。
十字链表有三种结点,1.总表头结点 2.行列表头结点 3.非零元素结点。下面一一介绍
1.总表头结点
共有5个子域
Row | Col | Next | |
Down | Right |
Row总行数
Col 总列数
Next 指向第一个行列表头结点
down和right两个指针域空置
2.行列表头结点
行列表头结点的结构与总表头结点相同,m行n列的矩阵需设置S(max(m,n))个行列表头结点
0 | 0 | Next | |
Down | Right |
next指向下一个行列表头结点
right指向本行第1个非零元素结点
down指向本列第1个非零元素结点
行列表头构成循环链表。稀疏矩阵的最后一个头结点next域要求指向总表头结点。
3.非零元素结点
i | j | aij | |
Down | Right |
row、col域存放行下标和列下标
right域指向本行的下一个非零元素结点
down域指向本列的下一个非零元素结点
行循环链表
最后一个非零元素结点的right指向行表头结点
同理列循环链表
本文实现了稀疏矩阵的建立和显示,见代码:
Linkedmatrix.h
#ifndef LINKEDMATRIX_H_
#define LINKEDMATRIX_H_
typedef int ElemType;
struct Node
{
int row;
int col;
Node *down;
Node *right;
union//共用体
{
Node *next;
ElemType val;
};
};
class Linkedmat
{
private:
Node *hm;
public:
Linkedmat();
~Linkedmat();
void Create();
void Show();
};
#endif
Linkedmatrix.cpp
#include "stdafx.h"
#include "Linkedmatrix.h"
#include <iostream>
using namespace std;
Linkedmat::Linkedmat()
{
}
Linkedmat::~Linkedmat()
{
Node *p,*p1;
int i;
for(i=1, p=hm->next; i<=hm->col; i++)//按行展开
{
p1=p->right;
while(p1!=p)
{
p->right=p1->right;
delete p1;
p1=p->right;
}
}
p=hm->next;
while(p!=hm)
{
hm->next=p->next;
delete p;
p=hm->next;
}
delete hm;
}
void Linkedmat::Create()
{
int m,n,s,r,c,v;
Node *p, *q, *h[15];
cout<<"请输入您要创建的矩阵维数:"<<endl;
cout<<"行数:"; cin>>m;
cout<<"列数:"; cin>>n;
s=m>n? m:n;
p=new Node;
p->row=m; p->col=n;
hm=p;
h[0]=p;
for(int i=1; i<=s; i++)
{
p=new Node;
p->row=0;
p->col=0;
h[i]=p;
p->right=p;
p->down=p;
h[i-1]->next=p;
}
h[s]->next=hm;//行表头循环链表
cout<<"注意:"<<endl;
cout<<"最大行坐标:"<<m<<endl;
cout<<"最大列坐标:"<<n<<endl;
cout<<"三元组最多个数:"<<m*n<<endl;
cout<<"若输入不在此范围内的数据将丢失!"<<endl;
int t;
cout<<"输入非零元素个数t = "; cin>>t;
cout<<"输入三元组的格式(以空格分开):r c v(回车)"<<endl;
for(int i=0; i<t; i++)
{
cout<<"输入三元组:";cin >>r>>c>>v;
p=new Node;
p->row=r;
p->col=c;
p->val=v;
//在行上寻找插入位置
q=h[r];
while((q->right!=h[r])&&(q->right->col<c))
{
q=q->right;
}
p->right=q->right;
q->right=p;
//在列上寻找插入位置
q=h[c];
while((q->down!=h[c])&&(q->down->row<r))
{
q=q->down;
}
p->down=q->down;
q->down=p;
}
}
void Linkedmat::Show()
{
Node *p,*p1;
int i,j;
cout<<"此十字链表存储的矩阵为:"<<endl;
for(i=1, p=hm->next; p!=hm && i<=hm->row; i++)//按行展开
{
p1=p->right;
for(j=1; j<=hm->col; j++)
{
if(p1!=p)
{
if(p1->col==j)
{
cout<<p1->val<<" ";
p1=p1->right;
}
else
{
cout<<"0"<<" ";
}
}
else
{
cout<<"0"<<" ";
}
}
cout<<endl;
p=p->next;
}
//
}
main.cpp
// main.cpp : 定义控制台应用程序的入口点。
//十字链表
#include "stdafx.h"
#include <iostream>
#include "Linkedmatrix.h"
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
Linkedmat Matrix;
Matrix.Create();
Matrix.Show();
system("pause");
return 0;
}
结果为: