目錄
表中的數據元素本身也是一個數據結構
數組
數組中的數據元素必須是同一數據類型
一個n維數組可以定義爲其數據元素是n-1維數組類型的一維數組類型
二維數組任一元素a[ij]存儲位置
從(0,0)開始存儲:LOC(i,j) = LOC(0,0) + (b*i+j)L
從(1,1)開始存儲:LOC(i,j) = LOC(1,1) + LOC(b*(i-1)+j-1)L;
ADT
ADT Array{
數據元素:ji = 0,...,bi-1, i = 1,2,...,n,
數據關係:R = {R1,R2,...Rn}
基本操作:
InitArray(&A,n,bound1,bound2,...,boundn);
操作結果:若維數n和各維長度合法,則構成相應的數組A,並返回OK;
DestoryArray(&A);
操作結果:銷燬數組A
Value(A,&e,index1,...,indexn);
初始條件:A是n維數組,e爲元素變量,隨後是n個下標值;
操作結果:若各下標不越界,則e賦值爲所指定的A的元素值,並返回 OK;
Assign(&A,e,index1,...,indexn);
初始條件:A是n爲數組,e爲元素變量,隨後是N個下標值
操作結果:若下標不越界,則將e的值賦給所指定的A的元素,並返回OK;
}
矩陣的壓縮存儲
三元組順序表
// 稀疏矩陣.cpp : 定義控制檯應用程序的入口點。
//
#include <stdio.h>
# include<stdlib.h>
# define ElemType int
# define Status int
# define OK 1
# define ERROR 0
# define TRUE 1
# define FALSE 0
# define OVERFLOW -1
# define MAXSIZE 10
typedef struct
{
int i, j;
ElemType e;
}Triple;
typedef struct
{
Triple data[MAXSIZE];
int mu, nu, tu;//矩陣行數,列數,非零元素個數
}TSMatrix;
Status CreateSMatrix(TSMatrix *m)
{
m = (TSMatrix *)malloc(1*sizeof(TSMatrix));
if (!m)
{
printf("內存分配失敗!\n");
return TRUE;
}
m->mu = 0;
m->nu = 0;
m->tu = 0;
return OK;
}
//銷燬矩陣
Status DestorySMatrix(TSMatrix *m)
{
if (!m)
{
printf("矩陣不存在!\n");
return ERROR;
}
m->mu = 0;
m->nu = 0;
m->tu = 0;
return OK;
}
//輸入矩陣的值
Status InputM(TSMatrix *m)
{
if (!m)
{
printf("矩陣不存在!\n");
return ERROR;
}
int c;
printf("輸入矩陣的行數,列數,非零元素個數:\n");
scanf_s("%d %d %d", &m->mu,&m->nu,&m->tu);
printf("輸入矩陣非零元素的值:\n");
for (c = 1; c <= m->tu; c++)
{
scanf_s("%d", &m->data[c].i);
scanf_s("%d", &m->data[c].j);
scanf_s("%d", &m->data[c].e);
}
return OK;
}
//打印矩陣
Status PrintM(TSMatrix m)
{
if (!(&m))
{
printf("矩陣不存在!\n");
return ERROR;
}
printf("輸出矩陣:\n");
int i, j;
int t = 1;
for (i = 1; i <= m.mu; ++i)
{
for (j = 1; j <= m.nu; ++j)
{
//非零元素
if (m.data[t].i == i && m.data[t].j == j)
printf("%d ",m.data[t++].e);
//零元素
else
printf("0 ");
}
printf("\n");
}
return OK;
}
//複製矩陣
Status CopySMatrix(TSMatrix m, TSMatrix *t)
{
if (!&m)
{
printf("矩陣不存在!\n");
return ERROR;
}
t->nu = m.nu;
t->mu = m.mu;
t->tu = m.tu;
int i;
for (i = 1; i <= m.tu; ++i)
{
t->data[i].i = m.data[i].i;
t->data[i].j = m.data[i].j;
t->data[i].e = m.data[i].e;
}
return OK;
}
//普通轉置矩陣
Status TransposeSMatrix(TSMatrix m,TSMatrix *t)
{
//普通轉置,從列開始遍歷,列數等於矩陣元素列時,進行轉置,非零元素累加
if (!&m)
{
printf("矩陣不存在!\n");
return ERROR;
}
if (!t)
{
printf("內存分配失敗!\n");
exit(OVERFLOW);
}
t->mu = m.nu;
t->nu = m.mu;
t->tu = m.tu;
if (t->tu)
{
int i = 1, j;//記錄非零元素的個數
for (j = 1; j <= t->nu; ++j)
{
for (i = 1; i <= m.tu; ++i)
{
if (m.data[i].j == j)
{
t->data[i].i = m.data[i].j;
t->data[i].j = m.data[i].i;
t->data[i].e = m.data[i].e;
i++;
}
}
}
}
return OK;
}
//快速轉置
Status FastTranposeSMatrix(TSMatrix m, TSMatrix *T)
{
T->mu = m.mu;
T->nu = m.nu;
T->tu = m.tu;
int col = 1,t,q;
int num[MAXSIZE], cpot[MAXSIZE];
if (T->tu)
{
//初始化計數數組
for (col = 1; col <= m.nu; ++col)
num[col] = 0;
for (t = 1; t <= m.tu; ++t)
++num[m.data[t].j];//求m中每一列含非零元個數
cpot[1] = 1;
//求第cpot列中第一個非零元在b.data中的序列
for (col = 2; col <= m.nu; ++col)
cpot[col] = cpot[col - 1] + num[col - 1];
for (t = 1; t <= m.tu; ++t)
{
col = m.data[t].j;
q = cpot[col];
T->data[q].i = m.data[t].j;
T->data[q].j = m.data[t].i;
T->data[q].e = m.data[t].e;
++cpot[col];
}
}
else
{
return ERROR;
}
return OK;
}
int main()
{
TSMatrix t;
TSMatrix m;
CreateSMatrix(&t);
InputM(&t);
PrintM(t);
FastTranposeSMatrix(t, &m);
PrintM(m);
/*
TransposeSMatrix(t, &m);
PrintM(m);
*/
return 0;
}
行邏輯鏈接的順序表
// 稀疏矩陣行邏輯鏈接順序表.cpp : 定義控制檯應用程序的入口點。
//
#include <stdio.h>
# include<stdlib.h>
# define Status int
# define ElemType int
# define OK 1
# define ERROR 0
# define OVERFLOW -1
# define TRUE 1
# define FALSE 0
# define MAXSIZE 10
# define MAXRC 10
typedef struct
{
ElemType e;
int i, j;
}Triple;
typedef struct
{
Triple data[MAXSIZE+1];
int rpos[MAXRC + 1];//各行第一個非零元素的位置表
int mu, nu, tu;//存儲行數,列數,非零元個數
}RLSMatrix;
//創建矩陣
Status CreateSMatrix(RLSMatrix *m)
{
int i;
Status k;
Triple T;
printf("請輸入矩陣的行數,列數 ,非零元素數:\n");
scanf_s("%d%d%d",&m->mu,&m->nu,&m->tu);
m->data[0].i = 0;//爲驗證輸入是否按照非遞減序 比較最準備
for (i = 1; i <= m->tu; ++i)
{
printf("按順序輸入第%d個非零元素所在行(1~%d),列(1~%d),元素值:", i, m->mu, m->nu);
do {
printf("輸入三元組行,列,值\n");
scanf_s("%d%d%d",&T.i,&T.j,&T.e);
k = 0;
if (T.i < 1 || T.i > m->mu || T.j < 1 || T.j > m->nu)
{
printf("行或者列超出範圍!\n");
k = 1;
return ERROR;
}
if (T.i <= m->data[i - 1].i && T.j <= m->data[i - 1].j)
{
printf("沒有按順序輸入非零元素!\n");
return ERROR;
k = 1;
}
} while (k);
m->data[i] = T;
}
for (i = 1; i <= m->tu; i++) // 計算rpos[]
if (m->data[i].i > m->data[i - 1].i)
for (T.i = 0; T.i < m->data[i].i - m->data[i - 1].i; T.i++)
m->rpos[m->data[i].i - T.i] = i;
for (i = m->data[m->tu].i + 1; i <= m->mu; i++) // 給最後沒有非零元素的幾行賦值
m->rpos[i] = m->tu + 1;
return OK;
}
//銷燬矩陣
Status DestorySMatrix(RLSMatrix *m)
{
if (!m)
{
printf("矩陣不存在!\n");
return ERROR;
}
m->mu = 0;
m->nu = 0;
m->tu = 0;
return OK;
}
//輸出矩陣
Status PrintM(RLSMatrix m)
{
if (!(&m))
{
printf("矩陣不存在!\n");
return ERROR;
}
printf("輸出矩陣:\n");
int i, j;
int t = 1;
for (i = 1; i <= m.mu; ++i)
{
for (j = 1; j <= m.nu; ++j)
{
//非零元素
if (m.data[t].i == i && m.data[t].j == j)
printf("%d ", m.data[t++].e);
//零元素
else
printf("0 ");
}
printf("\n");
}
return OK;
}
//複製矩陣
Status CopySMatrix(RLSMatrix m, RLSMatrix *t)
{
if (!&m)
{
printf("矩陣不存在!\n");
return ERROR;
}
t->nu = m.nu;
t->mu = m.mu;
t->tu = m.tu;
int i;
for (i = 1; i <= m.tu; ++i)
{
t->data[i].i = m.data[i].i;
t->data[i].j = m.data[i].j;
t->data[i].e = m.data[i].e;
t->rpos[i] = m.rpos[i];
}
return OK;
}
//快速轉置
Status TransposeSMatrix(RLSMatrix m, RLSMatrix *T)
{
T->mu = m.mu;
T->nu = m.nu;
T->tu = m.tu;
int col = 1, t, q;
int num[MAXSIZE], cpot[MAXSIZE];
if (T->tu)
{
//初始化計數數組
for (col = 1; col <= m.nu; ++col)
num[col] = 0;
for (t = 1; t <= m.tu; ++t)
++num[m.data[t].j];//求m中每一列含非零元個數
cpot[1] = 1;
//求第cpot列中第一個非零元在b.data中的序列
for (col = 2; col <= m.nu; ++col)
cpot[col] = cpot[col - 1] + num[col - 1];
for (t = 1; t <= m.tu; ++t)
{
col = m.data[t].j;
q = cpot[col];
T->data[q].i = m.data[t].j;
T->data[q].j = m.data[t].i;
T->data[q].e = m.data[t].e;
++cpot[col];
}
}
else
{
printf("矩陣不存在!\n");
return ERROR;
}
return OK;
}
//矩陣相乘
Status MultSMatrix(RLSMatrix M, RLSMatrix N, RLSMatrix *Q)
{
int arow, brow, p, q, ccol, ctemp[MAXRC + 1];
if (M.nu != N.mu) // 矩陣M的列數應和矩陣N的行數相等
return ERROR;
Q->mu = M.mu; // Q初始化
Q->nu = N.nu;
Q->tu = 0;
M.rpos[M.mu + 1] = M.tu + 1; // 爲方便後面的while循環臨時設置
N.rpos[N.mu + 1] = N.tu + 1;
if (M.tu*N.tu != 0) // M和N都是非零矩陣
{
for (arow = 1; arow <= M.mu; ++arow)
{ //從M的第一行開始,到最後一行,arow是M的當前行
for (ccol = 1; ccol <= Q->nu; ++ccol)
ctemp[ccol] = 0; //Q的當前行的各列元素累加器清零
Q->rpos[arow] = Q->tu + 1; //Q當前行的第1個元素位於上1行最後1個元素之後
/*找到每一行中的非零元素*/
for (p = M.rpos[arow]; p<M.rpos[arow + 1]; ++p)
{ // 對M當前行中每一個非零元
brow = M.data[p].j; //找到對應元在N中的行號(M當前元的列號)
/*
rpos[row]指示矩陣N的第row行中第一個非零元在N.data中的序號,rpos[row+1]-1指向的第row行最後一個非零元的位置
*/
for (q = N.rpos[brow]; q<N.rpos[brow + 1]; ++q)
{
ccol = N.data[q].j; //乘積元素在Q中列號
ctemp[ccol] += M.data[p].e*N.data[q].e;
}//for
} //求得Q中第arow行的非零元
for (ccol = 1; ccol <= Q->nu; ++ccol) //壓縮存儲該行非零元
if (ctemp[ccol])
{
if (++Q->tu>MAXSIZE)
return ERROR;
Q->data[Q->tu].i = arow;
Q->data[Q->tu].j = ccol;
Q->data[Q->tu].e = ctemp[ccol];
}//if
}//for
}//if
return OK;
}
int main()
{
RLSMatrix m,t,q;
CreateSMatrix(&m);
CopySMatrix(m, &t);
PrintM(m);
PrintM(t);
MultSMatrix(m, t, &q);
PrintM(q);
return 0;
}
稀疏矩陣的十字鏈表
// 稀疏矩陣的十字鏈表.cpp : 定義控制檯應用程序的入口點。
//
#include <stdio.h>
# include<stdlib.h>
# define ElemType int
# define Status int
# define OK 1
# define ERROR 0
# define OVERFLOW -1
# define TRUE 1
# define FALSE 0
# define MAXSIZE 10
typedef struct OLNode
{
int i, j;
ElemType e;
struct OLNode *right, *down;
}OLNode,*OLink;
typedef struct
{
OLink *rhead, *chead;//行和列鏈表頭指針向量基址
int mu, nu, tu;//稀疏矩陣的行數、列數和非零元素個數
}CrossList;
//創建稀疏矩陣,採用十字鏈表存儲表示
Status CreateSMatrix(CrossList *M)
{
OLNode *p,*q;
int m, n, t,i,j,e;
printf("輸入矩陣行數、列數、非零元個數:\n");
scanf_s("%d%d%d",&m,&n,&t);//輸入行數列數和非零元個數
M->mu = m; M->nu = n; M->tu = t;
if (!(M->rhead = (OLink*)malloc((m + 1) * sizeof(OLink))))
{
printf("內存分配失敗!\n");
exit(OVERFLOW);
}
if (!(M->chead = (OLink*)malloc((n + 1) * sizeof(OLink))))
{
printf("內存分配失敗!\n");
exit(OVERFLOW);
}
for (i = 1; i <= m; ++i)
{
M->chead[i] = NULL;//初始化行列頭指針向量;各行列鏈表爲空鏈表
M->rhead[i] = NULL;
}
while (1)
{
printf("輸入點的座標及其值:\n");
scanf_s("%d",&i);
if (i == 0)
{
printf("輸入結束!\n");
break;//以0作爲輸入結束標誌
}
scanf_s("%d%d",&j,&e);
//分配新節點
if (!(p = (OLNode *)malloc(1 * sizeof(OLNode))))
{
printf("節點內存分配失敗!\n");
exit(OVERFLOW);
}
p->i = i; p->j = j; p->e = e;//賦值
//行插入
if (M->rhead[i] == NULL || M->rhead[i]->j > j)
{
//覆蓋否指針節點,若該行沒有元素或者第一個元素在該節點之後,將p賦值給頭結點
p->right = M->rhead[i];
M->rhead[i] = p;
}
else
{
//尋找節點的插入位置
for (q = M->rhead[i]; (q->right) && q->right->j < j; q = q->right);
p->right = q->right;
q->right = p;
}
//列插入
if (M->chead[j] == NULL || M->chead[j]->i > i)
{
p->down = M->chead[j];
M->chead[j] = p;
}
else
{
for (q = M->chead[j]; (q->down) && q->down[j].i < i; q = q->down);
p->down = q->down;
q->down = p;
}
}
return OK;
}
//銷燬十字鏈表
Status DestroySMatrix(CrossList *M)
{
int i = 1;
OLNode *p, *q;
for (i = 1; i <= (*M).mu; ++i)
{
p = M->rhead[i];//遍歷指針
while (p)
{
q = p;
p = p->right;
free(q);//Q指向被釋放內存的地址
}
}
M->chead = M->rhead = NULL;
M->mu = M->nu = M->tu = 0;
return OK;
}
//訪問函數
Status visit(ElemType e)
{
printf("%d ",e);
return OK;
}
//輸出十字鏈表表示的矩陣
Status TraverseM(CrossList M,Status(*visit)(ElemType e))
{
if (!(&M))
{
printf("矩陣不存在!\n");
return ERROR;
}
printf("輸出矩陣:\n");
int i, j;
int t = 1;
OLNode* p;
for (i = 1; i <= M.mu; ++i)
{
p = M.rhead[i];
if(p)
{
for (j = 1; j <= M.nu; ++j)
{
//非零元素
if (p && p->j == j)
{
visit(p->e);
p = p->right;
}
else
{
visit(0);
}
}
}
else
{
for (j = 1; j <= M.nu; ++j)
{
printf("0 ");
}
}
printf("\n");
}
return OK;
}
//輸出十字鏈表存儲的值
Status DisplayM(CrossList M)
{
if (!(&M))
{
printf("矩陣不存在!\n");
return ERROR;
}
printf("按行輸出十字鏈表存儲的值是:\n");
int k;
OLink p;
for (k = 1; k <= M.mu; ++k)
{
p = M.rhead[k];
while (p)
{
printf("(%d,%d) e = %d",p->i,p->j,p->e);
p = p->right;
printf("\n");
}
}
return OK;
}
//複製矩陣
Status CopyM(CrossList M, CrossList *T)
{
if (!M.rhead)
{
printf("矩陣不存在!\n");
return ERROR;
}
if ((T->rhead))
DestroySMatrix(T);
int i;
OLNode *p, *q = NULL, *qr = NULL, *qc = NULL;
T->mu = M.mu; T->nu = M.nu; T->tu = M.tu;
T->rhead = (OLink *)malloc((T->mu + 1) * sizeof(OLink));
T->chead = (OLink *)malloc((T->nu + 1) * sizeof(OLink));
if (!T->chead || !T->rhead)
{
printf("內存分配失敗!\n");
exit(OVERFLOW);
}
for (i = 1; i <= M.mu; i++) // 初始化矩陣T的行頭指針向量;各行鏈表爲空鏈表
(*T).rhead[i] = NULL;
for (i = 1; i <= M.nu; i++) // 初始化矩陣T的列頭指針向量;各列鏈表爲空鏈表
(*T).chead[i] = NULL;
for (i = 1; i <= M.mu; ++i)
{
p = M.rhead[i];
while (p)
{
//因爲創建鏈表時,已經確定其位置,所以只有兩種情況
//1、第一個位置 2、鏈表尾部
q = (OLNode *)malloc(1 * sizeof(OLNode));
if (!q)
{
printf("內存分配失敗!\n");
exit(OVERFLOW);
}
q->i = p->i;
q->j = p->j;
q->e = p->e;
if (!T->rhead[i])//插在表頭
{
T->rhead[i] = q;
qr = q;//指向隊尾
}
else//表尾
{
qr->right = q;
qr = q;
}
if (!T->chead[q->j])//表頭
{
T->chead[q->j] = q;
q->down = NULL;
}
else
{
qc = T->chead[q->j];
while (qc->down)
{
qc = qc->down;
}
qc->down = q;
q->down = NULL;
}
p = p->right;
}
q->right = NULL;
}
return OK;
}
//矩陣取反
Status NegateM(CrossList M, CrossList *T)
{
if (!M.rhead)
{
printf("矩陣不存在!\n");
return ERROR;
}
if ((T->rhead))
DestroySMatrix(T);
int i;
OLNode *p, *q = NULL, *qr = NULL, *qc = NULL;
T->mu = M.mu; T->nu = M.nu; T->tu = M.tu;
T->rhead = (OLink *)malloc((T->mu + 1) * sizeof(OLink));
T->chead = (OLink *)malloc((T->nu + 1) * sizeof(OLink));
if (!T->chead || !T->rhead)
{
printf("內存分配失敗!\n");
exit(OVERFLOW);
}
for (i = 1; i <= M.mu; i++) // 初始化矩陣T的行頭指針向量;各行鏈表爲空鏈表
(*T).rhead[i] = NULL;
for (i = 1; i <= M.nu; i++) // 初始化矩陣T的列頭指針向量;各列鏈表爲空鏈表
(*T).chead[i] = NULL;
for (i = 1; i <= M.mu; ++i)
{
p = M.rhead[i];
while (p)
{
//因爲創建鏈表時,已經確定其位置,所以只有兩種情況
//1、第一個位置 2、鏈表尾部
q = (OLNode *)malloc(1 * sizeof(OLNode));
if (!q)
{
printf("內存分配失敗!\n");
exit(OVERFLOW);
}
q->i = p->i;
q->j = p->j;
q->e = -1 * p->e;
if (!T->rhead[i])//插在表頭
{
T->rhead[i] = q;
qr = q;//指向隊尾
}
else//表尾
{
qr->right = q;
qr = q;
}
if (!T->chead[q->j])//表頭
{
T->chead[q->j] = q;
q->down = NULL;
}
else
{
qc = T->chead[q->j];
while (qc->down)
{
qc = qc->down;
}
qc->down = q;
q->down = NULL;
}
p = p->right;
}
q->right = NULL;
}
return OK;
}
//矩陣相加 Q = M+N
Status AddSMatrix(CrossList M, CrossList N, CrossList *Q)
{
if (!M.chead || !N.chead)//矩陣不存在的情況
{
printf("矩陣不存在!\n");
return ERROR;
}
if (M.mu != N.mu || M.nu != N.nu)//同類型矩陣相加
{
printf("兩個矩陣不是同一個類型矩陣!\n");
return ERROR;
}
int k, i;
OLink *col;
OLNode *pm, *pn, *pq = NULL, *p;
Q->mu = M.mu; Q->nu = M.nu; Q->tu =0;//初始化變量
Q->rhead = (OLink *)malloc((Q->mu + 1)*sizeof(OLink));//按行存儲非零元素的地址
Q->chead = (OLink *)malloc((Q->nu + 1) * sizeof(OLink));//按列存儲非零元素地址
col = (OLink *)malloc((Q->nu + 1) * sizeof(OLink));//存儲每一列的最後一個非零元素地址
if (!Q->rhead || !Q->chead || !col)
{
printf("內存分配失敗!\n");
return ERROR;
}
//使用指針必須初始化
for (k = 1; k <= Q->mu; ++k)
{
Q->rhead[k] = NULL;
}
for (k = 1; k <= Q->nu; ++k)
{
col[k] = NULL;
Q->chead[k] = NULL;
}
//遍歷行
/*
每行矩陣相加有四種結果
1.M矩陣元素不爲0,N矩陣元素爲0,
2.M矩陣爲0,N矩陣不爲0
3.M矩陣與N矩陣相加不爲0
4.相加爲0
*/
for (i = 1; i <= M.mu; ++i)
{
pm = M.rhead[i];
pn = N.rhead[i];
while (pm && pn)
{
//注意循環條件是M矩陣和N矩陣元素都不爲零,所以一旦有一個行元素爲到頭,則退出;
//所以需要分別將MN中剩餘的元素插入矩陣Q中
if (pm->j < pn->j)//第一種情況,該行M元素不爲0,N矩陣元素爲0
{
p = (OLink)malloc(sizeof(OLNode));
if (!p)
{
printf("內存分配失敗!\n");
exit(OVERFLOW);
}
Q->tu++;
p->i = i;
p->j = pm->j;
p->e = pm->e;
p->right = NULL;
pm = pm->right;
}
else if (pm->j > pn->j)//第二種情況,N矩陣不爲0,M矩陣爲0
{
p = (OLink)malloc(sizeof(OLNode));
if (!p)
{
printf("內存分配失敗!\n");
exit(OVERFLOW);
}
Q->tu++;
p->i = i;
p->j = pn->j;
p->e = pn->e;
p->right = NULL;
pn = pn->right;
}
else if (pm->e + pn->e)
{
p = (OLink)malloc(sizeof(OLNode));
if (!p)
{
printf("內存分配失敗!\n");
return ERROR;
}
Q->tu++;
p->e = pm->e + pn->e;
p->i = i;
p->j = pm->j;
p->right = NULL;
pm = pm->right;
pn = pn->right;
}
else
{
pm = pm->right;
pn = pn->right;
continue;
}
//前三種情況的共同操作是將p指向的元素插入到矩陣Q中,類似與創建矩陣
if (!Q->rhead[i])
{
Q->rhead[i] = p;
pq = p;
}
else
{
pq->right = p;
pq = p;
}
if (!Q->chead[p->j])
{
Q->chead[p->j] = p;
col[p->j] = p;//col指向該列的最後一個元素
}
else
{//在列尾插入,並修改列尾指針的指向
col[p->j]->down = p;
col[p->j] = col[p->j]->down;
}
}//while(遍歷行內)
//插入M矩陣剩餘元素
while (pm)
{
p = (OLink)malloc(sizeof(OLNode));
if (!p)
{
printf("內存分配失敗!\n");
exit(OVERFLOW);
}
Q->tu++;
p->i = i;
p->j = pm->j;
p->e = pm->e;
p->right = NULL;
pm = pm->right;
if (!Q->rhead[i])
{
Q->rhead[i] = p;
pq = p;
}
else
{
pq->right = p;
pq = p;
}
if (!Q->chead[p->j])
{
Q->chead[p->j] = p;
col[p->j] = p;
}
else
{
col[p->j]->down = p;
col[p->j] = col[p->j]->down;
}
}
//插入N矩陣剩餘元素
while (pn)
{
p = (OLink)malloc(sizeof(OLNode));
if (!p)
{
printf("內存分配失敗!\n");
exit(OVERFLOW);
}
Q->tu++;
p->i = i;
p->j = pn->j;
p->e = pn->e;
p->right = NULL;
pn = pn->right;
if (!Q->rhead[i])
{
Q->rhead[i] = p;
pq = p;
}
else
{
pq->right = p;
pq = p;
}
if (!Q->chead[p->j])
{
Q->chead[p->j] = p;
col[p->j] = p;
}
else
{
col[p->j]->down = p;
col[p->j] = col[p->j]->down;
}
}
}//for(遍歷每行)
//將每一列最後一個元素的列down指針賦值
for (k = 1; k <= Q->nu; ++k)
{
if (col[k])
{
col[k]->down = NULL;
}
}
return OK;
}
//矩陣相減Q = M-N
Status SubtSMatrix(CrossList M, CrossList N, CrossList *Q)
{
if (!M.chead || !N.chead)
{
printf("矩陣不存在!\n");
return ERROR;
}
if (M.mu != N.mu || M.nu != N.nu)
{
printf("矩陣類型不一致!\n");
return ERROR;
}
CrossList tmp;
//矩陣取反
NegateM(N,&tmp);
AddSMatrix(M, tmp, Q);
return OK;
}
//矩陣乘積 Q = M*N
Status MultiSM(CrossList M, CrossList N, CrossList *Q)
{
if (!M.chead || !N.rhead)
{//矩陣不存在
printf("矩陣不存在!\n");
return ERROR;
}
if (M.mu != N.nu)
{//M矩陣行數不等於列數,不能相乘
printf("M矩陣行不等於N的列數,不能相乘!\n");
return ERROR;
}
if (Q->rhead)
DestroySMatrix(Q);
int i, k,j;
ElemType e;
OLink p0, q0, q, q1 = NULL, q2 = NULL;
//初始化
Q->mu = M.mu; Q->nu = N.nu; Q->tu = 0;
Q->chead = (OLink *)malloc((Q->nu + 1) * sizeof(OLink));
Q->rhead = (OLink *)malloc((Q->nu + 1) * sizeof(OLink));
if (!Q->rhead || !Q->chead)
{
printf("內存分配失敗!\n");
return ERROR;
}
//初始化指針
for (k = 1; k <= Q->mu; ++k)
{
Q->rhead[k] = NULL;
}
for (k = 1; k <= Q->nu; ++k)
{
Q->chead[k] = NULL;
}
for (i = 1; i <= Q->mu; ++i)
{
for (j = 1; j <= Q->nu; ++j)
{
p0 = M.rhead[i];//p0指向M中行元
q0 = N.chead[j];//q0指向q中列元
e = 0;
while (p0 && q0)
{
if (q0->i < p0->j)//q0所在行小於p0所在列
{
q0 = q0->down;
}
else if (q0->i > p0->j)//q0所在行小於p0所在列
{
p0 = p0->right;
}
else//兩元素可以相乘
{
e += p0->e * q0->e;
p0 = p0->right;
q0 = q0->down;
}
}
if (e)//乘積不爲0可以插入矩陣
{
Q->tu++;
q = (OLink)malloc(sizeof(OLNode));
if (!q)
{
printf("內存分配失敗!\n");
exit(OVERFLOW);
}
q->i = i;
q->j = j;
q->e = e;
q->right = NULL;
q->right = NULL;
//行插入
if (!Q->rhead[i])
{
Q->rhead[i] = q;
q1 = q;
}
else
{
q1->right = q;
q1 = q;
}
//列插入
if (!Q->chead[j])
{
Q->chead[j] = q;
}
else
{
q2 = Q->chead[j];
while (q2->down)
{
q2 = q2->down;
}
q2->down = q;
}
}//while
}//for_j
}//for_i
return OK;
}
int main()
{
CrossList m,t,n;
printf("輸入矩陣m:\n");
CreateSMatrix(&m);
TraverseM(m,visit);
printf("輸入矩陣n:\n");
CreateSMatrix(&n);
TraverseM(n, visit);
/*
MultiSM(m, n, &t);
TraverseM(t,visit)
SubtSMatrix(m, n, &t);
TraverseM(t,visit);
AddSMatrix(m, n, &t);
TraverseM(t, visit);
*/
return 0;
}
參考鏈接:
https://www.cnblogs.com/mycapple/archive/2012/08/03/2620932.html