十字链表实现矩阵存储
生活随笔
收集整理的這篇文章主要介紹了
十字链表实现矩阵存储
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
一、介紹
用十字鏈表存儲稀疏矩陣,可以起到節省空間的作用。
十字鏈表作為多重鏈表的一種,其結點分為兩種:
類型1:數據域為另一個單鏈表的頭指針。
類型2:數據域為待存儲的數據。
其中,“十字”體現在:每一個存儲數據的節點都屬于兩個單鏈表,從而構成十字形。
?
用十字鏈表表示的矩陣,有著以下特征:
1、整體的頭指針指向最初的頭結點,該頭結點一般用于存儲矩陣的行數、列數以及其中包含非0元素的數量。
2、由最初的頭結點分別橫向、縱向展開兩個單鏈表,這兩個鏈表中的每個結點都為類型1。
3、這兩個鏈表中的每個結點代表特定的行或列,引出單鏈表。
4、每個用于儲存矩陣元素的類型2結點都屬于某兩個類型1結點引出的單鏈表。由此可標記元素在矩陣中的具體位置。
二、實現
.general.h:總聲明。
#ifndef _GEN_H_#define _GEN_H_#include <stdio.h> #include <stdlib.h> #include <stdbool.h> typedef unsigned int Cursor; #define ERROR 0xABCDEF typedef int ElemType;#endifLinkGen.h:十字鏈表和基本的遍歷函數聲明。
#ifndef _LINK_GEN_H_#define _LINK_GEN_H_ #include ".general.h"/*Structure Declaration*/ enum Type {HEAD, UNIT, START}; typedef struct GNode *GPos; typedef struct GNode *GLink; struct GNode {enum Type tag;union {GLink head;struct {Cursor row;Cursor column;ElemType value;} unit;} region;GPos right;GPos down; };/*Function Declaration*/ //向右遍歷 GPos GLocateRight(GLink start, Cursor subs); //向下遍歷 GPos GLocateDown(GLink start, Cursor subs);#endifLinkGen.c:函數實現。
#include "LinkGen.h"GPos GLocateRight(GLink start, Cursor subs) {GPos ptr = start;for(int i = 0; i < subs; i++) {if(!ptr->right)return NULL;else ptr = ptr->right;}return ptr; }GPos GLocateDown(GLink start, Cursor subs) {GPos ptr = start;for(int i = 0; i < subs; i++) {if(!ptr->down)return NULL;else ptr = ptr->down;}return ptr; }Matrix.h:聲明矩陣和相關函數。
#ifndef _MATRIX_H_#define _MATRIX_H_ #include "LinkGen.h"/*Structure Declaration*/ typedef GLink Matrix;/*Function Declaration*/ //創建矩陣 Matrix CreateMatrix(Cursor MaxRow, Cursor MaxCol); //插入矩陣中的元素 bool InsertUnit(Matrix M, ElemType E, Cursor Row, Cursor Column); //打印矩陣 bool PrintMatrix(Matrix M); //銷毀矩陣 bool DestroyMatrix(Matrix M);#endifMatrix.c:函數實現。
#include "Matrix.h"Matrix CreateMatrix(Cursor MaxRow, Cursor MaxCol) {if(!MaxRow || !MaxCol)return NULL;/*Origin Node*/Matrix M = (Matrix) malloc(sizeof(struct GNode));if(!M)exit(EXIT_FAILURE);M->tag = START;M->region.unit.row = MaxRow;M->region.unit.column = MaxCol;M->region.unit.value = 0;/*Row Node*/GPos preR = M;for(int i = 0; i < MaxRow; i++) {GPos tmp = (GPos) malloc(sizeof(struct GNode));if(!tmp)exit(EXIT_FAILURE);tmp->tag = HEAD;tmp->region.head = NULL;preR->down = tmp;if(preR != M)preR->right = NULL;preR = preR->down;}preR->right = NULL;/*Column Node*/GPos preC = M;for(int i = 0; i < MaxCol; i++) {GPos tmp = (GPos) malloc(sizeof(struct GNode));tmp->tag = HEAD;tmp->region.head = NULL;preC->right = tmp;if(preC != M)preC->down = NULL;preC = preC->right;}preC->down = NULL;return M; }bool InsertUnit(Matrix M, ElemType E, Cursor Row, Cursor Column) {if(M->tag != START || Row > M->region.unit.row || Column > M->region.unit.column)return false;/*Allocation*/GPos tmp = (GPos) malloc(sizeof(struct GNode));if(!tmp)exit(EXIT_FAILURE);tmp->tag = UNIT;tmp->region.unit.row = Row;tmp->region.unit.column = Column;tmp->region.unit.value = E;/*Row Location*/GPos ptrR = GLocateDown(M, Row);if(ptrR->tag == HEAD && ptrR->region.head) {ptrR = ptrR->region.head;while(ptrR->right && !(ptrR->region.unit.column < Column && ptrR->down->region.unit.column > Column)) ptrR = GLocateRight(ptrR, 1);tmp->right = ptrR->right;ptrR->right = tmp;} else {if(ptrR->tag != HEAD)return false;tmp->right = NULL;ptrR->region.head = tmp;}/*Column Location*/GPos ptrC = GLocateRight(M, Column);if(ptrC->tag == HEAD && ptrC->region.head) {ptrC = ptrC->region.head;while(ptrC->down && !(ptrC->region.unit.row < Row && ptrC->down->region.unit.row > Row)) ptrC = GLocateDown(ptrC, 1);tmp->down = ptrC->down;ptrC->down = tmp;} else {if(ptrC->tag != HEAD)return false;tmp->down = NULL;ptrC->region.head = tmp;}M->region.unit.value++;return true; }bool PrintMatrix(Matrix M) {if(M->tag != START)return false;GPos ptrR = M;for(int i = 0; i < M->region.unit.row; i++) {ptrR = GLocateDown(ptrR, 1);if(!ptrR)return false;GPos ptrC = ptrR->region.head;if(!ptrC) {//空行填0for(int j = 0; j < M->region.unit.column; j++) printf("%-2d ", 0);putchar('\n');} else {//行前補0for(int k = 1; k < ptrC->region.unit.column; k++)printf("%-2d ", 0);//行中補0while(ptrC->right) {printf("%-2d ", ptrC->region.unit.value);int diff = ptrC->right->region.unit.column - ptrC->region.unit.column;for(int k = 1; k < diff; k++) printf("%-2d ", 0);putchar('\n');}//行后補0printf("%-2d ", ptrC->region.unit.value);int excess = M->region.unit.column - ptrC->region.unit.column;for(int k = 0; k < excess; k++)printf("%-2d ", 0);putchar('\n');}}return true; }三、運行實例
main.c
#include "Matrix.h"int main() {Matrix M = CreateMatrix(4, 3);InsertUnit(M, 62, 1, 2);InsertUnit(M, 23, 2, 1);InsertUnit(M, 18, 3, 2);InsertUnit(M, 29, 4, 3);PrintMatrix(M);return 0; }輸出:
總結
以上是生活随笔為你收集整理的十字链表实现矩阵存储的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 11.SolrJ索引操作
- 下一篇: 采样频率和带宽的关系_基于矢量网络分析仪