1、建立十字链表
2、输出十字链表
3、把十字链表转换为三元矩阵
4、打印三元矩阵
5、转置三元矩阵
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
/*
2020/4/27 By:lnh
*/
#define smax 30
typedef int datatype;
typedef struct lnode{
int i,j; //非零元素行,列
struct lnode *rptr,*cptr; //行和列的表头
union{
struct lnode *next;
datatype v;
}uval;
}link;//十字链表
typedef struct{
int i,j; //行,列
datatype v; //值
}node;
typedef struct{
int m,n,t;//总行,总列,总非零元个数
node *data[smax];
}spmatrix;//三元组存储
//函数声明
link *createlinkmat();
int printlinkmat(link *h);
spmatrix *changemat(link *h);
int printmat(spmatrix *a);
spmatrix *transmat(spmatrix *a);
//主函数
int main(void)
{
link *h;
spmatrix *a,*b;
//建立十字链矩阵
h = createlinkmat();
//输出十字链矩阵
printlinkmat(h);
//把十字链矩阵转换为三元组矩阵
a = changemat(h);
//打印三元组矩阵
printmat(a);
//转置三元组矩阵
b = transmat(a);
//输出转置后的矩阵
printmat(b);
}
//建立十字链矩阵
link *createlinkmat(){
link *head,*head_rowAndColum,*A[smax],*node_data,*temp;
int row,column,num,tims,i,max,k;
datatype val;
//输入数组行,列,非零元素个数
printf("请输入该数组行,列,非零元素个数:\n输入格式:4 5 9\n");
scanf("%d %d %d",&row,&column,&num);
getchar(); //接收回车符,防止下次输入的干扰
//检测输入是否合法
if((row<=0)||(column<=0)||(num<=0))
return NULL;
//创建总表头
head = (link*)malloc(sizeof(link));
head->i = row;
head->j = column;
k = 0; //记录非零元素的个数
A[0] = head;//总表域
if(row>column)
max = row;
else
max = column;
//创建行和列的表头
for(i=1;i<=max;i++){
head_rowAndColum = (link*)malloc(sizeof(link));
head_rowAndColum->i = 0;
head_rowAndColum->j = 0;
head_rowAndColum->rptr = head_rowAndColum;//行表头
head_rowAndColum->cptr = head_rowAndColum;//列表头
A[i] = head_rowAndColum;
A[i-1]->uval.next = head_rowAndColum;
}
//形成循环行表
A[max]->uval.next = head;
//形成非零元素链表
printf("请输入该数组行,列,元素的值:(以Ctrl+Z结束)\n输入格式:4 5 9\n");
while((scanf("%d %d %d",&row,&column,&val))!=EOF){//输入非零元素
k++;
if(k>num){
printf("本次创建十字链表失败,请仔细检查并重新创建\n");
return NULL;
}
node_data = (link*)malloc(sizeof(link));
node_data->i = row;
node_data->j = column;
node_data->uval.v = val;
//查找行
temp = A[row];
while((temp->rptr!=A[row])&&(temp->rptr->j<column))
//temp的行已经有非零值并且temp的下一个节点的列小于输入的值
temp = temp->rptr; //temp指向这一行的下一个节点
node_data->rptr = temp->rptr;
temp->rptr = node_data;
//查找列
temp = A[column];
while((temp->cptr!=A[column])&&(temp->cptr->i<row))
//temp的列已经有非零值并且temp的下一个节点的行小于输入的值
temp = temp->cptr; //temp指向这一列的下一个节点
node_data->cptr = temp->cptr;
temp->cptr = node_data;
}
head = A[0];
return head;
}
//输出十字链矩阵
int printlinkmat(link *h){
int row,column,max,i;
link *head,*temp;
if(h==NULL)
return 0;
row = h->i;
//copy the value of h
head = (link*)malloc(sizeof(link));
head = h;
//打印十字列表
printf("十字列表格式(行,列,值):\n");
for(i=1;i<=row;i++){
//指向下一行的表头
head = head->uval.next;
//临时变量,不能用free函数,否则head指针也清楚了
temp = (link*)malloc(sizeof(link));
temp = head;
//打印数据
while(temp->rptr->i!=0){
temp = temp->rptr;
printf("( %d,%d,%d)\n",temp->i,temp->j,temp->uval.v);
}
}
return 1;
}
//把十字链矩阵转换为三元组矩阵
spmatrix *changemat(link *h){
spmatrix *three;
node *data_three;
link *p,*temp;
int i,k;
three = (spmatrix*)malloc(sizeof(spmatrix));
three->m = h->i; //行
three->n = h->j; //列
p = (link*)malloc(sizeof(link));
p = h; //copy h
k = 0; //记录非零元素个数
for(i=1;i<=three->m;i++){ //按行进行扫描
//指向下一行的表头
p = p->uval.next;
temp = (link*)malloc(sizeof(link));
temp = p->rptr; //指向p表头所在的行
while(temp->i!=0){ //将p这一行的非零值给三元矩阵
k++;
data_three = (node*)malloc(sizeof(node));
data_three->i = temp->i;
data_three->j = temp->j;
data_three->v = temp->uval.v;
//将该节点存入三元组中
three->data[k] = data_three;
//指向这一行的下一个元素
temp = temp->rptr;
}
}
//记录总个数
three->t = k;
return three;
}
//打印三元组矩阵
int printmat(spmatrix *a){
spmatrix *three;
node data_node;
int k,n,row,colume;
three = (spmatrix*)malloc(sizeof(spmatrix));
three = a;
k = three->t;
n = 0;
row = a->m;
colume = a->n;
int arr[row][colume];
//将矩阵存入二维数组中
memset(arr,0,sizeof(arr)); //将数组值全置为零
//打印三元组
printf("三元组是:(行,列,值)\n(");
while(n<k){
n++;
arr[three->data[n]->i-1][three->data[n]->j-1] = three->data[n]->v;
printf("(%d, %d, %d)",three->data[n]->i,three->data[n]->j,three->data[n]->v);
}
printf(")\n");
//打印矩阵
printf("矩阵是:\n");
for(n=0;n<row;n++){
for(k=0;k<colume;k++)
printf(" %d ",arr[n][k]);
printf("\n");
}
return 1;
}
//转置三元组矩阵
spmatrix *transmat(spmatrix *a){
spmatrix *b;
node *temp;
int i = 1;
b = (spmatrix*)malloc(sizeof(spmatrix));
b->m = a->n;
b->n = a->m;
b->t = a->t;
//将a的行和列互换形成一个新的三元组
while(i<=b->t){
temp = (node*)malloc(sizeof(spmatrix));
temp->i = a->data[i]->j;
temp->j = a->data[i]->i;
temp->v = a->data[i]->v;
b->data[i] = temp;
i++;
}
return b;
}
运行结果图: