串 & 数组和广义表

理论基础

 

  串的存储方式 :

  定长存储方式 : 用一维数组存储, 后边加 ' \0 ' .  \0 表示终结

  堆分配存储 : typedef struct {

                            char * ch ;

                            int length ;

                          } HString ;

  堆分配方式更灵活.

  串的块链式存储表示 : 没有另外两种存储方法灵活 ( 定长存储 , 堆分配 ).

  KMP 算法 ( 模式匹配 )

  串的模式匹配是指,指定主串,子串。找到主串中子串的匹配情况。Index( S,T,pos ) , 其中pos指在主串中开始匹配的位置。

  普通的匹配算法是由主串和模式串中的字符依次递增比对。当出现不同时,从主串的刚刚比对的第一个位置+1,再进行匹配。

  这样就有个问题,当主串是 '0000000000000000000001' , 模式串是 '00000001' ,此时,每次都是比对了很多次之后发现不匹配,再 主串指针向后一位,

  仍然要移动很多次后,才发现不匹配。每次都是到模式串的最后一位。效率很低。

  串动态分配常用操作 : 如下 :

 

/* The basic operate , string
** Author : Kevin
** Date   : 2012/02/28
*/

#include"stdio.h"
#include"alloc.h"
#include"stdlib.h"


/*堆存储方式*/
typedef struct{
    char *ch;               /*assign memory*/
    int length ;    
}HString ;

/*创建字符串*/
int StrAssign( HString *t, char *chars ){
    int i ;
    char *c;
    for(i=0,c=chars; *c!='\0'; ++i,++c);   /*求字符串的长度,即 i 值*/
    t->ch = (char*)malloc(i*sizeof(char));
    t->length = i;
    c = chars;
    for(i=0; i<t->length; i++){
        /*t.ch[i] = c[i];*/
        *(t->ch+i) = *(c+i);                /* 这种方式和以上的注释的方式都可以*/
        printf("%c",t->ch[i]);
    }
    return 1;   
                    
}

/*返回字符串长度*/
int StrLength( HString t ){
    return t.length ;
}

/*比较两个字符串*/
int StrCompare(HString t, HString s){
    int i=0;
    while(i<t.length && i<s.length){
        if(t.ch[i]==s.ch[i]){
            
        }else if(t.ch[i]<s.ch[i]){
            return -1;
        }else{
            return 1;
        }
        i++;
    }       
  if(t.length == s.length){
    return 0;
  }else if(t.length < s.length){
    return -1;
  }else{
    return 1;
  }
 
}
/*清空字符串,类似初始化*/
int ClearString(HString *t){
    int i ;
    for(i=0; i<t->length; i++){
        *(t->ch+i) = '';
    }
    return 1;
}

/*连接两个字符穿*/
int Concat(HString *t, HString s1, HString s2){
    int i ;
    int length ;
    int j ;
    length = s1.length + s2.length ;
    t->ch = (char*)malloc(length*sizeof(char));
    for(i=0; i<s1.length; i++)
        *(t->ch+i) = *(s1.ch+i);

    for(i=s1.length,j=0;i<s2.length+s1.length; i++,j++)
        *(t->ch+i) = *(s2.ch+j);
    t->length = s1.length + s2.length ;
    return 1;
}
/*求子串*/
int SubString(HString t, HString *s, int pos, int len){

    int i ;

    s->ch = (char*)malloc(len*sizeof(char));
    for(i=0; i<len; i++){
        *(s->ch+i) = *(t.ch+pos+i);
    }
    s->length = len;
    return 1;
}
/*复制字符串*/
int StrCopy(HString t, HString *s){
    int i;
    s->ch = (char*)malloc(t.length*sizeof(char));
    for(i=0; i<t.length; i++)
        *(s->ch+i) = *(t.ch+i);
    s->length = t.length;
    return 1;
}   

/*指定位置插入字符串*/
int StrInsert(HString *t, int pos, HString s){
    
    int i,j ;

    t->ch = (char*)realloc(t->ch,(t->length+s.length)*sizeof(char));

    for(i=t->length-1; i>=pos; i--){
        *(t->ch+(s.length+i)) = *(t->ch+i);
    }

    for(j=0; j<s.length; i++,j++){
        *(t->ch+pos+j) = *(s.ch+j);
    }
    t->length = t->length+s.length;

    return 1;
}
/*指定位置删除字符串,指定删除长度问题*/
int StrDelete(HString *t, int pos, int len){
    int i = 0;
    int length = t->length - len ;
    
    for(i=pos; i<t->length-len; i++){
        *(t->ch+i) = *(t->ch+i+len);
        printf("%d",i);
    }

    
    t->length = t->length-len;


}
/*销毁字符串*/
void StrDestory(HString *t){

    free(t);

}


  KMP 算法:



/* 初始化NEXT函数 */
void InitNext(HString s, int *pn){
    int i, j;
    pn[1] = 0;                              /*NEXT[0] = 0 , pn[0] ¼´ NEXT[0]²»´æÔÚ*/
    pn[2] = 1;                              /*NEXT[1] = 1*/
    
    for(i=2; i<=s.length; i++){
        j = i ;
        do{
            if(*(s.ch+(i-1)) == *(s.ch+(pn[j]-1)))  {
                pn[i+1] = pn[j]+1;
                break ;
            }
            else{
                j = pn[j];
            }

        }while(j != 1);
                
        if(j == 1){
            pn[i+1] = 1;
        }
        
    }
            
}

/*求 NEXT 值*/
int Nextj(int *p, int j){
    return *(p+j);      
}

/* KMP 算法*/
int KmpString(HString *ps, HString *pm , int pos , int *p){
    int i;
    int j;
    i = pos;
    j = 1;
    while(i<ps->length && j< pm->length){
        if(*(ps->ch+i) == *(pm->ch+j) || j==0){
            i++;
            j++;
        }
        else{
            j = Nextj(p , j);
        }

    }
    if(j>=pm->length)
        return i-pm->length;
    else
        return 0;
}


int main()
{
    char *c = "abaabaf";
    char *mc = "abcdababcddabaabafaass";
    int next[7];
    int i ;
    int kmp_status ;
    int sta, stb ;
    HString smodel,smain ;
    sta = StrAssign(&smodel,c);
    stb = StrAssign(&smain,mc);
    if(sta){
        printf("model is assigned \n");
        printf("The model length %d\n",smodel.length);
    }else{
        printf("model assign error\n");
        return 0;
    }
    if(stb){

        printf("main string is assigned \n");
        printf("The String length %d\n",smain.length);
    }else{
        printf("main string assign error\n");
        return 0;
    }
    InitNext(smodel,next);
    /*
    for(i=0;i<=7;i++)
        printf("%d,",next[i]);

    */
    printf("\n");
    kmp_status = KmpString(&smain, &smodel, 1, next);
    if(kmp_status)
        printf("It is ok , The Location is %d",kmp_status);
    else
        printf("This is not matched , sorry ^_^");


    getchar();
    
}


数组

  typedef ElemType Array2[ m ][ n ] 等价于

  typedef ElemType Array1[ n ] ;

  typedef   Array1        Array2[ n ] ;

  将数组的定义拆开 , 定义2维数组时 , 可以如上想象 , 同理类推 :

  数组使用顺序存储 ( 内存分配一整块空间 )

  矩阵的压缩存储 : 为多个值相同的元只分配一个存储空间,对零元不分配存储空间。(一般可以使用全部存储,全部存储,运算方便)

  存储三元表 :( 1,2,12) 横坐标,纵坐标,值

  三元组存储的具体物理实现:

  1。三元组顺序表

        typedef struct {

            int i , j ;         //坐标

            ElemType e ;

        } Triple ;

       typedef struct {

           Triple data[MAXSIZE+1];    //存储实际非0元等等

            int mu,nu,tu;                       //矩阵真正的行列数(包括0元),非0元个数        

        } TSMatrix ;

   非0元顺序存储是以行顺序为主序排列。便于计算,但是,若需按行号存取某一行的非零元,则需从头开始查找。 -->必须是行,不是随便存储的

  2。行逻辑链接顺序表 ( 也是行顺序存储的 , 只是加了一个知道每行第一个非0元的位置 )

    为了便于随机存取任意一行的非零元。则需知道每一行的第一个元素再三元组(数组)中的位置。

       typedef struct {

          Triple data[MAXSIZE+1];        //记录数据和坐标

          int rpos[MAXRC+1] ;               //记录各行第一个非0元的位置,注意此位置是指在 data数组中的序号,而不是此行的列

          int mu , nu , tu ;                       //矩阵的行数,列数,非0元个数

       }RLSMatrix ;

这样,如果想找某一行的第1个非0元,可以查到该 rpos值,找到对应的 data 数组中该值,就找到了该结构体,也就找到了 i, j

  3。十字链表

   当矩阵的非0元个数和位置在操作过程中变化较大时。例如 a= a+b

以上图不是很清楚,应该是在上边和左侧各有个指针数组,chead , rhead 这是两个指针数组

这里的行指针和列指针并不是单一的一个,而是一组,多个。   

    typedef struct OLNode{t

       int i , j ;                       //坐标O

       ElemType e ;             //值

       struct OLNode *right , *down ;        //行,列指针

    }OLNode, *OLink;

     typedef struct {

         OLink *rhead , *chead ;        //行和列链表头指针向量基址由 createSMatrix 创建

         int mu , nu , tu ;

     } CrossList ;

    注意此处的 OLink * rhead *chead ; 此处是OLink本来就是定义指针变量的,所以此处为二级指针,即rhead , chead 指向一个指针,此指针指向OLink类型的指针。

    而且如上图,由于十字链表的行列指针并不是一个,而是一组。所以此两个指针。rhead , chead 正式指向行的一组和列的一组的首地址。

    而 CreateSMatrix中会根据实际数组的行列数而动态分配此行列组指针

    M.rhead = (OLink *) malloc ((mu+1)*sizeof(OLink)) ;

    M.chead = (OLink*) malloc((nu+1)* sizeof(OLink));

   注意:此处的确给每行每列都分配了指针,并且注意sizeof(OLink),为什么要用OLink,因为分配的内存是为了存放指向OLink类型的指针。其实就相当于分配了

   两个指针数组,数组中的指针是指向OLink类型。

 广义表

  定义 : LS = ( α1,α2,α3...,αn)

  其中 α1...αn 即可以是单个元素,也可以自己是一个表。(递归)

 实例推荐

  1.( 练习册 4.8 )

  /* KMP The practice for 4.8
** Author : Kevin
** Date   : 2012/02/29
*/

#include"stdio.h"
#include"stdlib.h"
#include"alloc.h"

/* 堆存储 定义*/
typedef struct{
    char *ch ;
    int length;
}HString ;

/* 字符串初始化 */
int StrAssign( HString *t, char *chars ){
    int i ;
    char *c;
    for(i=0,c=chars; *c!='\0'; ++i,++c);   /* 确认 i 值*/
    t->ch = (char*)malloc(i*sizeof(char));
    t->length = i;
    c = chars;
    for(i=0; i<t->length; i++){
        /*t.ch[i] = c[i];*/
        *(t->ch+i) = *(c+i);                /* 以上注释也可以 */
        printf("%c",t->ch[i]);
    }
    printf("\n");
    return 1;   
                    
}

/* 求长度 */
int StrLength( HString t ){
    return t.length ;
}




