(原創)數據結構之十字鏈表總結


7-1 稀疏矩陣 (30 分)
 

如果一個矩陣中,0元素占據了矩陣的大部分,那么這個矩陣稱為“稀疏矩陣”。對於稀疏矩陣,傳統的二維數組存儲方式,會使用大量的內存來存儲0,從而浪費大量內存。為此,可以用三元組的方式來存放一個稀疏矩陣。

對於一個給定的稀疏矩陣,設第r行、第c列值為v,且v不等於0,則這個值可以表示為 <r,v,c>。這個表示方法就稱為三元組。那么,對於一個包含N個非零元素的稀疏矩陣,就可以用一個由N個三元組組成的表來存儲了。

如:{<1, 1, 9>, <2, 3, 5>, <10, 20, 3>}就表示這樣一個矩陣A:A[1,1]=9,A[2,3]=5,A[10,20]=3。其余元素為0。

要求查找某個非零數據是否在稀疏矩陣中,如果存在則輸出其所在的行列號,不存在則輸出ERROR。

輸入格式:

共有N+2行輸入: 第一行是三個整數m, n, N(N<=500),分別表示稀疏矩陣的行數、列數和矩陣中非零元素的個數,數據之間用空格間隔; 隨后N行,輸入稀疏矩陣的非零元素所在的行、列號和非零元素的值; 最后一行輸入要查詢的非0數據k。

輸出格式:

如果存在則輸出其行列號,不存在則輸出ERROR。

輸入樣例:

在這里給出一組輸入。例如:

10 29 3
2 18 -10
7 1 98
8 10 2
2

輸出樣例:

在這里給出相應的輸出。例如:

8 10

解題思路:實際上這道題用三元組寫輕松解決,但是這里想講的是十字鏈表;
十字鏈表的圖大致如下:

 

那么如何去實現呢;
看以下代碼:因為下面都有注釋,這里便不贅述了。
  1 #include<iostream>
  2 #include<stdio.h>
  3 using namespace std;
  4 
  5 struct OLNod{
  6     int i ;   //該非零元的行下標; 
  7     int j ;   //該非零元 的列下標; 
  8     int value ;   //該非零元的數值;
  9     struct OLNod *right ,*down ;//該非零元所在的行表和列表的后繼鏈域; 
 10 };
 11 struct CrossL{
 12     OLNod **rhead, **sead; 
 13        //十字鏈表的行頭指針和列頭指針; 定義為指向指針的指針;
 14     int row;     //稀疏矩陣的行數; 
 15     int col;     //稀疏矩陣的列數; 
 16     int num;     //稀疏矩陣的非零個數; 
 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;   //將非零元素,行數和列數置為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;  //輸入稀疏矩陣的行數、列數和非零元個數; 
 54     (*M).row = m; 
 55     (*M).col = n ;
 56     (*M).num = t;
 57     //初始化行鏈表頭; 
 58     (*M).rhead = new  OLNod*[m+1];//為行頭指針申請一個空間; 
 59     if(!(*M).rhead)    //如果申請不成功,則退出程序;
 60        exit(0);
 61     //初始化列鏈表頭;
 62     (*M).sead = new OLNod*[n+1];//為列表頭申請一個空間;
 63     if(!(*M).sead)    //如果申請不成功,則退出程序;
 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;//輸入非零元的行、列、數值; 
 76      p =  new OLNod();//為p指針申請一個空間;
 77      if(!p)    //e如果申請不成功;
 78        exit(0);  //退出程序;
 79       p->i = i;
 80       p->j = j;
 81       p->value = value;
 82       if((*M).rhead[i]==NULL)   //如果行頭指針指向的為空;
 83       {
 84           //p插在該行的第一個結點處;
 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插在該行的第一個結點處;
 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;  //輸出行下標和列下標
121                 flag = 1;   //標記找到該元素;
122             }
123         }
124     }
125     
126     
127     if(flag==0)    //如果找不到
128 { 129 cout<<"ERROR\n"; 130 } 131 132 } 133 int main() 134 { 135 CrossL A; //定義一個十字鏈表; 136 InitSMatrix(&A); //初始化; 137 CreatSMatrix(&A); //創建; 138 PrintSMatrix(&A); //輸出; 139 DestroysMatrix(&A); //銷毀; 140 return 0; 141 }

 



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM