十字链表实现稀疏矩阵,包含十二大功能


题目:

  1. 十字链表实现稀疏矩阵

1.问题描述

用十字链表存储和表示稀疏矩阵,并实现如下功能

2.基本要求

  1. 初始化:创建十字链表并从文件中读取稀疏矩阵数据(文件数据可以是三元组结构);
  2. 在十字链表上设置坐标为(i,j)的位置值为value;
  3. 获取坐标为(i,j)的位置的值;
  4. 插入一项、删除某项的值;
  5. 输出十字链表表示的稀疏矩阵;
  6. 实现两个稀疏矩阵的加法、减法、乘法的功能,结果保存到新的十字链表中;
  7. 实现把十字链表表示的稀疏矩阵存入文件;
  8. 可以用菜单选择所有功能,设计良好的操作界面;
  9. 在需求分析阶段完成未尽功能需求,适当扩充功能(例如矩阵转置、求最值等)。

实现:

技术难点1:uthash存储十字链表矩阵,给每个矩阵进行命名,以名字作为key,十字链表作为value,实现相对自动化的功能;(需要自己在github上找到相关资源)

技术难点2:十字链表矩阵的插入函数是整个代码的核心,需要对十字链表的存储结构比较熟悉

技术难点3:十字链表矩阵的相加函数,针对两个矩阵不同对应的情况进行相加

代码前面的声明:

 

#include
#include
#include
#include"uthash.h" 
using namespace std;

/*                 稀疏矩阵的十字链表存储                                       */

typedef struct OLNode
{
    int row;                                                    			//非零元素的行下标
    int col;    															//非零元素的列下标
    int elem;    															//非零元素值
    struct OLNode *right;   												//右节点
    struct OLNode *down;   												    //下节点

}OLNode, *OLink;

typedef struct 
{
    OLink *rhead;   														//行指针链表
    OLink *chead;   														//列指针链表
    int rowSum;     														//矩阵的行数
    int ColSum;     														//矩阵的列数
    int NumSum;     														//矩阵的非零元素个数
}CrossList; 


/*                 uthash哈希表的结构体声明                                      */

struct HashCross{															//哈希表
    char name[10];															//矩阵名称  key
    CrossList crosslist;													//十字链表结构体  value
    UT_hash_handle hh;												
}HashCross;

/*                          全局hash表,存储矩阵                                */

struct HashCross *cross = NULL;											
 
/*   ************************************************************************** */

/*                          函数声明                                            */


void menu();						                    					//主菜单
void menu1(); 						               							//初始化部分
void menu2();						                						//基础操作部分
void menu3();  						                						//进阶操作部分   
void InitSMatrix(CrossList &M);				  								//初始化矩阵
void CreateMatrix(CrossList &M);											//创建矩阵	
void PrintSMatrix(CrossList M);												//输出矩阵
void InsertElem(OLink &newnode,CrossList &M);								//插入元素到矩阵M中
void changeValue(CrossList &M);												//寻找矩阵M中的某个值
void findValue(CrossList &M);												//查找矩阵中的某个值
void deleteValue(CrossList &M);												//删除矩阵中的某个值
void AddMatrix(CrossList &M,CrossList &N,CrossList &out);					//两个矩阵的相加
void SubtractMatrix(CrossList &M,CrossList &N,CrossList &out);				//两个矩阵的相减
void MultiplyMatrix(CrossList &M,CrossList &N,CrossList &out);				//两个矩阵的相乘
void TransposeSMatrix(CrossList &M, CrossList &out);						//矩阵的转置 
void findMaxOrMin(CrossList &M);										    //矩阵求最值 
void CopySMatrix(CrossList &M, CrossList &out);								//复制矩阵 
void ReadFromFile(CrossList &M);											//从文件中读取矩阵 
void WriteToFile(CrossList &M);												//把矩阵写入文件 
CrossList HashFind(char *name);												//哈希查找函数(没有该矩阵,手动创建)
CrossList HashFind2( char *name);											//哈希查找函数(没有该矩阵,文件读取创建)
CrossList getCrossList();													//控制台获取矩阵名称(没有该矩阵,手动创建)



/*   ************************************************************************** */

具体每个功能的函数:

/*                        实现功能的函数                                        */