/* 初始化 NEXT 值 */
void InitNext(HString s, int *pn){
    int i, j;
    pn[1] = 0;                              /*NEXT[0] = 0 , pn[0] ¼´ NEXT[0]²»´æÔÚ*/
    pn[2] = 1;                              /*NEXT[1] = 1*/
    
    for(i=2; i<=s.length; i++){
        j = i ;
        do{
            if(*(s.ch+(i-1)) == *(s.ch+(pn[j]-1)))  {
                pn[i+1] = pn[j]+1;
                break ;
            }
            else{
                j = pn[j];
            }

        }while(j != 1);
                
        if(j == 1){
            pn[i+1] = 1;
        }
        
    }
            
}

/* 求 下一个Next值 */
int Nextj(int *p, int j){
    return *(p+j);      
}

/* KMP 算法 */
int KmpString(HString *ps, HString *pm , int pos , int *p){
    int i;
    int j;
    i = pos;
    j = 1;
    while(i<ps->length && j< pm->length){
        if(*(ps->ch+i) == *(pm->ch+j) || j==0){
            i++;
            j++;
        }
        else{
            j = Nextj(p , j);
        }

    }
    if(j>=pm->length)
        return i-pm->length;
    else
        return 0;
}


int main()
{
    char *c = "ADABBADADA";
    char *mc = "ADBADABBAABADABBADADA";
    int next[10];
    int i ;
    int kmp_status ;
    int sta, stb ;
    HString smodel,smain ;
    sta = StrAssign(&smodel,c);
    stb = StrAssign(&smain,mc);
    if(sta){
        printf("model is assigned \n");
        printf("The model length %d\n",smodel.length);
    }else{
        printf("model assign error\n");
        return 0;
    }
    if(stb){

        printf("main string is assigned \n");
        printf("The String length %d\n",smain.length);
    }else{
        printf("main string assign error\n");
        return 0;
    }
    InitNext(smodel,next);
    /*
    for(i=0;i<=7;i++)
        printf("%d,",next[i]);

    */
    printf("\n");
    kmp_status = KmpString(&smain, &smodel, 1, next);
    if(kmp_status)
        printf("It is ok , The Location is %d",kmp_status);
    else
        printf("This is not matched , sorry ^_^");


    getchar();
    
}

2.( 练习册 4.10 )

/* Reverse String Practice for 4.10
** Author : Kevin
** Date   : 2012/02/29
*/

#include"stdio.h"
#include"alloc.h"
#include"stdlib.h"

/* 堆存储 */
typedef struct{
    char *ch;               /*Store the String*/
    int length;         /*String's length*/
}HString ;

/* 初始化 String*/
int StrAssign( HString *t, char *chars ){
    int i ;
    char *c;
    for(i=0,c=chars; *c!='\0'; ++i,++c);   /* 计算 i 的结果*/
    t->ch = (char*)malloc(i*sizeof(char));
    t->length = i;
    c = chars;
    for(i=0; i<t->length; i++){
        /*t.ch[i] = c[i];*/
        *(t->ch+i) = *(c+i);                /*  上面注释的也可以使用*/
        printf("%c",t->ch[i]);
    }
    printf("\n");
    return 1;   
                    
}

/* 求长度 */
int StrLength( HString t ){
    return t.length ;
}

/* 逆置字符串*/
int StrReverse( HString *t ){
    int i, j;
    char c = '';
    i = 0;
    j = t->length -1;

    while(i<j){
        c = *(t->ch+i);
        *(t->ch+i) = *(t->ch+j);
        *(t->ch+j) = c;
        i++;
        j--;
    }   
    return 1;
}


int main(){
    char *c = "ABCDEF";
    int i ;
    HString hs ;
    StrAssign( &hs ,c);
    printf("\n");
    printf("%d\n",hs.length);
    StrReverse( &hs );
    for(i=0; i<hs.length; i++)
        printf("%c,",*(hs.ch+i));
    getchar();
}


3.( 练习册 4.25 )

