第五章(4)十字链表

提醒一句哦:从上一节开始,我用了C++编译器(因为此时刚好学了C++,尝一下鲜),所以在往函数中传递数据时,用了引用,而没有用指针。不过说真心话,这引用比指针真的真的方便了许多许多啊!!!强烈建议大家使用引用,我嘛,看心情,想用哪个就用哪个!呵呵……

 

//当矩阵的非零元个数和位置在操作过程中变化较大时,就不宜采用顺序存储结构来表示三元组的线性表
//每个非零元可用一个含5个域的结点表示,其中除了row,col,e外,向右域right用以链接同一行的下一个非零元,向下域down用以链接同一列中下一个非零元
//同一行的非零元通过right域链接成一个线性表,同一列的非零元通过down域链接成一个线性表
#include < stdio.h >
#include < stdlib.h >

#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
#define UNDERFLOW -3

#define SIZE 10


typedef int Status;     
typedef int ElemType ;

typedef struct Triple
{
 int row , col ;       //非零元素的行下标和列下标
 ElemType e ;
 struct Triple *right , *down ;  //该非零元所在行表和列表的后继链域
} Triple , *TripleLink ;

typedef struct
{
 TripleLink *rhead , *chead ;    //行和列链表头指针向量基址,由CreateSMatrix分配。rhead 为行链表头指针,chead为列链表头指针
 int  mu , nu , tu ;             //此处是矩阵的行数(mu)、列数(nu)而不是三元组的行数和列数 . 非零元个数(tu)
} SMatrixList ;


//------------------------------------------Function!-------------------------------------------------//
Status CreateSMatrix( SMatrixList &M )
{   
 int i , row , col , e ;
 TripleLink p , q ;   //"TripleLink *p" is wrong !  TripleLink p 等效于 Triple *p , 为一个结点指针!
 
 // if( M )
 //  free( M );   //结构体元素不能这样释放!
 
 printf( "please input the rows , cols and numbers:" ) ;
 scanf( "%d %d %d" , &M.mu , &M.nu , &M.tu ) ;
 
 while( M.mu <= 0 || M.nu <= 0 || M.tu <= 0 || M.tu > M.mu * M.nu )
 {
  printf( "please input the rows , cols and numbers once again:" ) ;
  scanf( "%d %d %d" , &M.mu , &M.nu , &M.tu ) ;
 }
 
 if( !( M.rhead = ( TripleLink * )malloc( ( M.mu + 1 ) * sizeof( Triple ) ) ) )      //M.rhead[0]不用
  exit( OVERFLOW );
 if( !( M.chead = ( TripleLink * )malloc( ( M.nu + 1 ) * sizeof( Triple ) ) ) )  //M.chead[0]不用
  exit( OVERFLOW );
 
 for( i = 1 ; i <= M.mu ; ++ i )
 {
  M.rhead[ i ] = NULL ;  //初始化行头指针向量,各行链表为空链表
 }
 for( i = 1 ; i <= M.nu ; ++ i )
 {
  M.chead[ i ] = NULL ;  //初始化列头指针向量,各列链表为空链表
 }
 
 printf( "please input the element's row , col and data:" ) ;         //请按任意次序输入非零元
 for( i = 1 ; i <= M.tu ; i ++ )               //双for循环输入虽然整体简洁,但是下面的方法输入工作较少
 {   
  //scanf( "%d %d %d" , &M.data[ i ].row , &M.data[ i ].col , &M.data[ i ].e ) ;
  scanf( "%d %d %d" , &row , &col , &e ) ;    //结点为动态生成的,数组定义了后就有空间,而链表定义了后只有头指针的空间
  if( ( row <= 0 ) || ( col <= 0 ) )
  {
            printf( "input wrong ! please input again !" ) ;
            scanf( "%d %d %d" , &row , &col , &e ) ;
  } 
  
  if( !( p = ( TripleLink )malloc( sizeof( Triple ) ) ) )
   exit( OVERFLOW ) ;
  
  p->row = row ;   //生成结点
  p->col = col ;
  p->e = e ;
  
  //  弄清一个概念! M.rhead 为(TripleLink *)类型,而M.rhead[i]为(TripleLink)类型!而这里M.rhead[i]仍为指向Triple 的指针 (Triple == * TripleLink)
  
  if( M.rhead[ row ] == NULL || M.rhead[ row ]->col > col )   // p插在该行的第一个结点处
  {   //M.rhead[ row ] == NULL表示该行链为空链,M.rhead[ row ]->col > col表示该行链头结点存在且其列大于p的列
   p->right = M.rhead[ row ] ;        //将p插入到该row行链表的最后
   M.rhead[ row ] = p ;
  }
  else  //查找在行表中的插入位置
  {
   for( q = M.rhead[ row ] ; ( q->right ) && ( q->right->col < col ) ; q = q->right ) ;// ( q->right->col < col ) 按升序插入
   p->right = q->right ;
   q->right = p ;
  }  //完成行插入
  
  if( M.chead[ col ] == NULL || M.chead[ col ]->row > row )   // p插在该列的第一个结点处
  {
   p->down = M.chead[ col ] ;
   M.chead[ col ] = p ;
  }
  else  //查找在列表中的插入位置
  {
   for( q = M.chead[ col ] ; ( q->down ) && ( q->down->row < row ) ; q = q->down ) ;    
   p->down = q->down ;
   q->down = p ;
  }        //完成列插入
 }for i
 return OK ;
}///CreateSMatrix

