數組(矩陣)+ADT+代碼實現

目錄

 

表中的數據元素本身也是一個數據結構

數組

 ADT

矩陣的壓縮存儲

三元組順序表

行邏輯鏈接的順序表

稀疏矩陣的十字鏈表


 

表中的數據元素本身也是一個數據結構

數組

數組中的數據元素必須是同一數據類型

一個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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章