(數據結構課程設計)稀疏矩陣運算器

1.設計內容
  稀疏矩陣是指那些多數元素爲零的矩陣。利用「稀疏」特色進行存儲和計算能夠大大節省存儲空間,提升計算準備效率。實現一個能進行稀疏矩陣基本運算的運算器。
具體功能有:
(1)以「帶行邏輯連接信息」的三元組順序表示稀疏矩陣,實現兩個稀疏矩陣相加、相減、相乘、求逆以及矩陣轉置和求矩陣對應行列式值的功能。
(2)稀疏矩陣的輸入形式採用三元組表示,而運算結果的矩陣則以一般的陣列形式列出。
2. 本設計所採用的數據結構
稀疏矩陣採用帶行邏輯連接信息的三元組順序存儲


本設計最終代碼實現以下(C語言):數據結構

#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#include<conio.h>
#include<malloc.h>
#include<string.h>
#define MAXSIZE 100          /*假設非零元個數的最大值爲100*/
#define MAXMU 25              /*稀疏矩陣最大行列值爲25*/
typedef struct
{
	int i,j;                 /*該非零元的行下標和列下標*/
	int v;
}Triple;
typedef struct            /*稀疏矩陣是由三元組的順序存儲*/
{   int rpos[MAXMU+1];	     /*各行第一個非零元素的位置表*/
	Triple data[MAXSIZE+1];  /*非零元三元組順序表,data[0]未使用*/
	int mu,nu,tu;            /*矩陣的行數,列數和非零元個數*/
}TSMatrix;

void creat(TSMatrix *T) /*由用戶輸入建立稀疏矩陣*/
{
	int row,num,k;
	do
	{
		system("cls");
		system("color 4f");
		printf("\n 請輸入矩陣!\n");
		printf("*********************************\n");
		printf(" 請輸入稀疏矩陣行數: ");
		scanf("%d", &T->mu);
		if (T->mu<0 || T->mu>MAXMU)
			printf("\n 行數超出定義範圍,請從新輸入!\n");
	} while (T->mu<0 || T->mu>MAXMU);
	do
	{
		printf(" 請輸入稀疏矩陣列數: ");
		scanf("%d", &T->nu);
		if (T->nu<0 || T->nu>MAXMU)
			printf("\n 列數超出定義範圍,請從新輸入!\n");
	} while (T->nu<0 || T->nu>MAXMU);
	do
	{
		printf(" 請輸入稀疏矩陣的非零元素個數: ");
		scanf("%d", &T->tu);
		if (T->tu>MAXSIZE || (T->tu>T->mu*T->nu))
			printf("\n 非零元素個數超出定義範圍,請從新輸入!\n");
	} while (T->tu>MAXSIZE || (T->tu>T->mu*T->nu));
	printf("**********************************\n");
	printf(" 請按行從小到大依次輸入結點信息!\n");
	for (k=1; k<=T->tu; k++)
	{
		do
		{
			printf(" 請按三元組存儲輸入第%d個非零元素的行數i:", k);
			scanf("%d", &T->data[k].i);
			if (!T->data[k].i || T->data[k].i>T->mu)
				printf("\n 輸入有誤,請從新輸入!\n");
		} while ((!T->data[k].i || T->data[k].i>T->mu));
		do
		{
			printf(" 請按三元組存儲輸入第%d個非零元素的列數j:", k);
			scanf("%d", &T->data[k].j);
			if (!T->data[k].j || T->data[k].j>T->nu)
				printf("\n 輸入有誤,請從新輸入!\n");
		} while ((!T->data[k].j || T->data[k].j>T->nu));
		do
		{
			printf(" 請按三元組存儲輸入第%d個非零元素的值v:", k);
			scanf("%d", &T->data[k].v);
			if (T->data[k].v==0)
				printf("\n 輸入有誤,請從新輸入!\n");
		} while (T->data[k].v==0);
		printf("***********************************\n");
	}
	for(row=1,num=1;row<=T->mu;row++)   /*行邏輯連接信息存儲*/
	{
		T->rpos[row]=num;
		while(T->data[num].i==row)
			num++;
	}
	return;
}