Status DestorySMatrix( SMatrixList &M )
{
 int i ;
 TripleLink p , q ;   //p 为中转结点, q 为释放结点
 
 for( i = 1 ; i <= M.mu ; ++ i )  // 按行释放结点 ,也可以按列释放结点
 {
  p =  M.rhead[ i ] ;  //TripleLink p , 而 TripleLink * rhead .  M.rhead[ i ] = * ( M.rhead + i ).
  while( p )
  {
   q = p ;
   p = p->right ;
   free( q ) ;
  }  //释放当前行的所有元素
 }
 
 free( M.rhead ) ;   //释放行和列链表头指针
 free( M.chead ) ;
 
 M.rhead = M.chead = NULL ;
 M.mu = M.nu = M.tu = 0 ;
 
 return OK ;
}

Status PrintSMatrix( SMatrixList M )
{
 int i ;
 TripleLink p ;
 
 printf( "%d 行 %d 列 %d 个非零元素\n" , M.mu , M.nu , M.tu ) ;
 printf( "The SMatrix :\n" ) ;
 printf( "row , col , element\n" ) ;
 
 for( i = 1 ; i <= M.mu ; ++ i )   // 按行打印结点 ,也可以按列打印结点
 {
  p = M.rhead[ i ] ;
  while( p )
  {
   printf( "%3d %5d %6d\n" , p->row , p->col , p->e ) ;
   p = p->right ;
  }
 }
 
 printf( "\n" ) ;
 
 return OK ;
}

Status CopySMatrix( SMatrixList M , SMatrixList &N )
{
 int i ;
 TripleLink p , q , qa , qb ;
 
 N.mu = M.mu ;
 N.nu = M.nu ;
 N.tu = M.tu ;
 
 if( !( N.rhead = ( TripleLink * )malloc( ( N.mu + 1 ) * sizeof( Triple ) ) ) )      //N.rhead[0]不用,N.rhead[i]的row,col,e也不用,只需要right、down
  exit( OVERFLOW );
 if( !( N.chead = ( TripleLink * )malloc( ( N.nu + 1 ) * sizeof( Triple ) ) ) )  //N.chead[0]不用,N.rhead[i]的row,col,e也不用,只需要right、down
  exit( OVERFLOW );
 
 for( i = 1 ; i <= N.mu ; ++ i )
 {
  N.rhead[ i ] = NULL ;  //初始化行头指针向量,各行链表为空链表
 }
 for( i = 1 ; i <= N.nu ; ++ i )
 {
  N.chead[ i ] = NULL ;  //初始化列头指针向量,各列链表为空链表
 }
 
 for( i = 1 ; i <= M.mu ; ++ i )  //按行复制
 {
  p = M.rhead[ i ] ;  //p为该行的头指针
  while( p )    //当前行还存在元素
  {
   q = ( TripleLink )malloc( sizeof( Triple ) ) ;  //生成结点
   if( !q )
   {
    exit( OVERFLOW );
   }
   
   q->row = p->row ;   //复制
   q->col = p->col ;
   q->e = p->e ;
   
   if( !N.rhead[ i ] )   //插入行表头(头结点为空)
   {
    N.rhead[ i ] = qa = q ;  //N.rhead[ i ] = qa = q
    // qa = q ;
   }
   else      //插入行表尾
   {
    qa = qa->right = q ; //qa->right = q ; qa = qa->right ;
   }
   
   if( !N.chead[ q->col ] ) //插在列表头(N.chead[ q->col ]为q的列所在列的列链头指针)
   {
    N.chead[ q->col ] = q ;
    q->down = NULL ;
   }
   else      //插入列表尾
   {
    qb = N.chead[ q->col ] ;
    while( qb->down )  //找到所在列的最后一个元素
    {
     qb = qb->down ;
    }
    
    qb->down = q ;
    q->down = NULL ;
   }
   
   p = p->right ;   //转而复制该行的下一个结点
  } while p
  
  q->right = NULL ;      //该行复制完了
 } ///for i
 return OK ;
}

