日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

十字链表存储稀疏矩阵

發(fā)布時間:2023/12/10 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 十字链表存储稀疏矩阵 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

??對于矩陣的存儲,如果矩陣的元素呈有明顯規(guī)律的排列的話,我們一般用一個一維數組對矩陣進行壓縮存儲;若矩陣中的元素多數為0,只有少數的元素為非0元素時,我們成該矩陣為稀疏矩陣
我們有矩陣Aij,其中有非0元素m個,若mij≤0.05,則我們稱矩陣Aij為稀疏矩陣我們有矩陣A_{ij},其中有非0元素m個,若\frac{m}{ij} \le 0.05,則我們稱矩陣A_{ij}為稀疏矩陣 Aij?0mijm?0.05Aij?
??對于稀疏矩陣,因為非零元素的排列是沒有規(guī)律的,因此我們無法采用壓縮的方法存儲矩陣,而若用一個二維數組去存儲含有為數不多的非零元素的矩陣,會有大量的空間浪費在存儲毫無意義的0元素上,因此,對于稀疏矩陣,我們可以選擇用十字鏈表來存儲。

話不多說,先上代碼

#include<stdio.h> #include<stdlib.h> #define FALSE 0 #define TRUE 1typedef int DataType; typedef struct SNode {int row;int column;union{DataType value;struct SNode *next;}uval;struct SNode *rnext;struct SNode *cnext; }SNode, *SNodePtr;// 創(chuàng)建矩陣 DataType ** CreateMatrix(int row, int column);// 創(chuàng)造十字鏈表 SNodePtr Create(int row, int column);// 向十字鏈表插入(如果存在則相加) void Insert(SNodePtr phead, SNodePtr pnode);// 將稀疏矩陣轉換成十字鏈表存儲 SNodePtr Matrix2List(DataType **pparr, int row, int column);// 矩陣相加 SNodePtr MatrixAdd(SNodePtr phead1, SNodePtr phead2);// 打印矩陣 void Print(SNodePtr phead);int main() {printf("請輸入第一個矩陣\n");DataType **arr1 = CreateMatrix(4, 4);printf("\n\n請輸入第二個矩陣\n");DataType **arr2 = CreateMatrix(4, 4);SNodePtr phead1 = Matrix2List(arr1, 4, 4);SNodePtr phead2 = Matrix2List(arr2, 4, 4);printf("\n\n\n");// 打印兩個矩陣Print(phead1);printf("\n\n\n");Print(phead2);printf("\n\n\n");SNodePtr phead = MatrixAdd(phead1, phead2);Print(phead);return 0; }// 創(chuàng)建矩陣 DataType ** CreateMatrix(int row, int column) {DataType **ipparr = (int **)malloc(sizeof(int *) * row);for(int i = 0; i < row; ++i){ipparr[i] = (int *)malloc(sizeof(int) * column);for(int j = 0; j < column; ++j)scanf("%d", &ipparr[i][j]);}return ipparr; }// 創(chuàng)造十字鏈表 SNodePtr Create(int row, int column) {// 創(chuàng)建頭結點SNodePtr phead = (SNodePtr)malloc(sizeof(SNode));phead->row = row;phead->column = column;phead->rnext = phead->cnext = NULL;phead->uval.next = NULL;SNodePtr ptmp = phead;// 創(chuàng)建十字鏈表if(row > column){for(int i = 0; i < row; ++i){ptmp->uval.next = (SNodePtr)malloc(sizeof(SNode));ptmp = ptmp->uval.next;ptmp->row = ptmp->column = 0;ptmp->uval.next = NULL;ptmp->cnext = ptmp;if(i < column)ptmp->rnext = ptmp;else ptmp->rnext = NULL;}}else{for(int i = 0; i < column; ++i){ptmp->uval.next = (SNodePtr)malloc(sizeof(SNode));ptmp = ptmp->uval.next;ptmp->row = ptmp->column = 0;ptmp->uval.next = NULL;ptmp->rnext = ptmp;if( i < row)ptmp->cnext = ptmp;elseptmp->cnext = NULL;}}return phead; }// 向十字鏈表插入(如果存在則相加) void Insert(SNodePtr phead, SNodePtr pnode) {SNodePtr prtmp = phead;// 找到對應行for(int i = 0; i < pnode->row; ++i)prtmp = prtmp->uval.next;SNodePtr ptmp1 = prtmp;// 找到要插入的地方while(ptmp1->cnext != prtmp && ptmp1->cnext->column < pnode->column)ptmp1 = ptmp1->cnext;if(ptmp1->cnext->column != pnode->column) {SNodePtr ptmp = (SNodePtr)malloc(sizeof(SNode)); // 新開辟空間使為了不改變pnode的指針ptmp->cnext = ptmp1->cnext;ptmp1->cnext = ptmp;ptmp->column = pnode->column;ptmp->row = pnode->row;ptmp->uval.value = pnode->uval.value;ptmp->rnext = NULL;// 接下來要將行指針連接SNodePtr pctmp = phead;// 找到對應列for(int i = 0; i < pnode->column; ++i)pctmp = pctmp->uval.next;SNodePtr ptmp2 = pctmp;// 找到要插入的地方while(ptmp2->rnext != pctmp && ptmp2->rnext->row < pnode->row)ptmp2 = ptmp2->rnext;ptmp->rnext = ptmp2->rnext;ptmp2->rnext = ptmp;return ;}else // 這一行有非零元素且他們在同一列{ptmp1->cnext->uval.value += pnode->uval.value;return ; // 因為沒有開辟新的空間,原來的結構不變,因此不需要對列進行操作,直接返回即可}}// 將稀疏矩陣轉換成十字鏈表存儲 SNodePtr Matrix2List(DataType **pparr, int row, int column) {SNodePtr phead = Create(row, column); // 創(chuàng)建十字鏈表// 創(chuàng)建并初始化臨時指針SNodePtr ptmp = (SNodePtr)malloc(sizeof(SNode));ptmp->row = ptmp->column = 0;ptmp->uval.value = 0;ptmp->rnext = ptmp->cnext = NULL;for(int i = 0; i < row; ++i){for(int j = 0; j < column; ++j){if(pparr[i][j] != 0){ptmp->row = i + 1;ptmp->column = j + 1;ptmp->uval.value = pparr[i][j];Insert(phead, ptmp);}}}return phead; }// 矩陣相加 SNodePtr MatrixAdd(SNodePtr phead1, SNodePtr phead2) {if(phead1->row != phead2->row || phead1->column != phead2->column) // 矩陣無法相加return NULL;SNodePtr phead = Create(phead1->row, phead1->column);// 將phead1加入pheadSNodePtr ptmp = phead1;for(int i = 0; i < phead1->row; ++i){ptmp = ptmp->uval.next;SNodePtr ptmp2 = ptmp;while(ptmp2->cnext != ptmp){ptmp2 = ptmp2->cnext;Insert(phead, ptmp2);}}Print(phead);// 將phead2加入pheadptmp = phead2;for(int i = 0; i < phead2->row; ++i){ptmp = ptmp->uval.next;SNodePtr ptmp2 = ptmp;while(ptmp2->cnext != ptmp){ptmp2 = ptmp2->cnext;Insert(phead, ptmp2);}}return phead; }// 打印矩陣 void Print(SNodePtr phead) {SNodePtr prtmp = phead;for(int i = 0; i < phead->row; ++i){prtmp = prtmp->uval.next;SNodePtr pctmp = prtmp->cnext;if(pctmp == prtmp){printf("0 0 0 0 ");continue;}for(int j = 1; j <= pctmp->column; ++j){if(j < pctmp->column)printf("0 ");else{printf("%d ", pctmp->uval.value);pctmp = pctmp->cnext;if(pctmp == prtmp){for(int k = phead->column; k > j; --k)printf("0 ");break;}}}printf("\n");}printf("\n"); }

??我的基本思想是對于矩陣的操作是不會影響原矩陣,即A + B = C,C不是將A加入B或者B加入A得到的,而是新開辟的一塊空間。基于此思想,在進行插入操作的時候,我并沒有對待插入的結點的指針做任何轉變,而是找到要插入的位置,新開辟一塊空間,將待插入結點的值,行列等賦值給新開辟的空間,然后再連接插入的結點的行列指針即可。基于此思想,我們在執(zhí)行矩陣A和B的相加的時候,完全不用考慮矩陣A和矩陣B中指針的變動,只需要創(chuàng)建一個新的空的十字鏈表,然后將A和B中的元素插入即可。

總結

以上是生活随笔為你收集整理的十字链表存储稀疏矩阵的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。