void print(TSMatrix A)   /*輸出稀疏矩陣*/
{
	int q,n,k,a=0;
    system("cls");
    system("color 4f");
    printf("\n\n通過稀疏矩陣運算器運算,所得結果爲:\n");
    printf("***********************************\n");
    printf("***********************************\n");
	for(n=1;n<=A.mu;n++)
	{
	 for(k=1;k<=A.nu;k++)
       {
		 for(q=1;q<=A.tu;q++)
			 if(A.data[q].i==n && A.data[q].j==k)
			 {
				 printf("\t%-3d",A.data[q].v);break;
			 }
		 if(q>A.tu)
			 printf("\t%-3d",a);		 
	   }
	 printf("\n");
	} 
	printf("***********************************\n");
	printf("***********************************\n");
 }

void add(TSMatrix A,TSMatrix B)   /*加法運算*/
{
	system("color 4f");
	int n,k;
	if(A.mu!=B.mu || A.nu!=B.nu)
	{ 
		printf("\n          不知足矩陣相加條件!"); 
        printf("\n 需知足兩矩陣的行數、列數均對應相等方可進行加法運算!!");
	}
	else  
	{
		for(n=1;n<=A.tu;n++)
	         for(k=1;k<=B.tu;k++)   /*將矩陣A的非零元接至B中*/
				 if(A.data[n].i==B.data[k].i && A.data[n].j==B.data[k].j)
				 {
					 A.data[n].v+=B.data[k].v;
			         B.data[k].v=0;
				 }
		for(k=1;k<=B.tu;k++)
			if(B.data[k].v!=0)
			{
				A.data[A.tu+1].i=B.data[k].i;
				A.data[A.tu+1].j=B.data[k].j;
				A.data[A.tu+1].v=B.data[k].v;
				A.tu++;	
			}
		print(A);
     }
}

void sub(TSMatrix A,TSMatrix B)   /*減法運算*/
{
	system("color 4f");
	int n,k;
    if(A.mu!=B.mu || A.nu!=B.nu)
	{
		printf("\n    不知足矩陣相減條件!"); 
		printf("\n 須要知足兩矩陣的行數、列數均對應相等方可進行減法運算!!");
	}
	else
	{
	    for(n=1;n<=A.tu;n++)
	        for(k=1;k<=B.tu;k++)   /*將矩陣A的非零元接至B中*/
				if(A.data[n].i==B.data[k].i && A.data[n].j==B.data[k].j)
				{
					A.data[n].v-=B.data[k].v;
					B.data[k].v=0;
				}
            for(k=1;k<=B.tu;k++)
				if(B.data[k].v!=0)
				{
					A.data[A.tu+1].i=B.data[k].i;
				    A.data[A.tu+1].j=B.data[k].j;
				    A.data[A.tu+1].v=-B.data[k].v;
				    A.tu++;
				}
		print(A);  
	}
}

void mult(TSMatrix A,TSMatrix B,TSMatrix *c)   /*乘法運算*/
{
	system("color 4f");
	int arow,tp,i,t;
	int ccol,p,brow,q;
	int ctemp[MAXMU+1];
	if(A.nu!=B.mu)
	{
		printf(" 矩陣不知足相乘條件!");
		return ;
	}
	c->mu=A.mu;
	c->nu=B.nu;
	c->tu=0;
	if(A.tu==0||B.tu==0)
	{
		printf(" 結果矩陣爲零!");
		return ;
	}
	else
	{
		for(arow=1;arow<=A.mu;arow++)
		{
			for(i=0;i<MAXMU;i++)    /*存儲器清零*/
				ctemp[i]=0;
			c->rpos[arow]=c->tu+1;
			if(arow<A.mu)
				tp=A.rpos[arow+1];
			else
				tp=A.tu+1;
			for(p=A.rpos[arow];p<tp;p++)
			{
				brow=A.data[p].j;
				if(brow<B.mu)
					t=B.rpos[brow+1];
				else
					t=B.tu+1;
				for(q=B.rpos[brow];q<t;q++)
				{
					ccol=B.data[q].j;
					ctemp[ccol]+=A.data[p].v*B.data[q].v;
				}
			}
			for(ccol=1;ccol<=c->nu;ccol++)
				if(ctemp[ccol])
				{
					if(++(c->tu)>MAXSIZE)
					{
						printf("超出範圍!");
						return ;
					}
				    c->data[c->tu].v=ctemp[ccol];
				    c->data[c->tu].i=arow;
				    c->data[c->tu].j=ccol;
				}
		}
	}
	print(*c);
}