/*                        1. 主菜单                                             */
void menu()    
{
    int c=0;
	printf("--------------------------------------------------------------------------------\n");
	printf("******************<-----欢迎使用十字链表存储的稀疏矩阵进行操作----->*****************\n\n");
	printf("\t\t\t     1.*--<矩阵初始化>--*\n\n");
	printf("\t\t\t     2.*--<矩阵基本操作(插入、删除、查找)>--*\n\n");
	printf("\t\t\t     3.*--<矩阵进阶操作(四则运算、求逆、求转置、求最值等)>--*\n\n");
	printf("\t\t\t     4.*--<退出本程序>--*\n\n");
	printf("\n\n********************************************************************************\n");
	printf("--------------------------------------------------------------------------------\n");
	printf("*请输入相应功能的编号:");
	do
	{
		cin >> c;
		if(c<1||c>4)
			printf("*无该选项!请重新输入:");
	}while(c<1||c>4);
     switch(c)
     {
    	case 1:menu1();break;
	    case 2:menu2();break;
	   	case 3:menu3();break;
    	case 4:exit(0);break;
      }
}

/*   ************************************************************************** */

/*                        2.初始化菜单                                          */ 

void menu1()   
{
	int c=0;
	while(c != 1){
		printf("--------------------------------------------------------------------------------\n");
		printf("******************<-----欢迎来到矩阵初始化菜单----->*****************\n\n");
		printf("\t\t\t     1.*--<返回主菜单>--*\n\n");
		printf("\t\t\t     2.*--<手动输入矩阵>--*\n\n");
		printf("\t\t\t     3.*--<从文件中读取矩阵>--*\n\n");
		printf("\t\t\t     4.*--<退出本程序>--*\n\n");
		printf("\n\n********************************************************************************\n");
		printf("--------------------------------------------------------------------------------\n");
		printf("*请输入相应功能的编号:");
		do
		{
			cin >> c;
			if(c<1||c>4)
				printf("*无该选项!请重新输入:");
		}while(c<1||c>4);
	     switch(c)
	     {
	    	case 1:
				menu();
				break;
		    case 2:{
                getCrossList();
				break;
			}

	    	case 3:{
	    		CrossList M;
		    	printf("请输入需要操作的矩阵名称:(长度小于10)\n");
	            char name[10];
	            cin >> name;
				M = HashFind2(name); 
				break;
			}
	    	case 4:exit(0);
				break;
	      }
	  }
}

/*   ************************************************************************** */

/*                        3.  矩阵基本操作菜单                                  */

void menu2()     
{   
	int c=0;
    while(c != 1){
		printf("--------------------------------------------------------------------------------\n");
		printf("******************<-----欢迎来到矩阵基本操作菜单----->*****************\n\n");
		printf("\t\t\t     1.*--<返回主菜单>--*\n\n");
		printf("\t\t\t     2.*--<查看矩阵下标的值>--*\n\n");
		printf("\t\t\t     3.*--<删除矩阵下标的值>--*\n\n");
		printf("\t\t\t     4.*--<增加矩阵下标的值>--*\n\n");
		printf("\t\t\t     5.*--<退出本程序>--*\n\n");
		printf("\n\n********************************************************************************\n");
		printf("--------------------------------------------------------------------------------\n");
		printf("*请输入相应功能的编号:");
		do
		{
			cin >> c;
			if(c<1||c>5)
				printf("*无该选项!请重新输入:");
		}while(c<1||c>5);
	     switch(c)
	     {
	    	case 1:menu();break;
		    case 2:{
		    	CrossList M;
		    	M = getCrossList(); 
				findValue(M);
				break;
			}

	    	case 3:{
	    		CrossList M;
	    		M = getCrossList();
				deleteValue(M);
				break;
			}

	    	case 4:{
	    		CrossList M;
	    		M = getCrossList();
				changeValue(M);
				break;
			}		

	    	case 5:exit(0);break;
	      }
	}
}

/*   ************************************************************************** */

/*                        4.  矩阵进阶操作菜单                                  */