Status AddSMatrix( SMatrixList M , SMatrixList N , SMatrixList &Q )  //Q = M + N ,another is M += N ; //时间复杂度为O( M.tn + N.tu )
{   //为了便于插入和删除,还需设置辅助指针:在每一列的链表上设一个指针hl[i],其初值和列链表的头指针相同,即hl[i] = chead[i]
 int k ;
 TripleLink p , pa , pb , q ;   //pa,pb分别指向A和B的行值相同的两个非零元的结点(指针引用'->',非指针引用'.'。一般情况下,指针方便一些)
 TripleLink * hl ; 
 
 if( M.mu != N.mu && M.nu != N.nu )
 {
  return ERROR ;
 }
 
 //-------------- 初始化Q矩阵---------------//
 Q.mu = M.mu ;     
    Q.nu = M.nu ;
    Q.tu = 0 ;
 Q.rhead = ( TripleLink * )malloc( ( Q.mu + 1 ) * sizeof( Triple ) ) ;
 if( !Q.rhead )
 {
  exit( OVERFLOW ) ;
 }
 Q.chead = ( TripleLink * )malloc( ( Q.nu + 1 ) * sizeof( Triple ) ) ;
 if( !Q.chead )
 {
  exit( OVERFLOW ) ;
 }
 
 for( k = 1 ; k <= Q.mu ; k ++ )   // 初始化Q的行头指针向量;各行链表为空链表
 {
  Q.rhead[ k ] = NULL ;
 }
 for( k = 1 ; k <= Q.nu ; k ++ )
 {
  Q.chead[ k ] = NULL ;
 }
 
 //-------------辅助指针-----------------//
 hl = ( TripleLink * )malloc( ( Q.nu + 1 ) * sizeof( Triple ) );  // 生成指向列的最后结点的数组
 if( !hl )
 {
  exit( OVERFLOW ) ;
 }
 for( k = 1 ; k <= Q.nu ; ++ k )   //初始化
 {
  hl[ k ] = NULL ;
 }
 
 //------------Begin Add!----------------//
 for( k = 1 ; k <= M.mu ; ++ k )  //按行序相加
 {
  pa = M.rhead[ k ] ;    //指向矩阵M的第i行的第一个结点(头结点)
  pb = N.rhead[ k ] ;
  
  while( pa && pb )     //pa 与 pb 均存在时
  {
   if( pa->col > pb->col )  //矩阵M当前结点的列大于矩阵N当前结点的列
   {
    p = ( TripleLink )malloc( sizeof( Triple ) ) ;
    if( !p )
    {
     exit( OVERFLOW ) ;
    }
    ++ Q.tu ;
    p->row = k ;
    p->col = pb->col ;
    p->e = pb->e ;    //减法时,此处为 p->e = - (pb->e)
    p->right = NULL ;
    pb = pb->right ;     //pb指针向右移
   }
   else
   {
    if( pa->col < pb->col )  //矩阵M当前结点的列小于矩阵N当前结点的列
    {
     p = ( TripleLink )malloc( sizeof( Triple ) ) ;
     if( !p )
     {
      exit( OVERFLOW ) ;
     }
     ++ Q.tu ;
     p->row = k ;
     p->col = pa->col ;
     p->e = pa->e ;
     p->right = NULL ;
     pa = pa->right ;  //pa指针向右移
    }
    else
    {
     if( ( pa->e + pb->e ) )     //(pa-col == pb->col) and (pa->e + pb->e) != 0
     {
      p = ( TripleLink )malloc( sizeof( Triple ) ) ;
      if( !p )
      {
       exit( OVERFLOW ) ;
      }
      ++ Q.tu ;
      p->row = k ;
      p->col = pa->col ;
      p->e = pa->e + pb->e ;       //减法时,此处为 p->e = (pa->e) - (pb->e)
      p->right = NULL ;
      pa = pa->right ;
      pb = pb->right ;
     }
     else   //(pa-col == pb->col) and (pa->e + pb->e) == 0
     {
      pa = pa->right ;   //nothing else
      pb = pb->right ;
     }   //for : if( ( pa->e + pb->e ) ) ,  else
    }  //for : if( pa->col < pb->col ) , else
   }   //for : if( pa->col > pb->col ) , else
   
   
   if( Q.rhead[ k ] == NULL )  //p 为该行第一个结点
   {
    Q.rhead[ k ] = q = p ;  // p插在该行的表头且q指向p(该行的最后一个结点)
   }
   else   // 插在q所指结点之后
   {
    q->right = p ;
    q = q->right ;
   }
   
   if( Q.chead[ p->col ] == NULL )   //p 为该列第一个结点
   {
    Q.chead[ p->col ] = hl[ p->col ] = p ;
   }
   else   // 插在col[p->col]所指结点之后
   {
    hl[ p->col ]->down = p ;
    hl[ p->col ] = hl[ p->col ]->down ;
   }
   
  }   while
  
  while( pa )   //只有pa存在时,将矩阵M该行的剩余元素插入矩阵Q
  {
   p = ( TripleLink )malloc( sizeof( Triple ) ) ;
   if( !p )
   {
    exit( OVERFLOW ) ;
   }
   ++Q.tu ;
   p->row = k ;
   p->col = pa->col ;
   p->e = pa->e ;
   p->right = NULL ;
   pa = pa->right ;
   
   if( Q.rhead[ k ] == NULL )
   {
    Q.rhead[ k ] = q = p ;
   }
   else
   {
    q->right = p ;
    q = q->right ;
   }
   
   if( Q.chead[ p->col ] == NULL )
   {
    Q.chead[ p->col ] = hl[ p->col ] = p ;
   }
   else
   {
    hl[ p->col ]->down = p ;
    hl[ p->col ] = hl[ p->col ]->down ;
   }
  } while pa
  
  while( pb )     //只有pb存在时,将矩阵N该行的剩余元素插入矩阵Q
  {
   p = ( TripleLink )malloc( sizeof( Triple ) ) ;
   if( !p )
   {
    exit( OVERFLOW ) ;
   }
   ++Q.tu ;
   p->row = k ;
   p->col = pb->col ;
   p->e = pb->e ;      //减法时,此处为 p->e = (pa->e) - (pb->e)
   p->right = NULL ;
   pb = pb->right ;
   
   if( Q.rhead[ k ] == NULL )
   {
    Q.rhead[ k ] = q = p ;
   }
   else
   {
    q->right = p ;
    q = q->right ;
   }
   
   if( Q.chead[ p->col ] == NULL )
   {
    Q.chead[ p->col ] = hl[ p->col ] = p ;
   }
   else
   {
    hl[ p->col ]->down = p ;
    hl[ p->col ] = hl[ p->col ]->down ;
   }
  } ///while pb  
  
 }   /for
 
 for( k = 1 ; k <= Q.nu ; ++ k )
 {
  if( hl[ k ] ) //k列有结点
  {
   hl[ k ]->down = NULL ;
  }
 }
 free( hl ) ;
 return OK ;
}