char menu()   /*計算器主界面(菜單)*/
{
	char n;
    system("color 4f"); 
	system("title 稀疏矩陣運算器"); 
    system("cls");
	system("mode con cols=70 lines=30");
    printf("\n");
    printf("\n            課程設計  ******班                      \n\n\n\n\n\n");
 
    printf("              ****************************************          \n");
    printf("              *                                      *          \n");
    printf("              *         稀 疏 矩 陣 運 算 器         *          \n");
    printf("              *                                      *          \n");
    printf("              *             實 現 運 算              *          \n");
    printf("              *                                      *          \n");
    printf("              *             1:矩陣相加               *          \n");
    printf("              *             2:矩陣相減               *          \n");
    printf("              *             3:矩陣相乘               *          \n");
    printf("              *             4:矩陣求逆               *          \n");
	printf("              *             5:矩陣轉置               *          \n");
    printf("              *             6:行列式值               *          \n");
	printf("              *             7:選擇退出               *          \n");
	printf("              *                                      *          \n");
    printf("              ****************************************          \n");
    printf("                        請輸入序號進行操做  :)                 \n");
    printf("                                 ");n=getchar();
	 
    return n;
}

void zhuanzhi(TSMatrix A)   /*轉置運算*/
{
	int p,q,m;
	TSMatrix B;
	B.mu=A.nu; /*將原矩陣的行列數及非零元個數賦給新矩陣*/
	B.nu=A.mu;
	B.tu=A.tu;
	if(B.tu)
	{
		m=1;
		for(p=1;p<=A.mu;p++)              /*將原非零元三元組的行列值交換後賦給新三元組,獲得轉置矩陣*/
			for(q=1;q<=A.nu;q++)
			{
				B.data[m].i=A.data[m].j;
				B.data[m].j=A.data[m].i;
				B.data[m].v=A.data[m].v;
				++m;
			}
	}
	print(B);
}

int JsMatrix(int s[][MAXMU],int n) /*經過遞歸求矩陣對應行列式的值*/   
{
	int z,j,k,r,total=0;
	int b[MAXMU][MAXMU];
	if(n>2)
	{
		for(z=0;z<n;z++)
			{for(j=0;j<n-1;j++)
				for(k=0;k<n-1;k++)
					if(k>=z) b[j][k]=s[j+1][k+1];
					else b[j][k]=s[j+1][k];
					if(z%2==0) r=s[0][z]*JsMatrix(b,n-1);
					else r=(-1)*s[0][z]*JsMatrix(b,n-1);
			total=total+r;
			}
	}
	else if(n==2) total=s[0][0]*s[1][1]-s[0][1]*s[1][0];
	return total;
}

void yuzishi(int s[][MAXMU],int b[][MAXMU],int n) /*求矩陣每一個元素對應的餘子式*/
{
	int z,j,k,m,l,g,a[MAXMU][MAXMU];
	for(z=0;z<n;z++)
	{
		l=z;
		for(j=0;j<n;j++)
		{	
			m=j;
			for(k=0;k<n-1;k++)
				for(g=0;g<n-1;g++)
				{
					if(g>=m&&k<l) a[k][g]=s[k][g+1];
					else if(k>=l&&g<m)  a[k][g]=s[k+1][g];
				    else if(k>=l&&g>=m) a[k][g]=s[k+1][g+1];
				    else   a[k][g]=s[k][g];
				}	
			b[z][j]=JsMatrix(a,n-1);/*調用求行列式函數求出餘子式*/
		}
	}
}