/* Replace Operate Practice for 4.25
** Author : Kevin
** Date   : 2012/02/29
*/

#include"stdio.h"
#include"stdlib.h"
#include"alloc.h"

/*堆存储*/
typedef struct{
    char *ch;       /* Store the string */
    int length; /* length */
}HString;

/*初始化String*/
int StrAssign( HString *t, char *chars ){
    int i ;
    char *c;
    for(i=0,c=chars; *c!='\0'; ++i,++c);   /*求字符串的长度,即 i 值*/
    t->ch = (char*)malloc(i*sizeof(char));
    t->length = i;
    c = chars;
    for(i=0; i<t->length; i++){
        /*t.ch[i] = c[i];*/
        *(t->ch+i) = *(c+i);                /* 这种方式和以上的注释的方式都可以*/
        printf("%c",t->ch[i]);
    }
    printf("\n");
    return 1;   
                    
}

/*返回字符串长度*/
int StrLength( HString t ){
    return t.length ;
}



/*指定位置插入字符串*/
int StrInsert(HString *t, int pos, HString s){
    
    int i,j ;

    t->ch = (char*)realloc(t->ch,(t->length+s.length)*sizeof(char));

    for(i=t->length-1; i>=pos; i--){
        *(t->ch+(s.length+i)) = *(t->ch+i);
    }

    for(j=0; j<s.length; i++,j++){
        *(t->ch+pos+j) = *(s.ch+j);
    }
    t->length = t->length+s.length;

    return 1;
}
/*指定位置删除字符串,指定删除长度问题*/
int StrDelete(HString *t, int pos, int len){
    int i = 0;
    int length = t->length - len ;
    
    for(i=pos; i<t->length-len; i++){
        *(t->ch+i) = *(t->ch+i+len);
        printf("%d",i);
    }

    
    t->length = length;


}
/*销毁字符串*/
void StrDestory(HString *t){

    free(t);

}


/*初始化NEXT函数值*/
void InitNext(HString s, int *pn){
    int i, j;
    pn[1] = 0;                              /*NEXT[0] = 0 , pn[0] 即 NEXT[0]不存在*/
    pn[2] = 1;                              /*NEXT[1] = 1*/
    
    for(i=2; i<=s.length; i++){
        j = i ;
        do{
            if(*(s.ch+(i-1)) == *(s.ch+(pn[j]-1)))  {
                pn[i+1] = pn[j]+1;
                break ;
            }
            else{
                j = pn[j];
            }

        }while(j != 1);
                
        if(j == 1){
            pn[i+1] = 1;
        }
        
    }
            
}

/*求NEXT函数值*/
int Nextj(int *p, int j){
    return *(p+j);      
}

/*Kmp算法*/
int KmpString(HString *ps, HString *pm , int pos , int *p){
    int i;
    int j;
    i = pos;
    j = 1;
    while(i<ps->length && j< pm->length){
        if(*(ps->ch+i) == *(pm->ch+j) || j==0){
            i++;
            j++;
        }
        else{
            j = Nextj(p , j);
        }

    }
    if(j>=pm->length)
        return i-pm->length;
    else
        return 0;
}


int main()
{
    char *c = "abaabaf";
    char *mc = "abcdababcddabaabafaass";
    char *t = "xxx";
    int next[7];
    int i ;
    int kmp_status ;
    int sta, stb, stc ;
    HString smodel,smain,sx ;
    sta = StrAssign(&smodel,c);
    stb = StrAssign(&smain,mc);
    stc = StrAssign(&sx,t);
    if(sta){
        printf("model is assigned \n");
        printf("The model length %d\n",smodel.length);
    }else{
        printf("model assign error\n");
        return 0;
    }
    if(stb){

        printf("main string is assigned \n");
        printf("The String length %d\n",smain.length);
    }else{
        printf("main string assign error\n");
        return 0;
    }
    if(stc){

        printf("Replace string is assigned \n");
        printf("The replace length %d\n",sx.length);
    }else{
        printf("Replace string assign error\n");
        return 0;
    }
    
    InitNext(smodel,next);
    /*
    for(i=0;i<=7;i++)
        printf("%d,",next[i]);

    */
    printf("\n");
    kmp_status = KmpString(&smain, &smodel, 1, next);
    if(kmp_status){
        printf("It is ok , The Location is %d",kmp_status);
        StrDelete(&smain, kmp_status,smodel.length);
        StrInsert(&smain, kmp_status, sx);
        printf("\n");
        for(i=0; i<smain.length; i++)
            printf("%c,",*(smain.ch+i));
    }
    else {
        printf("This is not matched , sorry ^_^");
    }

    getchar();
    
}



4.( 数组练习 )

    转置 ( 普通三元组存储 ) , Book 算法 5.1

/* book_5.1
** 普通三元组存储方法,矩阵转置
** Author : Kevin
** Date   : 2012/03/01
*/

#include"stdio.h"
#include"stdlib.h"
#include"alloc.h"

#define MAX_SIZE 20

/*三元组结点存储*/
typedef struct {
    int i;      /* 存储行坐标 */
    int j;      /* 存储列坐标 */
    int elem;   /* 存储值 */
}Triple ;

/*矩阵存储结构*/
typedef struct {
    Triple data[MAX_SIZE];
    int mu;         /*行,包括0*/
    int nu;         /* 列,包括0 */
    int tu;         /*非0元个数*/       
}TSMatrix ;


/*设置矩阵*/
void CreateMatrix(TSMatrix *m, int lm, int lc, int lt)
{
    int i ;
    m->mu = lm;
    m->nu = lc;
    m->tu = lt;
    for(i=0; i<lt; i++){
        printf("Please input the %d values, hang,lie,value\n",i+1);
        scanf("%d,%d,%d",&((m->data[i]).i),&((m->data[i]).j),&((m->data[i]).elem));

    }   
}

/*转置*/
void ReverseMatrix(TSMatrix *m)
{
    int i ;
    int temp ;
    temp = m->mu;
    m->mu = m->nu;
    m->nu = temp ;
    for(i=0; i<m->tu; i++){
        temp = m->data[i].i;
        m->data[i].i = m->data[i].j;
        m->data[i].j = temp;
    }

}

/*显示*/
void DisplayMatrix(TSMatrix *m)
{
    int i, j, k;
    int status = 0;
    for(i=1; i<=m->mu; i++){
            printf("( ");
        for(j=1; j<=m->nu; j++){
            for(k=0; k<m->tu; k++){
                if((i==m->data[k].i) && (j==m->data[k].j)){
                    printf("%d ",m->data[k].elem);
                    status = 1;
                    break;
                }
            }
            if(status == 0)
                printf("0 ");
            status = 0;
        }
        printf(")");
        printf("\n");
    }



        /* 只打印非0元
    for(i=0; i<m->tu; i++)   {
        printf("%d,%d,%d",m->data[i].i,m->data[i].j,m->data[i].elem);
        printf("\n");
    }
    */
        
}
int main()
{
    TSMatrix m;
    CreateMatrix(&m, 3, 4, 4);
    DisplayMatrix(&m);
    printf("\n");
    ReverseMatrix(&m);
    DisplayMatrix(&m);
    getchar();
    getchar();      
}



  矩阵乘法 ( 采用 行逻辑链接存储方式 ) Book 算法 5.3 ( 只是逻辑链接,并非真正指针链接 )
 

/* book_5.3
** 行逻辑链接存储方式,矩阵乘法
** Author : Kevin
** Date   : 2012/03/01
*/

#include"stdio.h"
#include"stdlib.h"
#include"alloc.h"

#define MAX_SIZE 20
#define MAXRC 10

/*三元组结点存储*/
typedef struct {
    int i;      /* 存储行坐标 */
    int j;      /* 存储列坐标 */
    int elem;   /* 存储值 */
}Triple ;

/*矩阵存储结构*/
typedef struct {
    Triple data[MAX_SIZE];  /*存储数据*/
    int rpos[MAXRC];            /*记录各行第一个非0元启示位置*/
    int mu;         /*行,包括0*/
    int nu;         /* 列,包括0 */
    int tu;         /*非0元个数*/       
}RLSMatrix ;

/*未创建,初始化*/
void Initmatrix(RLSMatrix *m)
{
    int i;
    m->mu = 0;
    m->nu = 0;
    m->tu = 0;
    for(i=0; i<MAXRC; i++){
        m->rpos[i] = -1;
    }        
    
}

/*设置矩阵*/
void CreateMatrix(RLSMatrix *m, int lm, int lc, int lt)
{
    int i,j ;
    m->mu = lm;
    m->nu = lc;
    m->tu = lt;
    for(i=0; i<lt; i++){
        printf("Please input the %d values, hang,lie,value\n",i+1);
        scanf("%d,%d,%d",&((m->data[i]).i),&((m->data[i]).j),&((m->data[i]).elem));

    }
    /*增加 设置第一个非0元*/
    for(i=1; i<=m->mu; i++){
        m->rpos[i] = -1;
        for(j=0;j<m->tu;j++){
            if(i==m->data[j].i){
                m->rpos[i] = j;
                break ;
            }
        }
    }
    printf("The Matrix not 0 position is \n");
    for(i=1; i<=m->mu; i++){
        printf("%d ,",m->rpos[i]);
    }
    printf("\n");
}

/*转置*/
void ReverseMatrix(RLSMatrix *m)
{
    int i ;
    int temp ;
    temp = m->mu;
    m->mu = m->nu;
    m->nu = temp ;
    for(i=0; i<m->tu; i++){
        temp = m->data[i].i;
        m->data[i].i = m->data[i].j;
        m->data[i].j = temp;
    }

}

/*矩阵乘法*/
void MultSMatrix(RLSMatrix m1, RLSMatrix m2, RLSMatrix *r)
{
    int i;
    int hang = 0;     /*求rpos*/
    int pos = -1;
    if (m1.nu != m2.mu)
        return 0;

    for(i=0; i<m1.tu; i++){
            hang = m1.data[i].j;
            pos = m2.rpos[hang];
            if(pos >= 0 && m1.data[i].j == m2.data[pos].i ){
                r->data[r->tu].i = m1.data[i].i;
                r->data[r->tu].j = m2.data[pos].j;
                r->data[r->tu].elem = r->data[r->tu].elem + m1.data[i].elem * m2.data[pos].elem;
                pos++;
                r->tu++;
                r->mu++;
                r->nu++;
            }
            
    }
        
}

/*显示*/
void DisplayMatrix(RLSMatrix *m)
{
    int i, j, k;
    int status = 0;
    for(i=1; i<=m->mu; i++){
            printf("( ");
        for(j=1; j<=m->nu; j++){
            for(k=0; k<m->tu; k++){
                if((i==m->data[k].i) && (j==m->data[k].j)){
                    printf("%d ",m->data[k].elem);
                    status = 1;
                    break;
                }
            }
            if(status == 0)
                printf("0 ");
            status = 0;
        }
        printf(")");
        printf("\n");
    }



        /* 只打印非0元
    for(i=0; i<m->tu; i++)   {
        printf("%d,%d,%d",m->data[i].i,m->data[i].j,m->data[i].elem);
        printf("\n");
    }
    */
        
}
int main()
{
    RLSMatrix m , n , r;
    CreateMatrix(&m, 3, 4, 4);
    CreateMatrix(&n, 4, 2, 4);
    Initmatrix(&r);
    DisplayMatrix(&m);
    printf("\n");
    DisplayMatrix(&n);
    MultSMatrix(m,n,&r);
    printf("\n");
    DisplayMatrix(&r);
    /*
    ReverseMatrix(&m);
    DisplayMatrix(&m);
    */
    getchar();
    getchar();      
}



  十字链表 存储压缩矩阵 Book 算法 5.4

 

