(原创)数据结构之十字链表总结
7-1 稀疏矩陣 (30 分)
如果一個(gè)矩陣中,0元素占據(jù)了矩陣的大部分,那么這個(gè)矩陣稱為“稀疏矩陣”。對(duì)于稀疏矩陣,傳統(tǒng)的二維數(shù)組存儲(chǔ)方式,會(huì)使用大量的內(nèi)存來存儲(chǔ)0,從而浪費(fèi)大量?jī)?nèi)存。為此,可以用三元組的方式來存放一個(gè)稀疏矩陣。
對(duì)于一個(gè)給定的稀疏矩陣,設(shè)第r行、第c列值為v,且v不等于0,則這個(gè)值可以表示為 <r,v,c>。這個(gè)表示方法就稱為三元組。那么,對(duì)于一個(gè)包含N個(gè)非零元素的稀疏矩陣,就可以用一個(gè)由N個(gè)三元組組成的表來存儲(chǔ)了。
如:{<1, 1, 9>, <2, 3, 5>, <10, 20, 3>}就表示這樣一個(gè)矩陣A:A[1,1]=9,A[2,3]=5,A[10,20]=3。其余元素為0。
要求查找某個(gè)非零數(shù)據(jù)是否在稀疏矩陣中,如果存在則輸出其所在的行列號(hào),不存在則輸出ERROR。
輸入格式:
共有N+2行輸入: 第一行是三個(gè)整數(shù)m, n, N(N<=500),分別表示稀疏矩陣的行數(shù)、列數(shù)和矩陣中非零元素的個(gè)數(shù),數(shù)據(jù)之間用空格間隔; 隨后N行,輸入稀疏矩陣的非零元素所在的行、列號(hào)和非零元素的值; 最后一行輸入要查詢的非0數(shù)據(jù)k。
輸出格式:
如果存在則輸出其行列號(hào),不存在則輸出ERROR。
輸入樣例:
在這里給出一組輸入。例如:
10 29 3
2 18 -10
7 1 98
8 10 2
2
輸出樣例:
在這里給出相應(yīng)的輸出。例如:
8 10
解題思路:實(shí)際上這道題用三元組寫輕松解決,但是這里想講的是十字鏈表;
十字鏈表的圖大致如下:
那么如何去實(shí)現(xiàn)呢;
看以下代碼:因?yàn)橄旅娑加凶⑨專@里便不贅述了。
1 #include<iostream>
2 #include<stdio.h>
3 using namespace std;
4
5 struct OLNod{
6 int i ; //該非零元的行下標(biāo);
7 int j ; //該非零元 的列下標(biāo);
8 int value ; //該非零元的數(shù)值;
9 struct OLNod *right ,*down ;//該非零元所在的行表和列表的后繼鏈域;
10 };
11 struct CrossL{
12 OLNod **rhead, **sead;
13 //十字鏈表的行頭指針和列頭指針; 定義為指向指針的指針;
14 int row; //稀疏矩陣的行數(shù);
15 int col; //稀疏矩陣的列數(shù);
16 int num; //稀疏矩陣的非零個(gè)數(shù);
17 };
18
19 int InitSMatrix(CrossL *M) //初始化M(CrossL)類型的變量必須初始化;
20 {
21 (*M).rhead = (*M).sead = NULL;
22 (*M).row = (*M).col = (*M).num = 0;
23 return 1;
24 }
25
26 int DestroysMatrix(CrossL *M) //銷毀稀疏矩陣M;
27 {
28 int i ;
29 OLNod *p,*q;
30 for( i = 1 ; i <= (*M).row;i++)
31 {
32 p = *((*M).rhead+i); //p指針不斷向右移;
33 while(p!=NULL)
34 {
35 q = p ;
36 p = p ->right;
37 delete q; //刪除q;
38 }
39 }
40 delete((*M).rhead); //釋放行指針空間;
41 delete((*M).sead); //釋放列指針空間;
42 (*M).rhead = (*M).sead = NULL; //并將行、列頭指針置為空;
43 (*M).num = (*M).row = (*M).col = 0; //將非零元素,行數(shù)和列數(shù)置為0;
44 return 1;
45 }
46 int CreatSMatrix(CrossL *M)
47 {
48 int i , j , m , n , t;
49 int value;
50 OLNod *p,*q;
51 if((*M).rhead!=NULL)
52 DestroysMatrix(M);
53 cin>>m>>n>>t; //輸入稀疏矩陣的行數(shù)、列數(shù)和非零元個(gè)數(shù);
54 (*M).row = m;
55 (*M).col = n ;
56 (*M).num = t;
57 //初始化行鏈表頭;
58 (*M).rhead = new OLNod*[m+1];//為行頭指針申請(qǐng)一個(gè)空間;
59 if(!(*M).rhead) //如果申請(qǐng)不成功,則退出程序;
60 exit(0);
61 //初始化列鏈表頭;
62 (*M).sead = new OLNod*[n+1];//為列表頭申請(qǐng)一個(gè)空間;
63 if(!(*M).sead) //如果申請(qǐng)不成功,則退出程序;
64 exit(0);
65 for(int k = 1 ; k <= m ; k++)
66 {
67 (*M).rhead[k] = NULL;//初始化行頭指針向量;各行鏈表為空鏈表;
68 }
69 for(int k = 1 ; k <= n ;k++)
70 {
71 (*M).sead[k] = NULL;//初始化列頭指針向量;各列鏈表為空鏈表;
72 }
73 for(int k = 0 ; k < t ;k++) //輸入非零元素的信息;
74 {
75 cin>>i>>j>>value;//輸入非零元的行、列、數(shù)值;
76 p = new OLNod();//為p指針申請(qǐng)一個(gè)空間;
77 if(!p) //e如果申請(qǐng)不成功;
78 exit(0); //退出程序;
79 p->i = i;
80 p->j = j;
81 p->value = value;
82 if((*M).rhead[i]==NULL) //如果行頭指針指向的為空;
83 {
84 //p插在該行的第一個(gè)結(jié)點(diǎn)處;
85 p->right = (*M).rhead[i];
86 (*M).rhead[i] = p;
87 }else //如果不指向空
88 {
89 for(q = (*M).rhead[i];q->right; q = q->right);
90 p->right = q->right;
91 q->right = p;
92
93 }
94 if((*M).sead[j]==NULL)//如果列頭指針指向的為空;
95 {
96 //p插在該行的第一個(gè)結(jié)點(diǎn)處;
97 p->down = (*M).sead[j];
98 (*M).sead[j] = p;
99 }else//如果不指向空
100 {
101 for(q = (*M).sead[j];q->down;q = q->down);
102 p->down = q->down;
103 q->down = p;
104 }
105 }
106 return 1;
107 }
108 int PrintSMatrix(CrossL *M)
109 {
110 int flag = 0;
111 int val ;//要查找的元素的值;
112 cin>>val; //輸入要查找的s值;
113 OLNod *p;
114 for(int i = 1 ; i <= (*M).row ;i++)
115 {
116 for(p = (*M).rhead[i];p;p = p->right) //從行頭指針開始找,不斷向右找
117 {
118 if(p->value==val) //如果能找到
119 {
120 cout<<p->i<<" "<<p->j; //輸出行下標(biāo)和列下標(biāo)
121 flag = 1; //標(biāo)記找到該元素;
122 }
123 }
124 }
125
126
127 if(flag==0) //如果找不到
128 {
129 cout<<"ERROR
";
130 }
131
132 }
133 int main()
134 {
135 CrossL A; //定義一個(gè)十字鏈表;
136 InitSMatrix(&A); //初始化;
137 CreatSMatrix(&A); //創(chuàng)建;
138 PrintSMatrix(&A); //輸出;
139 DestroysMatrix(&A); //銷毀;
140 return 0;
141 }
總結(jié)
以上是生活随笔為你收集整理的(原创)数据结构之十字链表总结的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: kprobe原理解析
- 下一篇: 矩阵乘法及简易公式推导