美文网首页
数据结构之串,数组,矩阵

数据结构之串,数组,矩阵

作者: Hunter琼 | 来源:发表于2021-03-31 15:11 被阅读0次

    一 串

    1.1 串的定义

    串是有限序列的线性表,元素是字符构成,记为s = `a1a2a3....an`,其中s串名,单引号括起来的是串值.

    1.2 串的存储结构

    (1)顺序存储

    串的顺序存储是指一组连续存储单元来存储串值的字符串序列,由于串值为字符,所以可以通过程序语言字符数组定义串的存储空间,也可以通过串长的需要动态申请字符串空间.
    c程序演练顺序串的基本操作如 串初始化,复制,拷贝,求子串,KMP算法等

    #define STRINGMAXSIZE 2
    
    typedef struct{
    // 存储空间固定
    // char str[STRINGMAXSIZE];
    char *str;
    int length;
    }SString;
    
    // 初始化串
    SString initString(){
    SString s;
    // 预空间存储大小
    s.str =(char *) malloc(sizeof(char) *STRINGMAXSIZE);
    s.length = 0;
    return s;
    }
    
    // 动态增加串的长度
    void increaseSize(SString  *s,int len){
    
    char *p = s->str;
    s->str =  (char *)malloc(sizeof(char *) *STRINGMAXSIZE + len);
    
    // 需要将原来的值copy过来 开销比较大
    for(int i = 0; i < s ->length;i++){
      s->str[i] = p[i];
    
    }
    s->length += len;
    free(p);
    
    }
    
    // 赋值
    void assginElem(SString *s,char addStr[] ){
    
    int i = 0;
    
    while(addStr[i]){
      if(i > s->length) increaseSize(s,1);
    
      // s->str[++s->length] = addStr[i];
        s->str[i] = addStr[i];
        ++s->length;
         i++;
    }
    }
    
    // 拷贝
    void copyElem(SString *s,SString copyStr){
    // 调整内存
     if( s->length <  copyStr.length){
    
         s->str = (char *)realloc(s->str,copyStr.length *sizeof(char));
     }
    
      s->length = copyStr.length;
    
      for(int i = 0; i < copyStr.length;i++){
    
         s->str[i] = copyStr.str[i];
    
      }
    
    }
    
    // 查找子串 KMP 算法 复杂度 0(m + n)
    // 返回子串在串的第pos个字符的后 如果没有则返回0
    int KMPindex(SString *s ,SString *t ,int pos){
    // abcdef  f3
    if(t ->length <= 0 || pos < 0 || pos > s->length - 1 || s->length < 0) return 0;
    int i = pos;
    int j = 0;
     
    //    printf("111i == %d %c\n",i,s->str[2]);
    //    printf("1111j == %d %c\n",j,t->str[2]);
    
    while(i < s->length && j < t->length){
        printf("i == %d %c\n",i,s->str[i]);
        printf("j == %d %c\n",j,t->str[j]);
        if(s->str[i] == t->str[j]){
            i++;
            j++;
           // printf("%s","执行\n");
        }else{
           i =  i - j  + 1;
           j = 0;
         //.printf("%s","执行0000\n");
        }
    
    }
     
     
    //printf("j ==%d\n",j);
    
    if(j >= t->length){
       return i - t->length;
    }
    
    return 0;
    
    }
    
    int main(int argc,char *argv[]){
    
    SString str =  initString();
    
    char copyStr[]  = "abcdefcopy_indem11111";
    
    assginElem(&str,copyStr);
    
    printf("str长度=====%d\n",str.length);
     
    
    
    SString str1 = initString();
     
    //char copyStr2[]  = "copy_indem111";
    
    assginElem(&str1,"copy_indem111");
    
    //copyElem(&str,str1);
    
    printf("copy后的str长度=====%d\n",str1.length);
     
    printf("str1子串在str串的第%d位置后全部匹配\n",KMPindex(&str,&str1,0));
    
    return 0;
    }
    
    (2)链式存储

    串也可以使用链式存储,每个结点可以存储一个字符,也可以存储多个字符,注意链表结点大小的会影响链表存储的执行效率.

    typedef struct node{
    
      char ch;
    
      node *next;
    
    
    } Node, *LinkStr;
    
    // 初始化链串
    LinkStr creatLinkString(){
    
       node *nodeStr;
    
       nodeStr = (Node *)malloc(sizeof(Node));
    
       if(!nodeStr){
         nodeStr ->next = NULL;
       }
       
      return nodeStr;
    }
    

    二 多维数组

    二维码数组A[M][N],可以看成一个线性表,它的每个元素也是一个线性表.
    多维数组A[b1,b2, .... bn],设其每其没每一维的下界为1,bi是第i维的上界,从数据结构的逻辑上看,A中的每个元素都被n个关系所约束,这些关系是线性的,每个关系中,除了第一个关系和最后一个关系,其余关系都有一个直接前驱和一个直接后驱;一般来说数组不做删除和插入操作,比较适合顺序存储.

    设L表示每个数组元素占用的存储单元数目,m和n表示数组的行数和列数,那么以行为主序存储数组元素地址的计算公式为:
    Loc(aij) = Loc(a11) + ((i - 1) * n + (j - 1))*L
    同理按照列为主序存储数组元素地址的计算公式为:
    Loc(ij) = Loc(a11) + ((j - 1) *m + (i- 1))*L
    注意数组下标从1 开始.

    三 矩阵

    矩阵在很多科学与工程运算都有广泛的应用;在一些矩阵中有许多相同的元素和零元素,为了节省空间,对矩阵进行压缩存储,压缩存储的意义是多个相同的元素只分配一个存储单元,零元素不分配存储空间.

    3.1 特殊矩阵

    矩阵元素分布存在一定的规律,常见的特殊矩阵有对称矩阵,三角矩阵,多角矩阵等,由于它的元素存在一定的规律,可以将其压缩在一个一维数组中,建立特殊矩阵起每个非零元素和一维数组中位置的对应关系.
    An x n元素具有aij = aji特点,i >= 1 j <= n 则称为n阶对称矩阵.
    如果对称矩阵的每一对元素分配存储单元,可以将n^2的元素压缩存储到能存放n*(n+1)/2存储空间中,如果以行存储Anxn,对称矩阵的元素aij 和 一维数组B[K](0<= K< n*(n+1)/2),存在一一对应关系:
    当i >=j 时 k = i(i -1)/2 + j - 1
    当 i < j 时 k = j(j -1)/2 + i -1
    注意数组下标从0开始,矩阵的ij从1开始

    对角矩阵: 非0元素集中以主对角线为中心的带状区域


    对角矩阵.png

    特点: 1 第一行和最后一行有2个非零元素,2-(n-2)有3个非0元素
    2 使用一维数组存储,元素被压缩到3*n -2存储空间中.
    3 数组下标K和A[i][j]的关系是k= 2*i + j (i >= 0 0<= j < n) (按行存储) 如果 i >= 1 ,j <=n k = 2*i+j -3

    3.2 稀疏矩阵

    系数矩阵非零元素没有规律,对于稀疏矩阵的非0元素存储必须存储其位置(即行号和列号),所以使用三元组(i,j,aij)唯一确定稀疏矩阵的一个元素.

    稀疏矩阵.png

    上图稀疏矩阵,其三元组表为(1,2,12),(1,3,9),(3,1,-3),(3,6,14),(4,3,24),(5,2,18),(6,1,15),(6,4,-7)

    相关文章

      网友评论

          本文标题:数据结构之串,数组,矩阵

          本文链接:https://www.haomeiwen.com/subject/ujpwhltx.html