-
2021-11-12 00:58:50
-
实验内容及要求:
编写程序,从字符文件读入三个正整数m, n, t以及t个三元组(i, j, e)建立稀疏矩阵的十字链表存储结构。其中,m、n分别表示矩阵行数和列数;i, j为非零元素行号和列号。编写算法,实现矩阵转置,输出转置后的三元组到另一字符文件中,检查你的转置结果是否正确。要求转置时不得新建元素结点(但允许新建行头/列头结点数组以及删除行头/列头结点数组,转置前后,总头结点不允许改变)。
-
实验目的:掌握稀疏矩阵的十字链表存储结构。
-
数据结构设计简要描述:
采用三元组定义矩阵,十字链表存储矩阵,down指针指向下一行,right指针指向下一列,e为矩阵元素
-
算法设计简要描述:
更多相关内容 -
-
基于十字链表存储的稀疏矩阵的转置
2019-04-28 14:29:32实现了从字符文件读入三个正整数m, n, t以及t个三元组(i, j, e)建立稀疏矩阵的十字链表存储结构(m、n分别表示矩阵行数和列数;i, j为非零元素行号和列号)和十字链表的转置并将转置后的三元组到另一字符文件中 -
数据结构实验报告4-数组与广义表-基于十字链表的稀疏矩阵转置-实验内容及要求.docx
2019-07-06 20:45:49编写程序,从字符文件读入三个正整数m, n, t以及t个三元组(i, j, e)建立稀疏矩阵的十字链表存储结构。其中,m、n分别表示矩阵行数和列数;i, j为非零元素行号和列号。编写算法,实现矩阵转置,输出转置后的三元组到... -
数据结构实验:基于十字链表的稀疏矩阵转置
2021-11-20 15:30:13基于十字链表的稀疏矩阵转置采用C++编程,基于十字链表完成转置。
思想为改变行列指针指向。
#include <iostream> #include <string> #include <fstream> using namespace std; #define ERROR -1 #define OK 1 typedef int ElemType; typedef int Status; typedef struct OLNode { int i, j;//矩阵非零元素的行、列值 ElemType e;//非零元素的值 OLNode* right, * down;//行列后继域 }OLNode, * Olink; typedef struct { Olink rhead, chead;//行、列 表指针基址 int mu, nu, tu;//矩阵的行、列、非零元素个数 }CrossList; Status insert(Olink h, int i, int j, int e)//插入结点 { int m = h->i, n = h->j; if (i < 0 || i >= m || j < 0 || j >= n) return ERROR;//结点坐标不合法则返回ERROR Olink p = new OLNode; if (!p) return ERROR;//建立新结点 p->i = i;p->j = j;p->e = e; Olink qr = &h->down[i], q = qr->right; while (q != &h->down[i] && j > q->j)//找到结点插入位置 { qr = q;q = q->right; } qr->right = p;p->right = q; qr = &h->right[j];q = qr->down; while (q != &h->right[j] && i > q->i) { qr = q;q = q->down; } qr->down = p; p->down = q; cout << i << '\t' << j << '\t' << e << endl; return OK; } Status init(Olink h)//从文件中获取数据初始化十字链表 { fstream data; data.open("data.txt"); data >> h->i >> h->j;//建立总头节点,头结点内存储行列数与行列基址 int t; data >> t; h->e = t; h->down = new OLNode[h->i];//创建行头数组 if (!h->down) return ERROR;//返回NULL表示创建失败 h->right = new OLNode[h->j];//创建列头数组 if (!h->right) return ERROR; for (int i = 0;i < h->i;i++)//初始化行列头结点 { h->down[i].i = i; h->down[i].right = &h->down[i]; } for (int j = 0;j < h->j;j++) { h->right[j].j = j; h->right[j].down = &h->right[j]; } int m = h->i, n = h->j; for (;t > 0;t--) { int i, j, e; data >> i >> j >> e; insert(h, i, j, e); } data.close(); return OK; } Status Transpose(Olink h)//矩阵转置 { fstream data; data.open("out.txt"); int mid=h->i; h->i = h->j; h->j = mid; Olink pn; data << h->i << '\t' << h->j << '\t' << h->e << endl; for (int i = 0;i<h->i;i++)//从列数组遍历,改变down指针与right指针的指向 { Olink p = &h->right[i]; p->right = p->down; p = h->right[i].down; while(p!=&h->right[i]) { pn = p->down; p->down = p->right; p->right = pn; mid = p->i; p->i = p->j; p->j = mid; data<< p->i << '\t' << p->j << '\t' << p->e << endl;//写入文件 p = pn; } } for (int i = 0;i < h->j;i++)//改变行头数组的指向 { Olink p = &h->down[i]; p->down = p -> right; } Olink q = h->right; h->right = h->down; h->down = q; for (int i = 0;i < h->i;i++) { Olink p = h->down[i].right; while (p != &h->down[i]) { cout << p->i << '\t' << p->j << '\t' << p->e << endl; p = p->right; } } data.close(); return OK; } int main() { OLNode h; init(&h); cout << endl; Transpose(&h); }
-
C++实现基于十字链表的稀疏矩阵的转置
2019-04-09 21:45:14使用的数据结构 十字链表的定义如下: typedef struct node { int i, j;//行号,列号 int e;...基于十字链表存储的稀疏矩阵的创建这里不做详细讲解,这里只展示本人创建的示例: 转置算法的...使用的数据结构
十字链表的定义如下:
typedef struct node { int i, j;//行号,列号 int e;//存储的数据 struct node *right, *down;//right,down分别为行指针和列指针 }OLNode;
通过上述定义创建下图所示的十字链表结点:
基于十字链表存储的稀疏矩阵的创建这里不做详细讲解,这里只展示本人创建的示例:
转置算法的思路
矩阵转置实现的核心思想:将原矩阵的行变成列,列变成行,即仅通过改变结点的行列号以及对每个结点的指向进行改变从而得到转置后的矩阵,这里我用了一个例子来解释。
第一步:将矩阵中元素的行,列号交换并将其行指针与列指针指向的地址交换。如:
第2步:将十字链表中的行头结点和列头结点的行,纵坐标交换并将其行,列指针指向的值交换,结果如下:
第3步:将总头结点的行,列号值交换并将其行,列号指针指向的值交换,如图:
结果演示
经过以上三步就完成了对原矩阵的转置,而且并不需要进行结点的删增加等操作,最终的效果如图所示:
程序运行结果如下:
说明:本人是从文件中读取的数据,并将结果保存到另一个文件中。矩阵转置实现代码
void swap(int &i, int &j)//交换 { int temp; temp = i; i = j; j = temp; } void Transposition(OLNode &s)//十字链表的转置 { OLNode *p, *save, *temp; //将原十字链表中的元素的行坐标和列坐标,行指针和列指针交换 for (int i = 0; i < s.i; i++) { p = s.down[i].right; while (p != &s.down[i]) { swap(p->i, p->j); save = p; p = p->right; temp = save->right; save->right = save->down; save->down = temp; } } //将列头结点的行,列坐标以及行指针和列指针交换 for (int i = 0; i < s.j; i++) { swap(s.right[i].i, s.right[i].j); temp = s.right[i].right; s.right[i].right = s.right[i].down; s.right[i].down = temp; } //将行头结点的行,列坐标以及行指针和列指针交换 for (int i = 0; i < s.i; i++) { swap(s.down[i].i, s.down[i].j); temp = s.down[i].right; s.down[i].right = s.down[i].down; s.down[i].down = temp; } //将总头结点的行指针和列指针以及 temp = s.right; s.right = s.down; s.down = temp; swap(s.i, s.j); }
以上便是本文的全部内容,如果觉得好的话就点个赞吧!!!
-
十字链表实现稀疏矩阵,包含十二大功能
2021-11-19 09:38:15十字链表实现稀疏矩阵 1.问题描述 用十字链表存储和表示稀疏矩阵,并实现如下功能 2.基本要求 初始化:创建十字链表并从文件中读取稀疏矩阵数据(文件数据可以是三元组结构); 在十字链表上设置坐标为(i,j...
题目:
- 十字链表实现稀疏矩阵
1.问题描述
用十字链表存储和表示稀疏矩阵,并实现如下功能
2.基本要求
- 初始化:创建十字链表并从文件中读取稀疏矩阵数据(文件数据可以是三元组结构);
- 在十字链表上设置坐标为(i,j)的位置值为value;
- 获取坐标为(i,j)的位置的值;
- 插入一项、删除某项的值;
- 输出十字链表表示的稀疏矩阵;
- 实现两个稀疏矩阵的加法、减法、乘法的功能,结果保存到新的十字链表中;
- 实现把十字链表表示的稀疏矩阵存入文件;
- 可以用菜单选择所有功能,设计良好的操作界面;
- 在需求分析阶段完成未尽功能需求,适当扩充功能(例如矩阵转置、求最值等)。
实现:
技术难点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]; //矩阵名称 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语言实现稀疏矩阵的三元组转置
2018-01-18 12:55:10数据结构,该程序是利用c语言实现稀疏矩阵的三元组转置算法 -
稀疏矩阵的十字链表表示方法:矩阵加减乘法运算、矩阵转置运算、矩阵项的插入、矩阵行列链表的排序
2014-06-08 15:39:45稀疏矩阵的十字链表表示方法:矩阵加减乘法运算、矩阵转置运算、矩阵项的插入、矩阵行列链表的排序 -
十字链表存储稀疏矩阵
2021-11-23 10:29:03若矩阵中的元素多数为0,只有少数的元素为非0元素时,我们成该矩阵为稀疏矩阵。 我们有矩阵Aij,其中有非0元素m个,若mij≤0.05,则我们称矩阵Aij为稀疏矩阵 我们有矩阵A_{ij},其中有非0元素m个,若\frac{m}{ij} \... -
十字链表法,十字链表压缩存储稀疏矩阵详解
2021-05-22 14:55:08对于压缩存储稀疏矩阵,无论是使用图 1 十字链表示意图可以看到,使用十字链表压缩存储稀疏矩阵时,矩阵中的各行各列都各用一各链表存储,与此同时,所有行链表的表头存储到一个数组(rhead),所有列链表的表头存储到... -
十字链表实现稀疏矩阵的各种功能
2021-11-19 09:43:47十字链表实现稀疏矩阵的加法、减法、乘法、转置、求最值、插入、查看、删除等基本功能,菜单栏采用hash表存储稀疏矩阵,给每个矩阵存储一个名字,hash函数进行寻找。 -
稀疏矩阵的十字链表实现(C语言实现)
2015-02-06 11:30:10又要从头学数据结构了。 默默挨个实现一遍 实现的功能包括两个矩阵的加减 相乘...// 稀疏矩阵的十字链表存储表示 typedef struct OLNode { int i,j; //该非零元的列和下标 ElemType e; //非零元素值 struct O -
特殊矩阵的处理 实验5:稀疏矩阵ADT的十字链表实现,矩阵乘法/加法/转置
2020-04-14 10:57:19稀疏矩阵ADT的实现: 在现实应用中,一些规模很... 稀疏矩阵就是一种应用很广泛的特殊的矩阵,在实现稀疏矩阵ADT时通常采用“压缩”存储方案,即把只存储稀疏矩阵的非零元素,把稀疏矩阵抽象成为一个以三元组(行,... -
稀疏矩阵的存储表示(十字链表) C语言
2021-02-12 18:01:37} } /*输出稀疏矩阵,可能会在行数和列数比较大的时候发生错位,主要因为终端窗口不够大而且不能横向拉伸*/ void printMatrix(){ GList r = head->down; for(int i = 0;i <= head->col;++i){ printf("%d\t",i); } ... -
稀疏矩阵的十字链表实现:行列链表
2014-06-08 21:52:18稀疏矩阵的十字链表实现 -
十字链表在稀疏矩阵的应用
2010-10-28 10:04:47稀疏矩阵的应用(十字链表) 一、 设计要求 1.问题描述 设计程序用十字链表实现稀疏矩阵的加、乘、转置。 2.需求分析 (1)设计函数建立稀疏矩阵,初始化值。 (2)设计函数输出稀疏矩阵的值。 (3)构造函数进行... -
三元组,十字链表下的稀疏矩阵的加、转、乘的实现
2010-06-05 20:57:50用C++编写的程序,有很详细的步骤解说。 -
稀疏矩阵的三种表示方法·转置矩阵·矩阵相乘·十字链表表示法·数组的基本操作
2020-03-10 20:21:58十字链表中的结点中不仅有行号、列号、元素值,还有指向下一行的、下一列的非零元的两个指针。 typedef struct OLNode{ int i,j;//非零元的行、列下标 ElemType e; struct OLNode *right,*down;//该非零元所在行... -
稀疏矩阵的两种表达方式——三元组&&十字链表
2021-03-03 12:27:42十字链表 由行、列、值,和两个指向域,分别是down和right,分别指向两个方向,可以为空。 三元组存储时查找指定行号和列好元素值的算法,如下: typedefineStruct{ int i,j; ElemType e; }Triple; ... -
稀疏矩阵的链式存储——十字链表法
2019-11-11 22:55:28【创建】 CrossList* Create(int A[][maxSize], int m, int n) { CrossList* cl = (CrossList*)malloc(sizeof(CrossList)); cl->m = m; cl->n = n; cl->k = 0; ... //申请头结点... -
C语言数据结构两个稀疏矩阵相加
2019-04-30 18:27:20C语言数据结构之两个稀疏矩阵相加。代码中代码功能描述、输入输出说明和测试输出输入。 -
数据结构课程设计 报告 (十字链表实现稀疏矩阵的加法)
2021-01-16 02:33:31一、问题描述十字链表实现稀疏矩阵的加法1、功能要求:根据用户输入的矩阵,实现稀疏矩阵的求和运算,并输出结果。2、输入要求:矩阵的数据在程序运行的时候由用户提供,先由用户输入稀疏矩阵的行数、列数和非零元个... -
稀疏矩阵数据结构的存储——十字链表法
2020-07-06 12:06:55可以设想一个场景,一个矩阵是从左往右,从上往下,按左上角到右下角的方向生成的。在每个行和列交叉的节点上存储数据。那这些数据间有何种联系,采用何种方式可以方便的对任意节点的数据进行读写操作? 假设每个... -
算法5-4:采用十字链表存储的稀疏矩阵-题解(C++代码)
2021-05-23 03:33:45```cpp#include using namespace std;struct A{int row;int col;int data;struct A *pi = NULL;struct A *pj = NULL;};typedef A *PA;void disp(PA rhead[], PA chead[], int r, int c);int main(){int r, c;... -
稀疏矩阵快速转置稀疏矩阵快速转置
2011-05-10 17:13:36#######3稀疏矩阵快速转置........ -
三元组表压缩存储稀疏矩阵实现稀疏矩阵的快速转置(Java语言描述)
2021-02-28 09:32:56三元组表压缩存储稀疏矩阵实现稀疏矩阵的快速转置(Java语言描述)用经典矩阵转置算法和普通的三元组矩阵转置在时间复杂度上都是不乐观的。快速转置算法在增加适当存储空间后实现快速转置具体原理见代码注释部分,时间... -
数据结构——c语言描述 第五章(3)十字链表存储稀疏矩阵
2016-07-11 00:12:25第五章的最后一个内容,用十字链表存储系数矩阵,当然我看后面的图当中好像也还是有十字链表的内容的,我非常喜欢链表这个数据结构,实现起来感觉游刃有余,大概就是唯手熟尔吧,哈哈。首先上一下十字链表的逻辑图。... -
数据结构算法之稀疏矩阵
2020-12-21 21:53:30转载请注明出处: 转载自 Thinkgamer的CSDN博客:blog.csdn.net/gamer_gyt1:稀疏矩阵的背景2:什么是稀疏矩阵?3:为什么要对稀疏矩阵进行压缩存储以及压缩存储的方式?4:稀疏矩阵的相关运算一:背景第一此介绍... -
【数据结构】稀疏矩阵的压缩存储(三元组表、十字链表)(C语言)
2022-01-27 18:48:29十字链表2.1 十字链表的存储结构 稀疏矩阵是指矩阵中大多数元素为零的矩阵。从直观上讲,当非零元素个数低于总元素的30%时,这样的矩阵为稀疏矩阵。 1. 三元组表 1.1 三元组表的存储结构 稀疏矩阵的三元组表表示法... -
稀疏矩阵的存储与获取(十字链表法 C++版)
2021-07-12 20:53:27此稀疏矩阵我们打算采用十字链表法进行存储。 代码实现及结果测试: ... 稀疏矩阵的十字链表法实现方式 */ //十字链表的元素结点 typedef struct OLNode{ int i,j,value; //i行标 j列标 value元素值 struc...
收藏数
538
精华内容
215