• (原创)数据结构之十字链表总结


    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 "; 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 }

  • 相关阅读:
    jvm09
    jvm08
    jvm07
    求解最长公共子序列问题
    归并排序
    求解N皇后问题
    快速排序算法
    求解0/1背包问题
    求解全排列问题
    求解最大连续子序列和问题
  • 原文地址:https://www.cnblogs.com/yewanting/p/10706509.html
Copyright © 2020-2023  润新知