void menu3()     
{
    int c=0;
    while(c != 1){
		printf("--------------------------------------------------------------------------------\n");
		printf("******************<-----欢迎来到矩阵进阶操作菜单----->*****************\n\n");
		printf("\t\t\t     1.*--<返回主菜单>--*\n\n");
		printf("\t\t\t     2.*--<求稀疏矩阵的加法>--*\n\n");
		printf("\t\t\t     3.*--<求稀疏矩阵的减法>--*\n\n");
		printf("\t\t\t     4.*--<求稀疏矩阵的乘法>--*\n\n");
		printf("\t\t\t     5.*--<求稀疏矩阵的转置>--*\n\n");
		printf("\t\t\t     6.*--<输出稀疏矩阵>--*\n\n");
		printf("\t\t\t     7.*--<求稀疏矩阵的最值>--*\n\n");
		printf("\t\t\t     8.*--<将稀疏矩阵存入文件>--*\n\n");
		printf("\t\t\t     9.*--<退出本程序>--*\n\n");
		printf("\n\n********************************************************************************\n");
		printf("--------------------------------------------------------------------------------\n");
		printf("*请输入相应功能的编号:");
		do
		{
			cin >> c;
			if(c<1||c>9)
				printf("无该选项!请重新输入:");
		}while(c<1||c>9);
	     switch(c)
	     {
	    	case 1:
				menu(); break;
		    case 2:{
		    	CrossList M,N,out;
	    		M = getCrossList();
	    		N = getCrossList();
				AddMatrix(M,N,out);
				break;
			}
				
	    	case 3:{
	    		CrossList M,N,out;
	    		M = getCrossList();
	    		N = getCrossList();
				SubtractMatrix(M,N,out);
				break;
			}
				
	    	case 4:{
	    		CrossList M,N,out;
	    		M = getCrossList();
	    		N = getCrossList();
				MultiplyMatrix(M,N,out);
				break;
			}
				
	    	case 5:{
	    		CrossList M,out;
	    		M = getCrossList();
				TransposeSMatrix(M,out);
				break;
			}
				
	    	case 6:{
	    		CrossList M;
	    		M = getCrossList();
	    		PrintSMatrix(M);	
				break;
				} 
				
	    	case 7:{
	    		CrossList M;
	    		M = getCrossList();
				findMaxOrMin(M);
				break;
				}
	    	case 8:{
				CrossList M;
	    		M = getCrossList();
	    		WriteToFile(M);
				break;
			} 
	    	case 9:exit(0);break;
	      }
	  }
}
/*   ************************************************************************** */


/*                        5.  初始化稀疏矩阵                                    */

void InitSMatrix(CrossList &M){
    M.rhead = (OLink *)malloc((M.rowSum+1)*sizeof(OLink));
    M.chead = (OLink *)malloc((M.ColSum+1)*sizeof(OLink));
    
    //将所有结点赋为空值
    for(int i = 1; i<=M.rowSum; i++)
    {
        M.rhead[i]=NULL;
    }
    for(int i = 1; i <= M.ColSum; i++)
    {
        M.chead[i]=NULL;
    }
}

/*   ************************************************************************** */


/*                        6.  创建稀疏矩阵                                      */
void CreateMatrix(CrossList &M){
    int rowSum,ColSum,NumSum;
    int row, col, elem;
    cout << "请输入创建的稀疏矩阵的行数、列数、非0元素个数:\n" << endl;
	cin >> rowSum >> ColSum >> NumSum;
    M.rowSum = rowSum;
    M.ColSum = ColSum;
    M.NumSum = NumSum;
    //初始化矩阵
    InitSMatrix(M);
    //对矩阵进行赋值
    cout << "请按任意次序输入" << M.NumSum <<"个非零元的行 列 元素值:" << endl;

    for(int i = 1; i <= NumSum; i++){
    	cin >> row; 
		cin >> col;
		cin >> elem;
        OLink newNode = (OLink)malloc(sizeof(OLNode));
        newNode -> row = row;
        newNode -> col = col;
        newNode -> elem = elem;
        InsertElem(newNode,M);
    }
    cout << "创建成功!创建的矩阵为:\n" << endl;
//    printf("创建成功!创建的矩阵为:\n");
    PrintSMatrix(M); 
    
}

/*   ************************************************************************** */

/*                        7.  插入结点值                                        */

