PRELOADER

当前文章 : 《数据结构——串,数组和广义表学习篇(一)》

12/2/2019 —— 

前言

昨天一直在做关于KMP算法的事情,今天把数据结构中串,数组和广义表的知识点梳理一下

定义:是由零个或多个字符组成的有限序列,又称字符串。

串的长度:串中字符的数目称为串的长度。

空串:由零个字符组成的串叫做空串,空串不包括任何字符,其长度为零。

子串:串中任意个连续的字符组成的子序列称为该串的子串,空串是任何串的子串。

主串:包含子串的串相应的称为主串。

串有两种表示形式:顺序存储表示和链式存储表示。

顺序存储表示:串的顺序存储结构简称为顺序串,顺序串中的字符序列被顺序地存放在一组连续的存储单元中,主要有三种实现顺序串的方式。

串的顺序存储

#define MAXLEN 255
typedef struct{
    char ch[MAXLEN+1];//存储串的一维数组
    int length; ///串当前的长度 
}SString; 

注意:对于上面的数组加1是为了让数组的下标从1开始,为了避免麻烦而为之

串的堆式顺序存储结构

typedef struct{
    char *ch; 
    int length; ///串当前的长度 
}HString; 

串的链式存储

#define CHUNKSIZE 80
typedef struct Chunk {
    char ch[CHUNKSIZE];
    struct Chunk *next;
} Chunk;
typedef struct {
    Chunk *head,*tail;//串的头指针和尾指针
    int length;
} LString;

BF算法

主串和字串都是从第一个位置进行比较即i=1;j=1

int Index_BF(SString S,SString T) {
    int i=1,j=1; //初始化 
    while(i<=S.length&&j<=T.length) {//两个均为到达串尾 
        if(S.ch[i]==T.ch[j]) {//继续比较后继字符 
            ++i;
            ++j;
        } else {//匹配不成功后退重新开始匹配 
            i=i-j+2;
            j=1;
        }
        if(j>T.length)
            return i-T.length;//匹配成功 
        else return 0;
    }
}

去除特殊的位置进行匹配,也就是说让主串从任意位置与字串进行匹配,只需要把i=1,变成i=pos就可以了,pos代表主串匹配的位置

int Index_BF(SString S,SString T int pos) {
    int i=pos,j=1; //初始化 
    while(i<=S.length&&j<=T.length) {//两个均为到达串尾 
        if(S.ch[i]==T.ch[j]) {//继续比较后继字符 
            ++i;
            ++j;
        } else {//匹配不成功后退重新开始匹配 
            i=i-j+2;
            j=1;
        }
        if(j>T.length)
            return i-T.length;//匹配成功 
        else return 0;
    }
}

注意:其实BF算法就是一个简单的回溯,只需要一直回溯,然后进行字符串的匹配就可以了,其中的i-j+2可以看成是(i-j)+2

就是为了从i所在位置的下一个位置进行匹配就可以了

nextval[]数组计算:

时间复杂度:最好的情况O(m+n),最坏的情况O(m*n)

数组

数组的定义

数组是我们熟悉的数据类型,数组中各元素具有统一的类型,并且数组元素的下标一般具有固定的上界和下界,因此,数组的处理比其它复杂的结构更为简单。

任何数组A都可以看作一个线性表。数组维数确定后,数据元素个数和元素之间的关系不再发生改变,适合顺序存储。

数组的基本操作

数组的顺序表示和实现

行优先顺序

列优先顺序

矩阵的压缩存储

有些特殊矩阵,非零元素呈某种规律分布或者矩阵中出现大量的零元素的情况下,会占用许多单元去存储重复的非零元素或零元素,

这对高阶矩阵会造成极大的浪费,为了节省存储空间,对这类矩阵进行压缩存储——即为多个相同的非零元素只分配一个存储空间;对零元素不分配空间。

特殊矩阵:所谓特殊矩阵是指非零元素或零元素的分布有一定规律的矩阵,如对称矩阵、三角矩阵、对角矩阵等等。

对称矩阵

对称矩阵中元素关于主对角线对称,故只要存储矩阵中上三角或下三角中的元素,让每两个对称的元素共享一个存储空间,这样能节约近一半的存储空间。n2个元素可以压缩到n(n+1)/2个空间中。

三角矩阵

以主对角线划分,三角矩阵有上三角和下三角两种。上三角矩阵它的下三角中的元素均为常数。下三角矩阵正好相反,它的主对角线上方均为常数。

稀疏矩阵

除了记录非零元素的值之外,还必须同时几下它所在的行和列的位置。稀疏矩阵的存储方法一般有三种:三元组法、行逻辑连接顺序表和十字链表法。

广义表

广义表:是由零个或多个原子或子表组成的优先序列,是线性表的推广。

广义表的存储结构

广义表中的数据元素可以具有不同的结构,因此,难以用顺序存储结构表示,通常采用链式存储结构,每个数据元素可用一个节点表示。由于广义表中有两种数据元素,因此需要有两种结构的节点——一种是表结点,一种是原子结点。

表结点由三个域组成:标志域、指示表头的指针的指针域和指示表尾的指针域;而原子域只需两个域:标志域和值域。

表结点由三个域组成:标志域、指示表头的指针域和指向下一个元素的指针;原子结点的三个域为:标志域、值域和指向下一个元素的指针。

参考资料:

部分图片源自:数据结构知识点大总汇