Status SubSMatrix( SMatrixList &M , SMatrixList &N , SMatrixList &Q )   //one way is example like 'AddSMatrix'! another way is next!
{    // Q = M + ( -N ) ;
 int i ;
 TripleLink p ;
 
 for( i = 1 ; i <= N.mu ; ++ i )    //按行修改
 {
  p = N.rhead[ i ] ;  //每一行的头指针
  while( p )
  {
   p->e *= -1 ;
   p = p->right ;
  }
 }
 
 AddSMatrix( M , N , Q ) ;
 
 return OK ;
}

Status MultSMatrix( SMatrixList M , SMatrixList N , SMatrixList &Q )
{
 int k , e , row , col ;
 TripleLink q , p , qa , a , b ;
 
 if( M.nu != N.mu )
 {
  return ERROR ;
 }
 
 //--------------Init the SMatrixList of Q ---------------//
 Q.mu = M.mu ;     
    Q.nu = N.nu ;
    Q.tu = 0 ;
 
 Q.rhead = ( TripleLink * )malloc( ( Q.mu + 1 ) * sizeof( Triple ) ) ;
 if( !Q.rhead )
 {
  exit( OVERFLOW ) ;
 }
 Q.chead = ( TripleLink * )malloc( ( Q.nu + 1 ) * sizeof( Triple ) ) ;
 if( !Q.chead )
 {
  exit( OVERFLOW ) ;
 }
 
 for( k = 1 ; k <= Q.mu ; k ++ )   // 初始化Q的行头指针向量;各行链表为空链表
 {
  Q.rhead[ k ] = NULL ;
 }
 for( k = 1 ; k <= Q.nu ; k ++ )
 {
  Q.chead[ k ] = NULL ;
 }
 
 for( row = 1 ; row <= Q.mu ; ++ row )
 {
  for( col = 1 ; col <= Q.nu ; ++ col )
  {
   p = M.rhead[ row ] ;
   q = N.chead[ col ] ;
   e = 0 ;
   
   // -------此部分最好自己画图体验!---------//
   while( p && q )  
   {
    if( p->col < q->row ) //p->col为M的列,q->row为N的行。只在相等情况下相乘
    {
     p = p->right ;  // 列指针后移  哪个小哪个后移
    }
    else
    {
     if( p->col > q->row )
     {
      q = q->down ;
     }
     else  // q->row == p->col ;
     {
      e += p->e * q->e ;
      q = q->down ;
      p = p->right ;
     }
    }
   }/while
   
   if( e )          //e 存在 ,则将其插入Q中
   {
    ++ Q.tu ;
    qa = ( TripleLink )malloc( sizeof( Triple ) );
    if( !qa )
    {
     exit( OVERFLOW ) ;
    }
    
    qa->row = row ;
    qa->col = col ;
    qa->e = e ;
    qa->right = NULL ;
    qa->down = NULL ;
    
    if( !Q.rhead[ row ] )
    {
     Q.rhead[ row ] = a = qa ;
    }
    else
    {
     a = a->right = qa ;
    }
    
    if( !Q.chead[ col ] )
    {
     Q.chead[ col ] = qa ;
    }
    else
    {
     b = Q.chead[ col ] ;
     while( b->down )
     {
      b = b->down ;
     }
     b->down = qa ;
    }
    
   }
  }
 }
 return OK ;
}

Status TransposeSMatrix( SMatrixList M , SMatrixList &N )
{
 int i , row , nu ;   //设置一些中间量
 TripleLink * head , p , q , r ;
 
 CopySMatrix( M , N ) ;
 
 nu = N.nu ;     //转
 N.nu = N.mu ;
 N.mu = nu ;
 
 head = N.chead ;
 N.chead = N.rhead ;
 N.rhead = head ;
 
 for( i = 1 ; i <= N.mu ; ++ i )  // N.mu == N.nu ;
 {
  p = N.rhead[ i ] ;   //此时N.rhead[ i ] == N.chead[ i ] ;
  while( p )
  {
   q = p->down ;   //q指向下一个结点
   
   row = p->row ;
   p->row = p->col ;
   p->col = row ;
   
   r = p->down ;  //交换.down.和right
   p->down = p->right ;
   p->right = r ;
   
   p = q ;  // p指向下一个结点
  }
 }
 return OK ;
}

//--------------前面的函数只考虑到稀疏矩阵的使用,未考虑做为其他的功能使用!以下的则是为了多方面使用------------------//
Status InsertTriple( SMatrixList &M , TripleLink p  )  //其实前面很多地方用到了插入工作,此函数可以优化前面的代码
{
 int i , k = 0 ;
 int flaga = 0 ;  // flaga == 0  表示未插入元素
 int flagb = 0 ;
 TripleLink q , a ; 
 
 
 if( p->col > M.nu )   //插入元素的列超出矩阵的列
 {
  for( i = M.chead[ M.nu ]->col + 1 ; i <= p->col ; ++ i )
  {
   M.chead[ i ] = ( TripleLink )malloc( sizeof( Triple ) ) ;
   if( !M.chead[ i ] )
   {
    exit( OVERFLOW );
   }
  // M.chead[ i-1 ]->right = M.chead[ i ] ;
   M.chead[ i ] = NULL ;
  }
  M.nu = p->col ;
 }
 if( p->row > M.mu )     //插入元素的列超出矩阵的列
 {
  for( i = M.rhead[ M.mu ]->row + 1 ; i <= p->row ; ++ i )
  {
   M.rhead[ i ] = ( TripleLink )malloc( sizeof( Triple ) ) ;
   if( !M.rhead[ i ] )
   {
    exit( OVERFLOW );
   }
  // M.rhead[ i - 1 ]->down = M.rhead[ i ] ;
   M.rhead[ i ] = NULL ;
  }
  M.mu = p->row ;
 }
 

// ++ M.tu ;  不能在这地方自加,因为插入元素的位置可能和原有元素重叠
    
 q = M.rhead[ p->row ] ;     //行链插入
 //(插入元素的对应位原本不存在元素,所以不存在q->col == p->col)
 
 if( !q || p->col < q->col )   //  链首
 {
  if( !q )  // !q :当前行不存在.
  {
   M.rhead[ p->row ]  = p ;    //q = p ; q->right =NULL ;不可,因为头结点实质没有变
   M.rhead[ p->row ]->right = NULL ;
   ++ k ;
  }
  else   //p->col < q->col :位置在头结点之前。
  {
   p->right = M.rhead[ p->row ] ;
   M.rhead[ p->row ] = p ;
   ++ k ;
  }
 }
 else
 {
  if( q->right && ( flaga == 0 ) )   //链中   
  {
   while( q->right )  //找到其对应的列,元素插入到非头结点位置  //( q->col < p->col )
   {
    if( q->col < p->col && q->right->col > p->col ) //定位插入的位置
    {
     p->right = q->right ;
     q->right = p ;
     flaga = 1 ; //主要是为了方便跳出if语句
     ++ k ;
     break ;  //插入完了就跳出while循环
    }
    q = q->right ;
   } while
  }
  else          //链尾
  {   
   q->right = p ;
   p->right = NULL ;
   ++ k ;
  }
 }
 
 a = M.chead[ p->col ] ;    //列链插入
 if( !a || p->row < a->row )
 {
  if( !a )
  {
   M.chead[ p->col ] = p ;
   M.chead[ p->col ]->down = NULL ;
   flagb = 1 ;    //对上面的优化
  }
  else
  {
   p->down = M.chead[ p->col ] ;
   M.chead[ p->col ] = p ;
   flagb = 1 ;
  }
 }
 else
 {
  while( a->down && ( flagb == 0 ) )   //对上面的优化 
  {
   if( a->row < p->row && a->down->row > p->row )
   {
    p->down = a->down ;
    a->down = p ;
    flagb = 1 ;
    break ;
   }
   a = a->down ;
  }
  
  if( flagb == 0 )
  {
   a->down = p ;
   p->down = NULL ;
  }
 }

 if( k != 0 )
 {
  ++ M.tu ;
 }
 else
 {
  printf( "The location is already exist a element !\n" ) ;
 }

 return OK ;
}

Status DeletetTriple( SMatrixList &M , TripleLink p )
{
 int i = 1 ;
 TripleLink q , b ;
 
 if( p->col > M.nu || p->row > M.mu )
 {
  printf( "There is't exist!\n" ) ;
  return ERROR ;
 }
 
 q = M.rhead[ p->row ] ;    //按行查找
 if( p->col < q->col )   //在头结点之前
 {
  printf( "There is't exist!\n" ) ;
  return ERROR ;
 }

 while( ( q->col != p->col ) && q->right )  //找列相等
 {
  b = q->right ;
  q = b ;
 }
 if( p->col == q->col )      // 行列相等
 {
  if( p->e != q->e )   // 行列相等,但是值不相等
  {
   printf( "There is't exist!\n" ) ;
   return ERROR ;
  }
  else      // 行列相等,且值相等,则进行删除操作 ( p == b )
  {
   if( q == M.rhead[ p->row ] )   //如果b为当前行的头结点
   { 
    b = M.rhead[ p->row ]->right ;   
    M.rhead[ p->row ] = b ;
    -- i ;
   }
   else   //非头结点
   {
    b = q->right ;
    q = b ;
    -- i ;
   }
  } //行列值相等
 } // 行列相等

 if( i == 0 )
 {
  -- M.tu ;
 }
 else
 {
  printf( "There is't exist!\n" ) ;
  return ERROR ;
 }
 
 return OK ;
}