void InsertElem(OLink &newnode, CrossList &M){
    //将非零元素结点插入矩阵中
    OLink rowNode = M.rhead[newnode->row];
    //行的插入
    if (rowNode == NULL || rowNode -> col > newnode -> col) // 插在该行的第一个结点处 
		{
			newnode->right = rowNode;
			M.rhead[newnode->row] = newnode;
		}
	else 
		{
            //寻找插的位置的前一个结点
			for (; !(rowNode->col < newnode->col && (rowNode->right == NULL||rowNode -> right -> col > newnode->col)); rowNode = rowNode->right);
			newnode->right = rowNode->right; //完成行插入 
			rowNode->right = newnode;
		}

    //列的插入
    OLink colNode = M.chead[newnode -> col];
    if (colNode == NULL || colNode -> row > newnode -> row) // 插在该行的第一个结点处 
		{
			newnode->down = colNode;
			M.chead[newnode->col] = newnode;
		}
	else 
		{
            //寻找插的位置的前一个结点
			for (; !(colNode -> row < newnode->row && (colNode -> down == NULL || colNode -> down -> row > newnode->row)); colNode = colNode->down);
			newnode->down = colNode->down; //完成列插入 
			colNode->down = newnode;
		}
}

/*   ************************************************************************** */

/*                        8.  输出矩阵                                          */

void PrintSMatrix(CrossList M){
    //初始条件: 稀疏矩阵M存在
    int i, j;
	for (i = 1; i <= M.rowSum; i++)
	{ // 从第1行到最后1行
		OLink p = M.rhead[i]; // p指向该行的第1个非零元素
		for (j = 1; j <= M.ColSum; j++) // 从第1列到最后1列
			if (!p || p->col != j) // 已到该行表尾或当前结点的列值不等于当前列值
				printf("%-5d", 0); // 输出0
			else
			{
				printf("%-5d", p->elem);
				p = p->right;
			}
		printf("\n");
	}
}

/*   ************************************************************************** */

/*                        9. 修改矩阵中某个元素的值(如果没有就增加)            */

void changeValue(CrossList &M){
	//如果不存在对应下标的值,则直接插入新的值
	int row;
	int col;
	int elem;
	cout << "请输入需要修改的矩阵的行 列 元素值:\n" << endl;
	cin >> row >> col >> elem;
	OLink rowNode = M.rhead[row];
	OLink newnode = (OLink)malloc(sizeof(OLNode));
    newnode->row = row;
    newnode->col = col;
    newnode->elem = elem;

	if(rowNode == NULL || rowNode -> col > col){
		//如果行链表的头结点为空或者是当前修改的结点的列值大于头结点的列值,直接插入
		cout << "插入新值!\n" << endl;
//		printf("插入新值!\n");
		InsertElem(newnode,M);
	}
	else{
		OLink nextNode = rowNode;
		//头结点不为空,进行判断
		while(nextNode){
			if(nextNode -> col == col){
				nextNode -> elem = elem;
				cout << "修改成功!\n" << endl;
//				printf("修改成功!\n");
				break;
			}
			else if(nextNode -> col > col){
				cout << "插入新值!\n" << endl;
//				printf("插入新值!\n");
				InsertElem(newnode,M);
				break;
			}
			else{
				nextNode = nextNode -> right;
			}
		}
		//头结点为空时,直接插入
		if(nextNode == NULL){
			cout << "插入新值!\n" << endl;
//			printf("插入新值!\n");
			InsertElem(newnode,M);
		}
	}
	cout << "修改后的矩阵为:\n" << endl;
//	printf("修改后的矩阵为:\n");
	PrintSMatrix(M);
}

/*   ************************************************************************** */

/*                        10. 查找矩阵中某个元素的值                            */

void findValue(CrossList &M){
	int row;
	int col;
	cout << "请输入需要查找的矩阵的对应的行 列 下标值(如:10 10):\n" << endl;
    cin >> row >> col;
	OLink rowNode = M.rhead[row];
	if(rowNode == NULL || rowNode -> col > col){
		//如果行链表的头结点为空或者是当前修改的结点的列值大于头结点的列值,该元素的值为0
		cout << "下标为:(" << row << "," << col << ")值elem = 0\n" << endl;
	}
	else{
		OLink nextNode = rowNode;
		//头结点不为空,进行判断
		while(nextNode){
			if(nextNode -> col == col){
				int val = nextNode -> elem;
				cout << "下标为:(" << row << "," << col << ")值elem =" << val << endl;
				break;
			}
			else if(nextNode -> col > col){
				cout << "下标为:(" << row << "," << col << ")值elem = 0\n" << endl;
				break;
			}
			else{
				nextNode = nextNode -> right;
			}
		}
		//头结点为空时,值为0 
		if(nextNode == NULL){
			cout << "下标为:(" << row << "," << col << ")值elem = 0\n" << endl;
		}
	}

}

/*   ************************************************************************** */

/*                        11. 删除矩阵中某个元素的值                            */

void deleteValue(CrossList &M){
	int row;
	int col;
	cout << "请输入1需要删除的矩阵的对应的行 列 的下标值(如:10 10):\n" << endl;
	scanf("%d %d", &row, &col);

	//行指针的删除
	OLink rowNode = M.rhead[row];
	if(rowNode == NULL || rowNode -> col > col){
		//如果行链表的头结点为空或者是当前的结点的列值大于头结点的列值,该元素的值为0
		cout << "该下标对应的值为0,无需删除\n" << endl;
		return;
	}
	else{
		OLink p = NULL, q = NULL;
		p = rowNode;
		while(rowNode){
			if(rowNode -> col == col){
				if(p == rowNode){
					M.rhead[row] = p -> right;
				}
				else{
					q ->right = p -> right;
				}
				break;
			}
			else if(rowNode -> col > col){
				return;
			}
			else{
				q = p;
				p = p -> right;
			}
		}
	}

	//列指针的删除
	OLink ColNode = M.chead[col];
	if(ColNode == NULL || ColNode -> row > row){
		cout << "该下标对应的值为0,无需删除\n" << endl;
		return;
	}
	else{
		OLink p = NULL, q = NULL;
		p = ColNode;
		while(ColNode){
			if(ColNode -> col == col){
				if(p == ColNode){
					M.chead[col] = p -> down;
				}
				else{
					q -> down = p -> down;
				}
				break;
			}
			else if(ColNode -> row > row){
				return;
			}
			else{
				q = p;
				p = p -> down;
			}
		}
	}
	cout << "删除成功!\n" << endl;
	cout << "删除后的矩阵为:\n" << endl;
	PrintSMatrix(M);
}

/*   *************************************************************************  */

/*                        12. 两个矩阵相加                                      */

void AddMatrix(CrossList &M,CrossList &N, CrossList &out){

	//判断矩阵是否满足相加条件
	if(M.ColSum != N.ColSum || M.rowSum != N.rowSum){
		cout << "两个矩阵不是同类型的,不能相加\n" << endl;
		return;
	}

	//对out矩阵进行初始化
	out.ColSum = M.ColSum;
	out.rowSum = M.rowSum;
	out.NumSum = 0;
	InitSMatrix(out);

	//进行相加
	for(int row = 1; row <= M.rowSum; row++){
		OLink Node1 = M.rhead[row];
		OLink Node2 = N.rhead[row];
		for(int col = 1; col <= M.ColSum; col++){
			//M,N在相同位置都有值
			if(Node1 && Node1 -> col == col && Node2 && Node2 -> col == col){
//               //中间变量保存
//				OLink Node3 = Node1;
//				OLink temp = Node1 -> right;
//				int tmp = Node1 -> elem;
//
//                //插入
//				Node3 -> elem = Node1-> elem + Node2 -> elem;
//				InsertElem(Node3, out);
//				out.NumSum++;
//
//                //移动指针
//                Node1->elem = tmp;
//                Node1 = temp;
//				Node2 = Node2 -> right;

				//赋值
				OLink Node3 = (OLink)malloc(sizeof(OLNode));
				Node3 -> elem = Node1-> elem + Node2 -> elem;
				Node3 -> row = Node1 -> row;
				Node3 -> col = Node1 -> col;
				cout << Node1 -> elem;
				cout << Node2 -> elem;
				cout <<  Node3 -> elem  <<  Node3 -> row  << Node3 -> col << endl;

				//插入 
				InsertElem(Node3, out);
				out.NumSum++;
				
				//移动指针 
                Node1 = Node1 -> right;
				Node2 = Node2 -> right;
			}
			//M位置没有值,N位置有值
			if((Node1==NULL||Node1->col!=col)&& Node2 && Node2->col == col)
            {
//            	//中间变量保存
//				OLink Node3 = Node2;
//				OLink temp = Node2 -> right;
//
//                //插入
//				InsertElem(Node3, out);
//				out.NumSum++;
//
//                //移动指针
//                Node2 = temp;
				
				//赋值 
				OLink Node3 = (OLink)malloc(sizeof(OLNode));
				Node3 -> elem = Node2 -> elem;
				Node3 -> row = Node2 -> row;
				Node3 -> col = Node2 -> col;
				
				//插入 
				InsertElem(Node3,out);
                out.NumSum++;
                
                //移动指针 
                Node2 = Node2->right;
            }
			//M位置有值,N位置没有值
		   if(Node1 && Node1->col == col && (Node2 == NULL||Node2 ->col != col))
            {
//            	//中间变量保存
//            	OLink Node3 = Node1;
//            	OLink temp = Node1 -> right;
//            	
//            	//插入
//				InsertElem(Node3, out);
//				out.NumSum++;
//				
//				//移动指针
//                Node1 = temp;

			
				//赋值 
				OLink Node3 = (OLink)malloc(sizeof(OLNode));
				Node3 -> elem = Node1 -> elem;
				Node3 -> row = Node1 -> row;
				Node3 -> col = Node1 -> col;
				
				//插入 
				InsertElem(Node3,out);
                out.NumSum++;
                
                //移动指针 
                Node1 = Node1->right;
            }
		}
	}
	cout << "相加后的矩阵为:\n" << endl;
	PrintSMatrix(out);
}

