改写自课本例题。整个程序主要包括主函数main,建立十字链表的函数creatCrossList,和从十字链表里获取数组元素值的函数getValue,和在屏幕显示矩阵的函数display。整个矩阵的行列信息都存储在表头指针ptHead里。从这个指针开始可以获取整个矩阵的信息。既然用链表,就坚决不用数组,顺序表的灵魂就是里面包含的定长数组,通过数组下标可以快速访问所有数组数据。
代码如下:
#include<iostream>
#include<stdio.h>
using namespace std;
#define ROW 3
#define COLUMN 4
struct Node {
int row;
int column;
union{
int value;
Node* ptHead;
}ptOrValue;
Node* ptDown;
Node* ptRight;
};
void creatCrossList(Node *&ptHead,int array[ROW][COLUMN]) {
ptHead = new Node; //initial 总头指针
ptHead->row = ROW;
ptHead->column = COLUMN;
ptHead->ptOrValue.ptHead = ptHead; //already create a empty circle list
Node * ptTail = ptHead,* ptData,*ptHeadRC; //RC is short for row and column
//this ptHeadRC point represents the row and column head point.
for (int i = 0; i < (ROW > COLUMN ? ROW : COLUMN) ; i++) {
ptHeadRC = new Node;
ptHeadRC->ptRight = ptHeadRC->ptDown = ptHeadRC;
//creat empty loop list both in row and column direction
ptHeadRC->ptOrValue.ptHead = ptTail->ptOrValue.ptHead;
ptTail->ptOrValue.ptHead = ptHeadRC;
ptTail = ptHeadRC;
//insert this new head node into head-node-loop list;
}
//creat and insert data node into list
for(int row = 0 ; row < ROW ; row++)
for (int column = 0; column < COLUMN; column++)
if(array[row][column] != 0){
ptData = new Node;
ptData->row = row;
ptData->column = column;
ptData->ptOrValue.value = array[row][column];
//insert into row loop list,at row :"row"
ptHeadRC = ptHead;
for (int i = 0; i <= row; i++)
ptHeadRC = ptHeadRC->ptOrValue.ptHead;
ptTail = ptHeadRC;
while (ptTail->ptRight != ptHeadRC && ptTail->ptRight->column < column)
ptTail = ptTail->ptRight;
ptData->ptRight = ptTail->ptRight;
ptTail->ptRight = ptData;
//insert data node into column node loop list,at column :"column"
ptHeadRC = ptHead;
for (int i = 0 ; i <= column; i++)
ptHeadRC = ptHeadRC->ptOrValue.ptHead;
ptTail = ptHeadRC;
while (ptTail->ptDown != ptHeadRC && ptTail->ptDown->row < row)
ptTail = ptTail->ptDown;
ptData->ptDown = ptTail->ptDown;
ptTail->ptDown = ptData;
}
//数据节点插入链表,这里的做法很典型的体现了链表的特征,只能从表头开始查找
//when insert data node into cross list ,wo should first find the row list and
// the column list that it belongs to.
}
int getValue(Node *&ptHead,int row,int column) {
Node* ptHeadRC = ptHead,*pt;
for (int i = 0; i <= row; i++)
ptHeadRC = ptHeadRC->ptOrValue.ptHead;
pt = ptHeadRC->ptRight;
while (pt != ptHeadRC && pt->column < column)
pt = pt->ptRight;
//when this row`s elements are all zero or this element at (row,column)
//is zero ,we can not find it in the cross list.
if (pt == ptHeadRC || pt->column > column)
return 0;
else
return pt->ptOrValue.value;
}
void display(Node *& ptHead) {
int i;
for (int row = 0; row < ptHead->row; row++) {
for (int column = 0; column < ptHead->column; column++) {
i = getValue(ptHead, row, column);
if (i != 0)
printf("%5d", i);
else
printf("%5d",0);
}
cout << endl << endl;
}
}
int main() {
int array[ROW][COLUMN] = { {0,0,0,0}, {4,5,6,7}, {8,0,0,0} };
Node* ptHeadBig;
creatCrossList(ptHeadBig,array);
cout << "array is as follows : "<<endl;
display(ptHeadBig);
cout << "这样的输出比直接输出三元组更直观,thank you for your reading!" << endl;
return 0;
}
测试结果如下:
至此,稀疏矩阵的十字链表就结束了。再一点就是,稀疏矩阵一旦确定,不管里面有多少个零。取行数列数里的较大值n建立的n个行列头节点的个数是确定的,这个头节点的数目是不能省的。这是整个矩阵的框架,初始化十字链表时候已经确定了。具体的数据节点则是可有可无的。