Status LocateTriple( SMatrixList M , int e )  //可能有多个相同的数
{
 int i ,  c = 0  ;   //c统计与e相等元素的个数
 
 int row[ 9 ] , col[ 9 ] ;  // why row[ M.tu +1 ] , col[ M.tu + 1 ] can not ?   expected constant expression! 需要一个常量
 //  int row[ SIZE ] , col[ SIZE ] ;
 TripleLink p , q ;
 
 for( i = 1 ; i <= M.mu ; ++ i )
 {
  q = p = M.rhead[ i ] ;
  while( p->right && ( p->e != e ) )
  {
   q = p->right ;
   p = q ;
  }
  if( e == q->e )
  {
   ++ c ;
   row[ c ] = p->row ;
   col[ c ] = p->col ;
   // break ;
  }
 }
 
 if( c == 0 )
 {
  printf( "It's wrong or not exit! \n" ) ;
 }
 else
 {
  printf( "The row , col , element:\n" ) ;
  for( i = 1 ; i <= c ; ++ i )
  {
   printf( "%3d %5d %6d\n" , row[ i ] , col[ i ] , e ) ;
  }
 }
 
 return OK ;
}

Status GetTriple( SMatrixList M , int row , int col )
{
 TripleLink p ;  
 int e ;
 
 // p->row = row ;  //等效于Triple p ; p.row ;
 // p->col = col ;
 if( row > M.mu || col >M.nu )
 {
  printf( "It's out the Link!\n" );
  return ERROR ;
 }
 
 p = M.rhead[ row ] ; //指向第row行的头指针
 
 if( col < p->col )  //在当前行的一个元素的前面
 {
  e = 0 ;
 }
 while( p && ( p->col < col ) )  
 {
  p = p->right ;
 }
 if( p->col == col )   //行列值相等
 {
  e = p->e ;
 }
 else
 {
  e = 0 ;
 }
 
 printf( "The row , col , element:\n" ) ;
 printf( "%3d %5d %6d\n" , row , col , e ) ;
 
 return OK ;
}

//注意一下,注释量要适中!
//---------------------------------------------Main Function!------------------------------------//
int main( )
{
 SMatrixList M , N , Q , X ;
 TripleLink p ;
 
 p = ( TripleLink )malloc( sizeof( Triple ) ) ; 
 p->row = 4 ; p->col = 3 ; p->e = 6 ;
 
 CreateSMatrix( M ) ;
 PrintSMatrix( M ) ;
 
 InsertTriple( M ,  p ) ;
 PrintSMatrix( M ) ;

 DeletetTriple( M , p ) ;
 PrintSMatrix( M ) ;
 
 // LocateTriple( M , 2 ) ;
 
 // GetTriple( M , 3 , 3 ) ;
 
 // CopySMatrix( M , N ) ;
 // PrintSMatrix( N ) ;
 
 // AddSMatrix( M , N , Q ) ;
 // PrintSMatrix( Q ) ;
 
 // SubSMatrix( Q, N , X ) ;
 // PrintSMatrix( X ) ;
 
 // MultSMatrix( M , N , Q ) ;
 // PrintSMatrix( Q ) ;   
 
 // TransposeSMatrix( M , X ) ;
 // PrintSMatrix( X ) ;
 return 0 ;
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值