/*   *************************************************************************  */

/*                        13. 两个矩阵相减                                      */

void SubtractMatrix(CrossList&M,CrossList &N, CrossList &out){

	//判断矩阵是否满足相减 条件
	if(M.ColSum != N.ColSum || M.rowSum != N.rowSum){
		cout << "两个矩阵不是同类型的,不能相减 \n" << endl;
		return;
	}

	//对out矩阵进行初始化
	out.ColSum = M.ColSum;
	out.rowSum = M.rowSum;
	out.NumSum = 0;
	InitSMatrix(out);

	//进行相减 
	for(int row = 1; row <= M.rowSum; row++){
		OLink Node1 = M.rhead[row];
		OLink Node2 = N.rhead[row];
		for(int col = 1; col <= M.ColSum; col++){
			//M,N在相同位置都有值
			if(Node1 && Node1 -> col == col && Node2 && Node2 -> col == col){
//				//中间变量保存
//				OLink Node3 = Node1;
//				OLink temp = Node1 -> right;
//
//                //插入
//				Node3 -> elem = Node1-> elem - Node2 -> elem;
//				InsertElem(Node3, out);
//				out.NumSum++;
//
//                //移动指针
//                Node1 = temp;
//				Node2 = Node2 -> right;


				//赋值
				OLink Node3 = (OLink)malloc(sizeof(OLNode));
				Node3 -> elem = Node1-> elem - Node2 -> elem;
				Node3 -> row = Node1 -> row;
				Node3 -> col = Node1 -> col;

				//插入 
				InsertElem(Node3, out);
				out.NumSum++;
				
				//移动指针 
                Node1=Node1->right;
				Node2 = Node2 -> right;
			}
			//M位置没有值,N位置有值
			if((Node1 == NULL || Node1 -> col != col) && Node2 && Node2 -> col == col)
            {
//            	//中间变量保存
//				OLink Node3 = Node2;
//				OLink temp = Node2 -> right;
//
//                //插入
//				Node3 -> elem = - Node2-> elem;
//				InsertElem(Node3, out);
//				out.NumSum++;
//
//                //移动指针
//                Node2 = temp;

				//赋值 
				OLink Node3 = (OLink)malloc(sizeof(OLNode));
				Node3 -> elem = - Node2 -> elem;
				Node3 -> row = Node2 -> row;
				Node3 -> col = Node2 -> col;
				
				//插入 
				InsertElem(Node3,out);
                out.NumSum++;
                
                //移动指针 
                Node2 = Node2->right;
            }
			//M位置有值,N位置没有值
		   if(Node1 && Node1 -> col == col && (Node2 == NULL || Node2 -> col != col))
            {
//            	//中间变量保存
//            	OLink Node3 = Node1;
//            	OLink temp = Node1 -> right;
//            	
//            	//插入
//				InsertElem(Node3, out);
//				out.NumSum++;
//				
//				//移动指针
//                Node1 = temp;

				//赋值 
				OLink Node3 = (OLink)malloc(sizeof(OLNode));
				Node3 -> elem = Node1 -> elem;
				Node3 -> row = Node1 -> row;
				Node3 -> col = Node1 -> col;
				
				//插入 
				InsertElem(Node3,out);
                out.NumSum++;
                
                //移动指针 
                Node1 = Node1->right;
            }
		}
	}
	cout << "相减后的矩阵为:\n" << endl;
	PrintSMatrix(out);
}

/*   *************************************************************************  */
 