/* 十字链表 初始化压缩矩阵 Book 算法 5.4
** Author : Kevin
** Date   : 2012/03/01
*/

#include"stdio.h"
#include"stdlib.h"
#include"alloc.h"

/*三元组结点存储*/
typedef struct OLNode{
    int i;          /*行坐标*/
    int j;          /*列坐标*/
    int elem;       /*值*/
    struct OLNode *down; /*向下指针*/
    struct OLNode *right; /*向右指针*/
    
}OLNode, *OLink ;

/*十字链表存储结构*/
typedef struct{
    OLink *rhead;           /*行指针,指向行数组,数组是个指针数组,指向行*/
    OLink *chead;           /*列指针,指向列数组,数组是个指针数组,指向列*/
    int mu;                     /*行,包括 0 元*/
    int nu;                     /*列,包括 0 元*/
    int tu;                     /*非 0 元个数*/
}CrossList;

/*创建十字链表*/
void CreateCrossList(CrossList *pm , int amu, int anu, int atu){
    int i;
    OLink q = NULL;            /*新增加结点时,行指针*/
    OLink pc = NULL;            /*新增加结点时,列指针*/
    OLink pn = NULL;            /*新结点指针*/
    OLink rprior = NULL;    /*保存前一个行指针*/
    OLink cprior = NULL;    /*保存前一个列指针*/
    int hang,lie,value;
    pm->mu = amu;
    pm->nu = anu;
    pm->tu = atu;
    pm->rhead = (OLink *)malloc((amu+1)*sizeof(OLink));   /*指针数组,头指针,没有right*/
    pm->chead = (OLink *)malloc((anu+1)*sizeof(OLink));   /*指针数组,头指针,没有down*/
    for(i=0; i<amu+1; i++){
        /*pm->rhead[i] = NULL;*/
        *(pm->rhead+i) = NULL;
       
    }
    for(i=0; i<anu+1; i++){
        /*pm->chead[i] = NULL;*/
        *(pm->chead+i) = NULL;
        
    }
    
    for(i=1; i<=atu; i++){
        printf("Please input the %d ,hang,lie,value",i);
        scanf("%d,%d,%d",&hang,&lie,&value);
        pn = (OLink)malloc(sizeof(OLNode));
        pn->i = hang;
        pn->j = lie;
        pn->elem = value;
        /*行插入*/
        if( *(pm->rhead+hang) == NULL || (*(pm->rhead+hang))->j > pn->j ){

            pn->right = *(pm->rhead+hang);
            *(pm->rhead+hang) = pn ;

        }
        else{
            for(q = *(pm->rhead+hang); q->right && q->right->j < pn->j; q = q->right);
                pn->right = q->right;
                q->right = pn ;
        }
        /*列插入*/
        if( *(pm->chead+lie) == NULL || (*(pm->chead+lie))->i > pn->i){
            pn->down = *(pm->chead+lie);
            *(pm->chead+lie) = pn ;

        }
        else{
            for(q = *(pm->chead+lie); q->down && q->down->i < pn->i; q = q->down);
                pn->down = q->down;
                q->down = pn ;
        }

    }

}

/*Display the Matrix*/
void DisplayMatrix(CrossList *pm)
{
    int i;
    OLink q = NULL;

    /*行打印*/
    for(i=0; i<pm->mu+1; i++){
        q = *(pm->rhead+i);
        if(q){
            while(q){
                printf("%d ",q->elem);
                q = q->right;
            }
            q = NULL;
        }else{
            continue;
        }
    }
            
}

int main(){
    CrossList cl;
    CreateCrossList(&cl,3,4,4);
    DisplayMatrix(&cl);

    getchar();
    getchar();
}





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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值