1. 程式人生 > 其它 >稀疏矩陣-正交連結串列-加法

稀疏矩陣-正交連結串列-加法

兩個以正交連結串列表示的稀疏矩陣的加法演算法:

//自己寫的親測有效,經過嚴格測試:
#include<stdio.h>
#include<stdlib.h>
#define MaxSize  100
typedef   enum { H, E }   TagField;
typedef struct term {
    int row, col, value;
}Term;
typedef struct mnode {
    struct mnode* Right, * Down;
    TagField Tag;
    union {
        struct
mnode* Next; Term Element; }U; }MNode; typedef struct linkedmatrix { MNode* Head; MNode* HD[MaxSize]; }LinkedMatrix; MNode* NewNode() { MNode* temp = (MNode*)malloc(sizeof(MNode)); temp->Down = NULL; temp->Right = NULL; return temp; } //該演算法的時間複雜度為O(heads+nozeros)
LinkedMatrix MRead(void) { int rows, cols, nozeros, heads; int row, col, value, i; MNode* ptemp, * prow_last, *pcol_last, * pnode, * Temp; LinkedMatrix A; printf("Enter the number of rows, columns and number of nozero terms: "); scanf_s("%d%d%d", &rows, &cols, &nozeros);
//建立正交連結串列的表頭結點 heads = (cols > rows) ? cols : rows; pnode = NewNode(); pnode->Tag = E; pnode->U.Element.row = rows; pnode->U.Element.col = cols; pnode->U.Element.value = nozeros; pnode->Down = NULL; A.Head = pnode; Temp = A.Head; //把A的表頭結點賦給一個臨時變數 if (!heads) { pnode->Right=pnode; } else { //建立heads 個行/列表頭結點, 形成一個包含有Heads個元素的包含有表頭節點的空迴圈連結串列, for (i = 0; i < heads; i++) { A.HD[i] = NewNode(); A.HD[i]->Tag = H; A.HD[i]->Right = A.HD[i]; A.HD[i]->Down = A.HD[i]; if (i==0) { Temp->Right = A.HD[i]; } else { Temp->U.Next = A.HD[i]; } Temp = A.HD[i]; } Temp->U.Next = A.Head; //包含有Heads個元素的包含有表頭節點的空迴圈連結串列建立完成 //從第0行起,按行插入非0元素 for (i = 0; i < nozeros;i++) { printf("Enter row , col and value: "); scanf_s("%d%d%d", &row, &col, &value); ptemp = NewNode(); ptemp->Tag = E; ptemp->U.Element.row = row; ptemp->U.Element.col = col; ptemp->U.Element.value = value; ptemp->Right = A.HD[row]; ptemp->Down = A.HD[col]; prow_last = A.HD[row]; for (; prow_last->Right != A.HD[row]; prow_last = prow_last->Right); prow_last->Right = ptemp; prow_last = ptemp; pcol_last=A.HD[col]; for (; pcol_last->Down != A.HD[col]; pcol_last = pcol_last->Down); pcol_last->Down=ptemp; pcol_last=ptemp; } } return A; } LinkedMatrix Add2LinkedMatrix(LinkedMatrix a, LinkedMatrix b) { MNode* p_head_temp, * prow_temp, *p_a_row_temp, * p_a_col_temp, * ptemp, * p_a_row_temp1; int equalFlag = 0, lastrowFlag=0,lastcolFlag=0; LinkedMatrix result; if (a.Head==NULL || b.Head==NULL) { printf("can not be null\n"); return; } if (a.Head->U.Element.row != a.Head->U.Element.row || a.Head->U.Element.col != a.Head->U.Element.col) { printf("the shape of two Matrix must be itentical\n"); return; } p_head_temp = b.Head->Right; for (; p_head_temp != b.Head; p_head_temp = p_head_temp->U.Next) { prow_temp = p_head_temp->Right;//b中新的一行 for (; prow_temp != p_head_temp; prow_temp = prow_temp->Right) {//prow_temp按行掃描b,prow_temp指代當前b矩陣中非零結點 //printf("%d %d %d\n", prow_temp->U.Element.row, prow_temp->U.Element.col, prow_temp->U.Element.value); //在這裡開始逐一將b中的元素與a中的元素進行對比。如果相同位置中,a有b的同樣的元素,就直接將值相加。如果沒有,就將b中的元素插入到a的這個位置上。 equalFlag = 0; p_a_row_temp = a.HD[prow_temp->U.Element.row]; for (; p_a_row_temp->Right != a.HD[prow_temp->U.Element.row]; p_a_row_temp = p_a_row_temp->Right) { if (p_a_row_temp->U.Element.row == prow_temp->U.Element.row && p_a_row_temp->U.Element.col == prow_temp->U.Element.col) {//如果找到了這個元素, 行列一樣的話 p_a_row_temp->U.Element.value += prow_temp->U.Element.value; equalFlag = 1; break; } } if (equalFlag ==0 && p_a_row_temp->U.Element.row == prow_temp->U.Element.row && p_a_row_temp->U.Element.col == prow_temp->U.Element.col) {//如果找到了這個元素, 行列一樣的話 p_a_row_temp->U.Element.value += prow_temp->U.Element.value; continue; } if (equalFlag==0) {//如果這個元素a中沒有的話,那就將此元素插入到a中 lastrowFlag = 0; lastcolFlag = 0; a.Head->U.Element.value++; ptemp = NewNode(); ptemp->Tag = E; ptemp->U.Element.row = prow_temp->U.Element.row; ptemp->U.Element.col = prow_temp->U.Element.col; ptemp->U.Element.value = prow_temp->U.Element.value; ptemp->Right = NULL; ptemp->Down = NULL; //先把行搞定 p_a_row_temp1 = a.HD[prow_temp->U.Element.row]; //重新整理 p_a_row_temp 為 a的行表頭 for (; p_a_row_temp1->Right != a.HD[prow_temp->U.Element.row]; p_a_row_temp1 = p_a_row_temp1->Right) { if (p_a_row_temp1->Right->U.Element.col > ptemp->U.Element.col) { ptemp->Right = p_a_row_temp1->Right; p_a_row_temp1->Right=ptemp; lastrowFlag = 1; break; } } if (lastrowFlag==0) { ptemp->Right= a.HD[prow_temp->U.Element.row]; p_a_row_temp1->Right = ptemp; // 這時 p_a_row_temp1 指代 a中當前行的最後一個結點 } //再把列搞定 p_a_col_temp = a.HD[prow_temp->U.Element.col]; for (; p_a_col_temp->Down != a.HD[prow_temp->U.Element.col]; p_a_col_temp = p_a_col_temp->Down) { if (p_a_col_temp->Down->U.Element.row > ptemp->U.Element.row) { ptemp->Down = p_a_col_temp->Down; p_a_col_temp->Down = ptemp; lastcolFlag = 1; break; } } if (lastcolFlag == 0) { ptemp->Down = a.HD[prow_temp->U.Element.col]; p_a_col_temp->Down = ptemp; // 這時 p_a_row_temp1 指代 a中當前行的最後一個結點 } } } } result = a; return result; } void PrintLinkedMatrix(LinkedMatrix A) { MNode* ptemp, * prow_temp; ptemp = A.Head->Right; for (; ptemp != A.Head; ptemp= ptemp->U.Next) { prow_temp = ptemp->Right; for (; prow_temp != ptemp; prow_temp = prow_temp->Right) { printf("%d %d %d\n", prow_temp->U.Element.row, prow_temp->U.Element.col, prow_temp->U.Element.value); } } } void main() { LinkedMatrix A, B,addRes; A = MRead(); PrintLinkedMatrix(A); printf("**********************\n"); B = MRead(); PrintLinkedMatrix(B); printf("**********************\n"); addRes = Add2LinkedMatrix(A, B); PrintLinkedMatrix(addRes); system("pause"); }

UP主是一名程式設計師,再次考研複習中,需要討論問題一起復習的請聯絡我。