C語言數(shù)據(jù)結(jié)構(gòu)創(chuàng)建及遍歷十字鏈表
本文需要讀者有一定的代碼基礎(chǔ),了解指針,鏈表,數(shù)組相關(guān)知識(shí)。
一、十字鏈表是什么?
十字鏈表常用于表示稀疏矩陣,可視作稀疏矩陣的一種鏈?zhǔn)奖硎?,因此,這里以稀疏矩陣為背景介紹十字鏈表。不過,十字鏈表的應(yīng)用遠(yuǎn)不止稀疏矩陣,一切具有正交關(guān)系的結(jié)構(gòu),都可用十字鏈表存儲(chǔ)。
二、十字鏈表的存儲(chǔ)結(jié)構(gòu)
1.用于總結(jié)點(diǎn)的存儲(chǔ)結(jié)構(gòu)
m
:總行數(shù)
n
:總列數(shù)
len
:總元素個(gè)數(shù)
row_head
:行指針數(shù)組(通過行指針數(shù)組可以快速定位到某一行)
col_head
:列指針數(shù)組
2.用于單個(gè)節(jié)點(diǎn)的存儲(chǔ)結(jié)構(gòu)
row
:行數(shù)
col
:列數(shù)
value
:存儲(chǔ)的元素值
right
:右指針域
down
:下指針域
3.對于每一行,通過指針數(shù)組記錄下每一行的頭節(jié)點(diǎn)位置,對于列來說相同
4.通過對某一行,某一列的元素可以快速訪問
三、代碼實(shí)現(xiàn)
1.引入頭文件并定義結(jié)構(gòu)體
#include <stdio.h> #include<stdlib.h> /*十字鏈表的總結(jié)點(diǎn)結(jié)構(gòu)類型定義如下:*/ typedef struct OLNode { int row, col; /*非零元素的行和列下標(biāo)*/ int value; struct OLNode* right; /*非零元素所在行表、列表的后繼鏈域*/ struct OLNode* down; }OLNode, *OLink; /*單個(gè)節(jié)點(diǎn)結(jié)構(gòu)類型定義如下:*/ typedef struct { OLink* row_head; /*行、列鏈表的頭指針向量*/ OLink* col_head; int m, n, len; /*稀疏矩陣的行數(shù)、列數(shù)、非零元素的個(gè)數(shù)*/ }CrossList; void out_M(CrossList M); void CreateCrossList(CrossList* M);
2.建立十字鏈表
void CreateCrossList(CrossList* M) { int m, n, t, i, j, e; OLNode* p;//單元的結(jié)構(gòu)體指針 OLNode* q; /*采用十字鏈表存儲(chǔ)結(jié)構(gòu),創(chuàng)建稀疏矩陣M*/ printf("請輸入行數(shù),列數(shù)和非零元素的個(gè)數(shù)\n"); scanf_s("%d%d%d", &m, &n, &t); /*輸入M的行數(shù),列數(shù)和非零元素的個(gè)數(shù)*/ M->m = m; M->n = n; M->len = t; M->row_head = (OLink*)malloc((m + 1) * sizeof(OLink)); M->col_head = (OLink*)malloc((n + 1) * sizeof(OLink)); /*初始化行、列頭指針向量,各行、列鏈表為空的鏈表*/ for (int h = 0; h < m + 1; h++) { M->row_head[h] = NULL; } for (int t = 0; t < n + 1; t++) { M->col_head[t] = NULL; } printf("請輸入第i行,第j列中存儲(chǔ)的元素,以0結(jié)束\n"); for (scanf_s("%d%d%d", &i, &j, &e); i != 0; scanf_s("%d%d%d", &i, &j, &e)) { p = (OLNode*)malloc(sizeof(OLNode)); p->row = i; p->col = j; p->value = e; /*生成結(jié)點(diǎn)*/ /*在十字鏈表中插入節(jié)點(diǎn),對于行指針數(shù)組和列指針數(shù)組分開看,類似于單鏈表中的插入操作*/ if (M->row_head[i] == NULL) { M->row_head[i] = p; p->right = NULL; } else { /*尋找行表中的插入位置*/ for (q = M->row_head[i]; q->right && q->right->col < j; q = q->right); /*空循環(huán)體*/ p->right = q->right; q->right = p; /*完成插入*/ } if (M->col_head[j] == NULL) { M->col_head[j] = p; p->down = NULL; } else { /*尋找列表中的插入位置*/ for (q = M->col_head[j]; q->down && q->down->row < i; q = q->down); /*空循環(huán)體*/ p->down = q->down; q->down = p; /*完成插入*/ } } }
3.遍歷十字鏈表
void out_M(CrossList M) { /*遍歷十字鏈表的思想:可采用雙重for循環(huán)實(shí)現(xiàn),對于每一行中的每一列進(jìn)行遍歷輸出*/ int i; OLNode* p; char ch; /* 輸出矩陣的總行數(shù)、總列數(shù)、非零元素總個(gè)數(shù) */ printf("\n 總行數(shù)有%d 總列數(shù)有%d 非零元素有%d\n", M.m,M.n,M.len); for (i = 1; i <= M.m; i++) { p = M.row_head[i]; /* 指向第i行 */ if (p) { printf("\n 第%d行的數(shù)據(jù)如下\n", i); while (p) { printf(" (%3d%3d%4d) ", p->row, p->col, p->value); p = p->right; } } printf("\n"); } }
4.調(diào)用函數(shù)
void out_M(CrossList M) { /*遍歷十字鏈表的思想:可采用雙重for循環(huán)實(shí)現(xiàn),對于每一行中的每一列進(jìn)行遍歷輸出*/ int i; OLNode* p; char ch; /* 輸出矩陣的總行數(shù)、總列數(shù)、非零元素總個(gè)數(shù) */ printf("\n 總行數(shù)有%d 總列數(shù)有%d 非零元素有%d\n", M.m,M.n,M.len); for (i = 1; i <= M.m; i++) { p = M.row_head[i]; /* 指向第i行 */ if (p) { printf("\n 第%d行的數(shù)據(jù)如下\n", i); while (p) { printf(" (%3d%3d%4d) ", p->row, p->col, p->value); p = p->right; } } printf("\n"); } }
以上就是C語言數(shù)據(jù)結(jié)構(gòu)創(chuàng)建及遍歷十字鏈表的詳細(xì)內(nèi)容,更多關(guān)于C語言數(shù)據(jù)結(jié)構(gòu)的資料請關(guān)注腳本之家其它相關(guān)文章!
- C語言 二叉樹的鏈?zhǔn)酱鎯?chǔ)實(shí)例
- C語言實(shí)現(xiàn)通用數(shù)據(jù)結(jié)構(gòu)之通用鏈表
- C語言數(shù)據(jù)結(jié)構(gòu)之單向鏈表詳解分析
- C語言數(shù)據(jù)結(jié)構(gòu)之復(fù)雜鏈表的拷貝
- C語言數(shù)據(jù)結(jié)構(gòu)單鏈表接口函數(shù)全面講解教程
- C語言編程數(shù)據(jù)結(jié)構(gòu)帶頭雙向循環(huán)鏈表全面詳解
- C語言編程數(shù)據(jù)結(jié)構(gòu)線性表之順序表和鏈表原理分析
- C語言編程數(shù)據(jù)結(jié)構(gòu)的棧和隊(duì)列
- C語言數(shù)據(jù)結(jié)構(gòu)之線性表的鏈?zhǔn)酱鎯?chǔ)結(jié)構(gòu)
相關(guān)文章
老生常談C語言動(dòng)態(tài)函數(shù)庫的制作和使用(推薦)
下面小編就為大家?guī)硪黄仙U凜語言動(dòng)態(tài)函數(shù)庫的制作和使用(推薦)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-08-08探討register關(guān)鍵字在c語言和c++中的差異
建議不要用register關(guān)鍵字定義全局變量,因?yàn)槿肿兞康纳芷谑菑膱?zhí)行程序開始,一直到程序結(jié)束才會(huì)終止,而register變量可能會(huì)存放在cpu的寄存器中,如果在程序的整個(gè)生命周期內(nèi)都占用著寄存器的話,這是個(gè)相當(dāng)不好的舉措2013-10-10Qt使用SQLite數(shù)據(jù)庫存儲(chǔ)管理圖片文件
這篇文章主要為大家詳細(xì)介紹了Qt如何使用SQLite數(shù)據(jù)庫實(shí)現(xiàn)存儲(chǔ)管理圖片文件的功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下2023-04-04C語言用函數(shù)指針實(shí)現(xiàn)一個(gè)特別的計(jì)算器
函數(shù)指針是一個(gè)指針變量,它可以存儲(chǔ)函數(shù)的地址,然后使用函數(shù)指針,下面這篇文章主要給大家介紹了關(guān)于C語言用函數(shù)指針實(shí)現(xiàn)計(jì)算器的方法,需要的朋友可以參考下2022-07-07C語言詳細(xì)講解strcpy strcat strcmp函數(shù)的模擬實(shí)現(xiàn)
這篇文章主要介紹了怎樣用C語言模擬實(shí)現(xiàn)strcpy與strcat和strcmp函數(shù),strcpy()函數(shù)是C語言中的一個(gè)復(fù)制字符串的庫函數(shù),strcat()函數(shù)的功能是實(shí)現(xiàn)字符串的拼接,strcmp()函數(shù)作用是比較字符串str1和str2是否相同2022-05-05C語言中對字母進(jìn)行大小寫轉(zhuǎn)換的簡單方法
這篇文章主要介紹了C語言中對字母進(jìn)行大小寫轉(zhuǎn)換的簡單方法,是C語言入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2015-08-08