void qiuni(TSMatrix TM)   /*求逆運算*/
{
	system("color 4f");
	int i,j,n,k;
	n=TM.mu;
	float temp;
	int a[MAXMU][MAXMU];
	int b[MAXMU][MAXMU];
	float c[MAXMU][MAXMU];
	for(i=0;i<n;i++)
		for(j=0;j<n;j++)
			a[i][j]=0;
	for(i=1;i<=TM.tu;i++)
		a[TM.data[i].i-1][TM.data[i].j-1]=TM.data[i].v;
	k=JsMatrix(a,n); /*調用求行列式值的函數求出行列式的值*/
	printf(" 矩陣的行列式的值爲:|A|=%d\n",k);
	if(k==0)
		printf(" 行列式的值|A|=0,原矩陣無逆矩陣!");
	else
	{
		yuzishi(a,b,n);

		for(i=0;i<n;i++) /*由余子式獲得代數餘子式*/
			for(j=0;j<n;j++)
				if((i+j)%2!=0 && b[i][j]!=0) 
					b[i][j]=-b[i][j];

		for(i=0;i<n;i++) /*將代數餘子式矩陣轉置獲得伴隨矩陣*/
			for(j=i+1;j<n;j++)
			{
				temp=b[i][j];
				b[i][j]=b[j][i];
				b[j][i]=temp;
			}

		printf(" 伴隨矩陣A*爲:\n");
		for(i=0;i<n;i++) /*輸出伴隨矩陣*/
		{
			printf("\n");
			for(j=0;j<n;j++)
				printf("%6d",b[i][j]);
			printf("\n");
		}
		for(i=0;i<n;i++)/*伴隨矩陣除以行列式的值獲得逆矩陣*/
			for(j=0;j<n;j++)
				c[i][j]=(float)b[i][j]/k;
		printf(" 逆矩陣(A*)/|A|爲:\n"); 
		for(i=0;i<n;i++)/*輸出逆矩陣*/
		{
			printf("\n");
				for(j=0;j<n;j++)
					printf("%1.1f\t",c[i][j]);		    
			printf("\n");
		}
	}
}
void hlsz(TSMatrix TM)   /*求逆運算*/
{
	system("color 4f");
	int i,j,n,k;
	n=TM.mu;
	float temp;
	int a[MAXMU][MAXMU];
	int b[MAXMU][MAXMU];
	float c[MAXMU][MAXMU];
	for(i=0;i<n;i++)
		for(j=0;j<n;j++)
			a[i][j]=0;
	for(i=1;i<=TM.tu;i++)
		a[TM.data[i].i-1][TM.data[i].j-1]=TM.data[i].v;
	k=JsMatrix(a,n); /*調用求行列式值的函數求出行列式的值*/
	printf("該稀疏矩陣對應行列式的值爲%d",k);
}
void main() /*功能主函數*/
{ 
	TSMatrix A,B,C;

	 for(;;)
		 switch(menu())
	 {case '1':creat(&A);
               creat(&B);
			   add(A,B);
			   getch();
			   break;
      case '2':creat(&A);
               creat(&B);
			   sub(A,B);
			   getch();
			   break;
      case '3':creat(&A);
               creat(&B);
			   mult(A,B,&C);
			   getch();
			   break;
	  case '4':creat(&A);
		       qiuni(A);
			   getch();
			   break;
	  case '5':creat(&A);
		       zhuanzhi(A);
			   getch();
			   break;
	  case '6':creat(&A);
		       hlsz(A);
			   getch();
			   break;
      case '7':system("cls");
			  system("color f2");
			  printf("計算器已關閉,按任意鍵退出 :)\n");
			  exit(0);
	 }
}
相關文章
相關標籤/搜索