#ifndef ARRAY_H
#define ARRAY_H
#include"Head.h"
#define MAX_ARRAY_DIM 8
#define MU 20
#define NU 20
#define MAX_ARRAY_SIZE 12500
//数组
typedef struct {
ElemType_Int* base;//数组元素基址
int dim;//数组维度
int* bounds;//数组维界基址
int* constants;//数组映像函数常量基址
}Array;
//
//理解定义可参考https://www.cnblogs.com/kangjianwei101/p/5227234.html
//
//三元组顺序表
typedef struct {
int i, j;
ElemType_Int e;
}Triple;
typedef struct {
Triple data[MAX_ARRAY_SIZE + 1];
int mu, nu, tu;//矩阵行列和非零元个数
}TSMartix;
//行逻辑链接的顺序表
typedef struct {
Triple data[MAX_ARRAY_SIZE + 1];
int rops[MAX_ARRAY_SIZE + 1];//各行第一个非零元的位置表
int mu, nu, tu;
}RLSMartix;
//十字链表
typedef struct OLNode {
int i, j;
ElemType_Int e;
struct OLNode* right, * down;
}OLNode, * OLink;
typedef struct {
OLink* rhead, * chead;
int mu, nu, tu;
}CrossList;
//广义表
typedef enum { ATOM, LIST }ElemTag;
typedef struct GLNode {
ElemTag tag;
union {
ElemType_Int atom;
struct {
struct GLNode* hp, * tp;
}ptr;
};
}GLNode, * GList;//广义表的链式存储
typedef struct MPNode {
ElemTag tag;
int exp;
union {
float coef;
struct MPNode* hp;
};
struct MPNode* tp;
}*MPList;
//数组的创建
Status InitArray(Array* A, int dim, ...);
//十字链表的创建
Status InitCrossList(CrossList* C, FILE* fp);
//销毁
Status DestoryArray(Array* A);
//元素定位
Status LocateArray(Array A, va_list ap, int* off);
//获取下标所指元素的值
Status ValueArray(Array A, ElemType_Int* e, ...);
//将e赋给所指下标元素
Status Assign(Array* A, ElemType_Int e, ...);
//三元组顺序表
//矩阵的加法
//赋值函数
void AssignTSM(Triple* T, int i, int j, int e);
//把B中的从i到j的元素赋给A从p开始
void CopyTSMartix(TSMartix* A, TSMartix B, int i, int j, int p);
Status AddTSMartix(TSMartix* A, TSMartix B);
//十字链表的加法
Status AddCrossList(CrossList* A, CrossList B);
//矩阵的转置
Status TransTSMartix(TSMartix* A, TSMartix B);
//快速转置
Status FastTransTSMartix(TSMartix* A, TSMartix B);
//矩阵的乘法
//行逻辑链接的顺序表
Status MultRLSMartix(RLSMartix A, RLSMartix B, RLSMartix* M);
//十字链表
Status MultCrossList(CrossList A, CrossList B, CrossList* M);
//打印输出
Status OutPutArray(Array A);
Status OutPutTSMatix(TSMartix T);
Status OutPutRLSMartix(RLSMartix M);
Status OutPutCrossLink(CrossList L);
#endif // !ARRAY_H
#ifndef ARRAY_C
#define ARRAY_C
#include"Array.h"
//数组的创建
Status InitArray(Array* A, int dim, ...) {
if (dim<1 || dim>MAX_ARRAY_DIM)
return ERROR;
(*A).dim = dim;
(*A).bounds = MALLOC(dim, ElemType_Int);
(*A).constants = MALLOC(dim, ElemType_Int);
int elemtotal = 1;
int i;
va_list ap;
va_start(ap, dim);
for (i = 0; i < dim; i++) {
(*A).bounds[i] = va_arg(ap, int);
if ((*A).bounds[i] < 0)
return UNDERFLOW;
elemtotal *= (*A).bounds[i];
}
va_end(ap);
(*A).base = MALLOC(elemtotal, ElemType_Int);
(*A).constants[dim - 1] = 1;
for (i = dim - 2; i >= 0; i--)
(*A).constants[i] = (*A).bounds[i + 1] * (*A).constants[i + 1];
return OK;
}
//十字链表的创建
Status InitCrossList(CrossList* C, FILE* fp) {
Scanf(fp, "%d%d%d", &(*C).mu, &(*C).nu, &(*C).tu);
int row, col, count;
OLink p, q;
(*C).rhead = MALLOC((*C).mu + 1, OLink);
(*C).chead = MALLOC((*C).nu + 1, OLink);
for (row = 1; row <= (*C).mu; (*C).rhead[row] = NULL, row++);
for (col = 1; col <= (*C).mu; (*C).chead[col] = NULL, col++);
for (count = 0; count < (*C).tu; count++) {
p = MALLOC(1, OLNode);
Scanf(fp, "%d%d%d", &p->i, &p->j, &p->e);
if (!(*C).rhead[p->i] || (*C).rhead[p->i]->j > p->j) {
p->right = (*C).rhead[p->i];
(*C).rhead[p->i] = p;
}
else {
for (q = (*C).rhead[p->i]; q->right && q->right->j < p->j; q = q->right);
p->right = q->right;
q->right = p;
}
if (!(*C).chead[p->j] || (*C).chead[p->j]->j > p->j) {
p->down = (*C).chead[p->j];
(*C).rhead[p->j] = p;
}
else {
for (q = (*C).chead[p->j]; q->down && q->down->i < p->i; q = q->down);
p->down = q->down;
q->down = p;
}
}
return OK;
}
//销毁
Status DestoryArray(Array* A) {
if (!(*A).base) return ERROR;
free((*A).base);
(*A).base = NULL;
if (!(*A).bounds) return ERROR;
free((*A).bounds);
(*A).bounds = NULL;
if (!(*A).constants) return ERROR;
free((*A).constants);
(*A).constants = NULL;
return OK;
}
//元素定位
Status LocateArray(Array A, va_list ap, int* off) {
int ind;
*off = 0;
for (int i = 0; i < A.dim; i++) {
ind = va_arg(ap, int);
if (ind < 0 || ind >= A.bounds[i])
return OVERFLOW;
*off += A.constants[i] * ind;
}
return OK;
}
//获取下标所指元素的值
Status ValueArray(Array A, ElemType_Int* e, ...) {
va_list ap;
int result, off;
va_start(ap, e);
if ((result = LocateArray(A, ap, &off)) <= 0) return result;
*e = *(A.base + off);
return OK;
}
//将e赋给所指下标元素
Status Assign(Array* A, ElemType_Int e, ...) {
va_list ap;
int result, off;
va_start(ap, e);
if ((result = LocateArray(*A, ap, &off)) <= 0) return result;
*((*A).base + off) = e;
return OK;
}
//三元组顺序表
//矩阵的加法
//赋值函数
void AssignTSM(Triple* T, int i, int j, int e) {
(*T).e = e;
(*T).i = i;
(*T).j = j;
}
//把B中的从i到j的元素赋给A从p开始
void CopyTSMartix(TSMartix* A, TSMartix B, int i, int j, int p) {
while (i <= j) {
Assign(&(*A).data[p++], B.data[i].i, B.data[i].j, B.data[i].e);
i++;
}
}
Status AddTSMartix(TSMartix* A, TSMartix B) {
if ((*A).mu != B.mu || (*A).nu != B.nu)
return ERROR;
int count1 = (*A).tu, count2 = B.tu, count=MAX_ARRAY_SIZE;
(*A).tu += B.tu;
while (count1 >= 0 && count2 >= 0) {
if ((*A).data[count1].i == B.data[count2].i)
if ((*A).data[count1].j == B.data[count2].j) {
if ((*A).data[count1].e + B.data[count2].e)
AssignTSM(&(*A).data[count], (*A).data[count1].i, (*A).data[count1].i, (*A).data[count1].e + B.data[count2].e);
(*A).tu--;
count1--;
count2--;
}
else if ((*A).data[count1].j > B.data[count2].j) {
AssignTSM(&(*A).data[count], (*A).data[count1].i, (*A).data[count1].j, (*A).data[count1].e);
count1--;
}
else {
AssignTSM(&(*A).data[count], B.data[count2].i, B.data[count2].j, B.data[count2].e);
count2--;
}
else if ((*A).data[count1].i < B.data[count2].i) {
AssignTSM(&(*A).data[count], B.data[count2].i, B.data[count2].j, B.data[count2].e);
count2--;
}
else {
AssignTSM(&(*A).data[count], (*A).data[count1].i, (*A).data[count1].j, (*A).data[count1].e);
count1--;
}
count--;
}
if (!count1) {
if (count2) {
CopyTSMartix(A, B, 0, count2, 0);
CopyTSMartix(A, *A, count, MAX_ARRAY_SIZE, count2);
}
}
else
CopyTSMartix(A, *A, count, MAX_ARRAY_SIZE, count1);
return OK;
}
//十字链表的加法
Status AddCrossList(CrossList* A, CrossList B) {
OLink pre, p, q, t;
int i, j;
for (i = 1; i < (*A).mu; i++) {
q = (*A).rhead[i];//q指向A第i行的第一个元素
pre = NULL;
p = B.rhead[i];//p指向B第i行的第一个元素
if (!q && p) {//若A中第i行无元素并且B中第i行有元素
(*A).rhead[i] = p;
while (p) {
loop1:if (!(*A).chead[p->i] || (*A).chead[p->i]->i > p->i) {//A中第p的列无元素或首元素的行值大于p的行值
p->down = (*A).chead[p->i];
(*A).chead[p->i] = p;
}
else {
q = (*A).chead[p->i];
while (q->down && q->down->i < p->i)
q = q->down;
p->down = q->down;
q->down = p;
}
p = p->right;
}
}
else {
while (p && q) {
if (p->j == q->j) {
p->e += q->e;
p = p->right;
t = q;
q = q->right;
free(t);
}
else if (p->j > q->j) {
if (!pre) {
p->right = q;
(*A).rhead[i] = p;
}
else {
while (q->right && q->right < p->j)
q = q->right;
p->right = q->right;
q->right = p;
}
if (!(*A).chead[p->i] || (*A).chead[p->i]->i > p->i) {
p->down = (*A).chead[p->i];
(*A).chead[p->i] = p;
}
else {
q = (*A).chead[p->i];
while (q->down && q->down->i < p->i)
q = q->down;
p->down = q->down;
q->down = p;
}
pre = p;
p = p->right;
}
else
q = q->right;
}
if (!q && p)//p到行尾但q还没到
goto loop1;
}
}
}
//矩阵的转置
Status TransTSMartix(TSMartix* A, TSMartix B) {
int i, j, t;
t = 1;
for (i = 1; i <= B.mu; i++)
for (j = 1; j <= B.tu; j++)
if (B.data[j].j == i) {
AssignTSM(&(*A).data[t], B.data[j].j, B.data[j].i, B.data[j].e);
t++;
}
}
//快速转置
Status FastTransTSMartix(TSMartix* A, TSMartix B) {
int* num, * cpot;//存放转置后的矩阵每行的元素个数和该行第一元素在三元组中的位置
int i;
num = MALLOC(B.mu + 1, int);
cpot = MALLOC(B.mu + 1, int);
for (i = 1; i <= B.mu; num[i] = 0, cpot[i] = 0, i++);
for (i = 1; i <= B.tu; i++)
num[B.data[i].j]++;
cpot[1] = 1;
for (i = 2; i <= B.mu; cpot[i] = cpot[i - 1] + num[i - 1], i++);
(*A).mu = B.nu;
(*A).nu = B.mu;
(*A).tu = B.tu;
for (i = 1; i <= B.tu; i++) {
AssignTSM(&(*A).data[cpot[B.data[i].j]], B.data[i].j, B.data[i].i, B.data[i].e);
cpot[B.data[i].j]++;
}
return OK;
}
//矩阵的乘法
//行逻辑链接的顺序表
Status MultRLSMartix(RLSMartix A, RLSMartix B, RLSMartix* M) {
if (A.nu != B.mu)
return ERROR;
int* ctemp = MALLOC(B.nu + 1, int);//存储每行中的非零元个数
(*M).mu = A.mu;
(*M).nu = B.nu;
(*M).tu = 0;
int arow, acol, ccol, brow, i, t, p, q;
if (A.tu * B.tu) {
for (arow = 1; arow <= A.mu; arow++) {//处理A中的每一行
for (i = 1; i <= A.nu; ctemp[i] = 0, i++);//当前行累加器清零
(*M).rops[arow] = (*M).tu + 1;//位置表
if (arow < A.mu) t = A.rops[arow + 1];
else t = A.tu + 1;//找出A中当前行的上限
for (p = A.rops[arow]; p < t; p++) {
brow = A.data[p].i;
if (brow < B.mu) brow = B.rops[brow + 1];
else brow = B.tu + 1;//找出B中当前行的上限
for (q = B.rops[brow]; q < brow; q++)
ctemp[B.data[q].j] += A.data[q].e * B.data[p].e;
}//for p
for (ccol = 1; ccol <= B.nu; ccol++) {
if (ctemp[ccol]) {
if (++(*M).tu > MAX_ARRAY_SIZE) return ERROR;
AssignTSM(&(*M).data[(*M).tu], arow, ccol, ctemp[ccol]);
}//if
}//for ccol
}
}
free(ctemp);
ctemp = NULL;
return OK;
}
//十字链表
Status MultCrossList(CrossList A, CrossList B, CrossList* M) {
if (A.nu != B.mu)
return ERROR;
int* ctemp = MALLOC(B.nu + 1, int);//存储每行中的非零元个数
(*M).mu = A.mu;
(*M).nu = B.nu;
(*M).tu = 0;
int arow, i;
OLNode* p, * q;
(*M).rhead = MALLOC((*M).mu + 1, OLink);
(*M).chead = MALLOC((*M).nu + 1, OLink);
for (i = 1; i <= (*M).mu; (*M).rhead[i] = NULL, i++);
for (i = 1; i <= (*M).mu; (*M).chead[i] = NULL, i++);
for (arow = 1; arow <= A.mu; arow++) {
for (i = 1; i <= A.nu; ctemp[i] = 0, i++);//当前行累加器清零
for (p = A.rhead[arow]; p; p = p->right) {
for (q = B.chead[p->j]; q; q = q->down)
ctemp[q->j] = p->e * q->e;
}
for(i=1;ii = arow;
p->j = i;
p->e = ctemp[i];
if (!(*M).rhead[p->i] || (*M).rhead[p->i]->j > p->j) {
p->right = (*M).rhead[p->i];
(*M).rhead[p->i] = p;
}
else {
for (q = (*M).rhead[p->i]; q->right && q->right->j < p->j; q = q->right);
p->right = q->right;
q->right = p;
}
if (!(*M).chead[p->j] || (*M).chead[p->j]->j > p->j) {
p->down = (*M).chead[p->j];
(*M).rhead[p->j] = p;
}
else {
for (q = (*M).chead[p->j]; q->down && q->down->i < p->i; q = q->down);
p->down = q->down;
q->down = p;
}
}
}
free(ctemp);
return OK;
}
//打印输出
Status OutPutArray(Array A) {
for (int i = 0; i < A.bounds[0] * A.constants[0]; i++) {
printf("%3d", A.base[i]);
if (!((i + 1) % A.bounds[1]))
printf("\n");
}
printf("\n");
return OK;
}
Status OutPutTSMatix(TSMartix T) {
int k;
k = 1;
printf("row\tcol\tdata\n");
while (k <= T.tu) {
printf("%d\t%d\t%d\n", T.data[k].i, T.data[k].j, T.data[k].e);
k++;
}
printf("\n");
return OK;
}
Status OutPutRLSMartix(RLSMartix M) {
int i;
printf("i\tj\te\n");
for (i = 1; i <= M.tu; i++)
printf("%d\t%d\t%d\n", M.data[i].i, M.data[i].j, M.data[i].e);
printf("col\tpos\n");
for (i = 1; i <= M.mu; i++)
printf("%d\t%d\n", i, M.rops[i]);
printf("\n");
return OK;
}
Status OutPutCrossLink(CrossList L) {
int row;
OLNode* p;
printf("i\tj\te\n");
for (row = 1; row <= L.mu; row++) {
p = L.rhead[row];
while (p) {
printf("%d\t%d\t%d\n", (*p).i, (*p).j, (*p).e);
p = p->right;
}
}
printf("\n");
return OK;
}
#endif // !ARRAY_C