/*                        14. 两个矩阵相乘                                      */

void MultiplyMatrix(CrossList &M,CrossList &N, CrossList &out){

	//判断矩阵是否满足相乘条件
	if(M.ColSum != N.rowSum){
		cout << "两个矩阵不满足相乘条件 \n" << endl;
		return;
	}
	//对out矩阵进行初始化
	out.rowSum = M.rowSum;
	out.ColSum = N.ColSum;
	out.NumSum = 0;
	InitSMatrix(out);

	//进行相乘

	//行列遍历
	for(int row = 1; row <= out.rowSum; row++){
		for(int col = 1; col <= out.ColSum; col++){
			int elem = 0;
			OLink Node1 = M.rhead[row];
			OLink Node2 = N.chead[col];

			//对M的行,N的列进行遍历
			for(; Node1; Node1 = Node1 -> right){
				for(; Node2 && Node2 -> row <= Node1 -> col; Node2 = Node2 -> down){ 
					if(Node2 -> row == Node1 -> col){//执行相乘
						elem = elem + Node1-> elem * Node2 -> elem;
						break;
					}
				}
			}

			//满足条件插入矩阵
			if(elem){
				out.NumSum++;
                OLink newnode = (OLink)malloc(sizeof(OLNode));
                newnode -> row = row;
                newnode -> col = col;
                newnode -> elem = elem;
                InsertElem(newnode, out);
			}
		}
	}
	cout << "相乘后的矩阵为:\n" << endl;
	PrintSMatrix(out);
}

/*   *************************************************************************  */

/*                        15. 矩阵转置                                   	    */

void TransposeSMatrix(CrossList &M, CrossList &out){

	//out对M进行复制一份
	CopySMatrix(M, out);

	//进行转置
	for(int row = 1; row <= out.rowSum; row++){
		OLink rowNode = out.rhead[row];
		while(rowNode){
			//当结点不为空时,进行指针和下标的交换
			OLink nextRightNode = rowNode -> right;
			
				//下标更换
			int row = rowNode -> row;
			rowNode -> row = rowNode -> col;
			rowNode -> col = row;
				//指针交换
			OLink down = rowNode -> down;
			rowNode -> down = rowNode -> right;
			rowNode -> right = down;
				//对下一个进行判断
			rowNode = nextRightNode;
		}
	}

	//进行转置后的交换
	int rowSum = out.rowSum;
	int ColSum = out.ColSum;
	OLink* rhead = out.rhead;
	out.ColSum = rowSum;
	out.rowSum = ColSum;
	out.rhead = out.chead;
	out.chead = rhead;
    cout << "转置后的矩阵为:\n" << endl;
	PrintSMatrix(out);
	
}

/*   *************************************************************************  */

/*                        16. 矩阵求最值                                    	*/

void findMaxOrMin(CrossList &M){
	int min = INT_MAX;
	int max = INT_MIN;

	//矩阵最大值
    for(int i = 1; i <= M.rowSum; i++){
        OLink p = M.rhead[i];
        while(p != NULL){
            if(max < p -> elem)
             max = p -> elem;
            p = p -> right;
        }
    }
	
	//矩阵最小值
	for(int i = 1; i <= M.rowSum; i++){
        OLink p = M.rhead[i];
        while(p != NULL){
            if(min > p -> elem)
             min = p -> elem;
            p = p -> right;
        }
    }
    cout << "矩阵的最大值为: \n" <<  max << endl;
    cout << "矩阵的最小值为: \n" << min << endl;
}

/*   *************************************************************************  */

/*                        17. 复制矩阵                                          */

void CopySMatrix(CrossList &M, CrossList &out){

	//对out进行初始化
	out.NumSum = M.NumSum;
	out.ColSum = M.ColSum;
	out.rowSum = M.rowSum;
	InitSMatrix(out);
	
	//复制
	for (int row = 1; row <= M.rowSum; row++) 
	{
		OLink rowNode = M.rhead[row];
		while(rowNode)
		{
			OLink newnode = (OLink)malloc(sizeof(OLNode));
			newnode -> row = rowNode -> row;
			newnode -> col = rowNode -> col;
			newnode -> elem = rowNode -> elem;
			InsertElem(newnode, out);
			rowNode = rowNode -> right;
		}
	}
	// printf("复制得到的矩阵为:\n");
	// PrintSMatrix(out);
}

/*   *************************************************************************  */

