题目:

  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<iostream>
#include<cstdlib>
#include<iomanip>
#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];                                                         //矩阵名称  keyCrossList crosslist;                                                 //十字链表结构体  valueUT_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); // 输出0else{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){//如果行链表的头结点为空或者是当前修改的结点的列值大于头结点的列值,该元素的值为0cout << "下标为:(" << 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){//如果行链表的头结点为空或者是当前的结点的列值大于头结点的列值,该元素的值为0cout << "该下标对应的值为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;elsefscanf(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;
}/*   ************************************************************************** */

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

  1. 【swjtu】数据结构实验5_基于十字链表的稀疏矩阵转置

    实验内容及要求: 编写程序,从字符文件读入三个正整数m, n, t以及t个三元组(i, j, e)建立稀疏矩阵的十字链表存储结构.其中,m.n分别表示矩阵行数和列数:i,  j为非零元素行号和列号.编 ...

  2. 数据结构 - 十字链表之稀疏矩阵的存储

    当数组中非零元素非常少时,我们可以称之为稀疏矩阵.为了减少空间的浪费,在存储稀疏矩阵的时候,我们对它进行压缩存储,即指存储非零信息. 一.数组的顺序存储 在存储稀疏矩阵的时候,除了存储非零元素的值,还 ...

  3. 多重链表 十字链表存储稀疏矩阵,中缀表达式

    第一个term是说该矩阵有4行5列 7个非零元素 为入口 转载于:https://blog.51cto.com/13930723/2362035

  4. 稀疏矩阵建立十字链表c语言,实验6-稀疏矩阵十字链表的存储.doc

    实验6-稀疏矩阵十字链表的存储.doc -/电子信息学院实验报告书课程名 数据结构 题 目 稀疏矩阵十字链表的存储 实验类别 设计 班 级 BX1001 学 号 24 姓 名 肖望龙 2011年 10 ...

  5. 十字链表 java_十字链表法,十字链表压缩存储稀疏矩阵详解

    对于压缩存储稀疏矩阵,无论是使用三元组顺序表,还是使用行逻辑链接的顺序表,归根结底是使用数组存储稀疏矩阵.介于数组 "不利于插入和删除数据" 的特点,以上两种压缩存储方式都不适合解 ...

  6. 稀疏矩阵的十字链表存储表示和实现(第五章 P104 算法5.4)

    稀疏矩阵的十字链表存储 当矩阵的非零元个数和位置在操作过程中变化较大时,就不宜采用顺序存储结构来表示三元组的线性表.对这种类型的矩阵,采用链式存储结构表示三元组的线性表更为恰当. 在链表中,每个非零元 ...

  7. 十字链表法,十字链表压缩存储稀疏矩阵详解

    对于压缩存储稀疏矩阵,无论是使用三元组顺序表,还是使用行逻辑链接的顺序表,归根结底是使用数组存储稀疏矩阵.介于数组 "不利于插入和删除数据" 的特点,以上两种压缩存储方式都不适合解 ...

  8. c语言建立并存储树,利用十字链表存储树结构(便于同时求出某一点的入度与出度)------C语言实现...

    #include #include #include /* 利用十字链表存储有向图,可用于同时查找某个顶点的出度与入度: */ typedef struct edge {//顶点表 int headv ...

  9. 18、数据结构笔记之十八链表实现稀疏矩阵

    18.数据结构笔记之十八链表实现稀疏矩阵 "必须如蜜蜂一样,采过许多花,才能酿出蜜来." 上篇中实现了栈在多项式实现中的例子,再来看下稀疏矩阵通过链表方式实现. 关键字:十字链表存 ...

  10. 特殊矩阵的压缩存储(详细版 通俗易懂 含c语言稀疏矩阵十字链表代码 )

    前言 此文章是本人第一篇博客,目的在于巩固过去所学的知识,同时可能会给大家带来一丝丝帮助,但由于没有经验加上本人能力极其有限,文章中可能存在不足之处,还请读者能够指正(`・ω・´). 这篇文章首先会介 ...

最新文章

  1. mysql 分词搜索_MySQL5.7分词全文检索思路
  2. Android Studio动态调试Smali
  3. 使用for及递归求 1-100的和
  4. JavaScript实现表单的分向提交
  5. 用promise封装ajax_vue实践---vue结合 promise 封装原生ajax
  6. zookeeper windows 下安装
  7. 北大计算机基础与应用,北大16秋《计算机基础与应用-第六组》在线作业
  8. 阿里云centos远程连接mysql
  9. OC基础--关键字@property 和 @synthesize
  10. android 表情的正则,Android 手势 正则匹配图片实例代码
  11. 绿坝捅乱子,全球看笑话
  12. 50 个常用 matplotlib 可视化图表
  13. There's code using JDBC based datastore and not disposing them和threadLocal多次访问时,有的时候会访问不到
  14. 域名抢注代码_如何停止域名抢注攻击
  15. 程序员520❤七夕情人节表白代码Html+Js+Css花瓣相册网页模板❤程序员表白必备...
  16. JavaSE笔记 30天学Java打卡 Day03
  17. AUC / uAUC
  18. FANUC机器人Config系统配置中各项参数的功能描述及设定
  19. 职场,社恐的终极噩梦
  20. 目标检测_精确定位_2020

热门文章

  1. 企业信息管理系统(1)_系统页面框架分析
  2. Python-snap7 安装和测试
  3. ADC的DMA多通道数据采集(雨滴传感器+光敏传感器)
  4. C语言自动处理异常,C语言中异常错误处理机制浅析
  5. 如果你想专升本那就一定要看的文学常识完整版(三)
  6. 认识XP下的NetBEUI
  7. [复杂网络博弈] 第二章 演化博弈动力学基础
  8. 【时间序列】DTW算法详解
  9. 分治法--线性时间选择
  10. Cadence Allegro Vertex功能介绍使用方法Vertex与Slide的区别图文教程