十字链表存储
(耿《數(shù)據(jù)結(jié)構(gòu)》原文)為避免大量移動(dòng)元素,采用稀疏矩陣的鏈?zhǔn)酱鎯?chǔ)法——十字鏈表。
它的好處是能靈活地插入因運(yùn)算而產(chǎn)生的非零元素,刪除因運(yùn)算而產(chǎn)生的新的零元素,實(shí)現(xiàn)矩陣的各種運(yùn)算。
1.十字鏈表的存儲(chǔ)表示(五要素)
矩陣的每一個(gè)非零元素用一個(gè)結(jié)點(diǎn)表示,該結(jié)點(diǎn)除了(row,col,value)以外,還要添加兩個(gè)鏈域:
right:用于鏈接同一行中的下一個(gè)非零元素
down:用于鏈接同一列中的下一個(gè)非零元素
在十字鏈表的儲(chǔ)存結(jié)構(gòu)中,可以看成是兩個(gè)單鏈表的組合溝通。可以類比行指針,列指針。
同一行的非零元素通過right域鏈接成一個(gè)單鏈表,
同一列的非零元素通過down域鏈接成一個(gè)單鏈表。
相應(yīng)的,需要附設(shè)一個(gè)存放所有行鏈表頭指針的一維數(shù)組和一個(gè)存放所有列鏈表的頭指針的一維數(shù)組。
2.十字鏈表的類型定義
一個(gè)結(jié)點(diǎn)的定義;
typedef struct OLNode { int row,col; ElementType value; struct OLNode *right,*down;//指向的下一個(gè)結(jié)點(diǎn)也是同樣的結(jié)構(gòu) }OLNode;*OLink;十字鏈表存儲(chǔ)結(jié)構(gòu)
typedef struct { OLink *row_head,*col_head;//頭指針 int m,n,len;//行,列,非零元素個(gè)數(shù) }CrossList;3.十字鏈表的算法實(shí)現(xiàn)
步驟:
①讀入稀疏矩陣的行數(shù),列數(shù),非零元素個(gè)數(shù);
②申請(qǐng)行,列鏈表的頭指針空間;
③逐個(gè)讀入非零元素,分別插入行鏈表,列鏈表。
算法(建立稀疏矩陣的十字鏈表,實(shí)質(zhì)是在兩個(gè)單鏈表中完成插入)
CreateCrossList(CrossList *M) { scanf("%d %d %d",&m,&n,&t); M->m=m; M->n=n; M->len=t; if(!(M->row_head=(OLink*)malloc((m+1)sizeof(OLink)))) exit(OVERFLOW); if(!(M->col_head=(OLink*)malloc((n+1)sizeof(OLink)))) exit(OVERFLOW); M->row_head[]=M->col_head[]=NULL;//初始化 for(scanf(&i,&j,&e);i!=0;scanf(&i,&j,&e))//讀入非零的數(shù)據(jù),信息包括它的行,列,數(shù)據(jù) { if(!(p=(OLNode*)malloc(sizeof(OLNode)))) exit(OVERFLOW); p->row=i; p->col=j; p->value=e;//生成結(jié)點(diǎn) //插入行鏈表 if(M->row_head[i]==NULL)//如果原先的稀疏矩陣這一行全為零,直接以這個(gè)插入的結(jié)點(diǎn)創(chuàng)建這一行行鏈表的頭指針 M->row_head[i]=p; else { //尋找插入的位置 q=M->row_head[i];//用來指向這一行的插入點(diǎn)的前一個(gè)結(jié)點(diǎn),一開始指向行表頭 while(q->right!=NULL&&q->right->col<j) { q=q->right; p->right=q->right;//隨循環(huán)右移 q->right=p;//完成插入 } //插入列鏈表 if(M->col_head[j]==NULL) M->col_head[j]=p; else { //尋找插入位置 q=M->col_head[j]; while(q->down!=NULL&&q->down->row<i) q=q->down; p->down=q->down; q->down=p; } } }總結(jié)
- 上一篇: python日志配置文件解释_pytho
- 下一篇: java - 百钱百鸡小算法