/*                        18. 从文件中读取                                      */

void ReadFromFile(CrossList &M){
	FILE* fpread;
	char str[100];
	int count=0;
	int num[1000];
	cout << "请输入文件名称:\n" << endl;
	cin >> str;
	fpread = fopen(str, "r");
	if (fpread == NULL)
	{
		cout << "不存在该文件!\n" << endl;
		return ;
	}

	//读取数据
	while(1) { 
		int ch = fgetc(fpread);
		if(ch == EOF)
		 break;
		else
		 fscanf(fpread, "%d", &num[count++]);
	}
	fclose(fpread);

	//初始化矩阵并输出
	M.rowSum = num[0];
	M.ColSum = num[1];
	M.NumSum = num[2];
	InitSMatrix(M);
	cout << num[0] << M.ColSum << M.NumSum << endl;
	for(int i = 3; i < count; i+=3){
		OLink newNode = (OLink)malloc(sizeof(OLNode));
        newNode -> row = num[i];
        newNode -> col = num[i+1];
        newNode -> elem = num[i+2];
        InsertElem(newNode,M);
	}

	//显示矩阵
	cout << "文件中读取的矩阵为:\n" << endl;
	PrintSMatrix(M);
}

/*   *************************************************************************  */

/*                        19. 把矩阵写入文件                                    */

void WriteToFile(CrossList &M){
    char str[1024];
    cout << "请输入需要保存到的文件名:\n" << endl;
	cin >> str;
    FILE* fid = fopen(str, "wt");
	if (fid == NULL)
	{
		cout << "文件不存在!\n" << endl;
		return;
	}

	//写入文件
    fprintf(fid," ");
    fprintf(fid,"%d ",M.rowSum);
    fprintf(fid,"%d ",M.ColSum);
    fprintf(fid,"%d\n",M.NumSum);

    for(int i = 1; i <= M.rowSum; i++){
        OLink Node = M.rhead[i];
        while(Node != NULL){
            fprintf(fid,"%d ",Node -> row);
            fprintf(fid,"%d ",Node -> col);
            fprintf(fid,"%d\n",Node -> elem);
            Node =  Node -> right;
        }
    }
    fclose(fid);
    cout << "文件写入成功!\n" << endl;
}

/*   *************************************************************************  */

/*                        20. 哈希查找函数(用于手动写入矩阵)                    */

CrossList HashFind(char name[10]){
    struct HashCross *tmp = NULL;
    HASH_FIND_STR(cross,name,tmp);
    if(tmp == NULL){
        cout << "该矩阵不存在,系统已经自动为您生成该名称的矩阵\n" << endl;
        CrossList M;
        tmp = (struct HashCross *)malloc(sizeof(struct HashCross));
        strcpy(tmp -> name, name);
        CreateMatrix(M);
        tmp -> crosslist = M;
        HASH_ADD_STR(cross,name,tmp);
        if(cross == NULL) cout << "hash还是空" << endl; 
        return M;
    }
    else{
        cout << "该矩阵存在!\n" << endl;
        return tmp -> crosslist;
    }
}

/*   *************************************************************************  */

/*                        21. 哈希查找函数(用于读文件写入矩阵)                  */

CrossList HashFind2(char name[10]){
    struct HashCross *tmp = NULL;
    HASH_FIND_STR(cross,name,tmp);
    if(tmp == NULL){
    	cout << "该矩阵不存在,系统已经自动为您生成该名称的矩阵\n" << endl;
        tmp = (struct HashCross *)malloc(sizeof(struct HashCross));
        strcpy(tmp -> name, name);
        CrossList M;
        ReadFromFile(M);
        tmp -> crosslist = M;
        HASH_ADD_STR(cross,name,tmp);
        return M;
    }
    else{
    	cout << "该矩阵存在!\n" << endl;
        return tmp -> crosslist;
    }
}

/*   *************************************************************************  */

/*                        21. 获取矩阵名(没有的话,自动创建矩阵)              */

CrossList getCrossList(){
    CrossList M;
    cout << "请输入需要操作的矩阵名称:(长度小于10)\n" << endl;
    char name[10];
    cin >> name;
    M = HashFind(name);
    return M;
}

/*   *************************************************************************  */

/*                       22.主函数调用                                          */


int main(){
	menu();
    return 0;
}

/*   ************************************************************************** */

你可能感兴趣的:(c语言,数据结构,链表,hash,矩阵)