【Data】串的存储

来源:互联网 发布:java mail.jar maven 编辑:程序博客网 时间:2024/06/07 03:30
1、定长顺序存储表示
2、堆分配存储表示
3、串的块链存储表示

(1和2是顺序存储,3是链式存储)



一、定长顺序存储表示

类似于线性表的顺序存储结构,用一组地址连续的存储单元存储串值的字符序列。

#define MAXSTRLEN 255
typedef unsigned char SString[MAXSTRLEN+1]//0号单元存放串长

串长可用下标为0的数组元素存储,也可在串值后设特殊标记,加一个不计入串长度的'\0'
串的实际长度可以再预定义长度的范围内随意取值,超过预定义的长度的串值则被舍弃

例:串联接的实现Concat(&T,S1,S2)
假设S1,S2和T都是SString型的变量,且串T是由串S1联结串S2得到的,即串T的值的前一段和串S1的值相等,串T的值的后一段和串S2的值相等,则只要进行相应的“串值复制”操作即可,对超长部分实施“截断”操作。
串联接可能出现三种情况:
a、S1,S2串长的和小于T
b、S1,S2串长的和超过最大串长
c、S1串长已等于最大串长  奋斗(为啥不写大于等于呢?我觉得应该是大于等于才对啊)


二、堆分配存储表示

这种存储表示的特点是,仍以一组地址连续的存储单元存放串值字符序列,但它们的存储空间是在程序执行过程中动态分配而得。
在C语言中,存在一个称之为堆的自有存储区,并由C语言的动态分配函数malloc()和free()来管理,利用malloc()为每个新产生的串分配一块实际串长所需存储空间,为处理方便,约定串长也作为存储结构的一部分
(malloc合理预设串长度空间,若串长改变,使用realloc按新串长度增加空间)
typedef struct{char *ch;//若是非空串,则按串长分配存储区,否则ch为NULLint length;//串长度}HStringStatus SrInsert(HString &S,int pos,HString T)//在串S的第pos个字符之前插入T{if(pos<1||pos>S.length+1)return ERROR;if(T.length)//只要串T不空就需要重新分配S空间,以便插入T{     if(!(S.ch=(char *)realloc(S.ch,(S.length+T.length)*sizeof(char))))     exit(OVERFLOW);     for(i=S.length-1;i>=pos-1;--i)//为插入T而腾出pos之后的位置,即从S的pos位置起全部字符均后移。i>pos-1?     S.ch[i+T.length]=S.ch[i];     S.ch[pos-1..pos+T.length-2]=T.ch[0..T.length-1];     S.length+=T.length;}return OK;}


三、串的块链存储表示

为了便于进行过串的操作,当以链表存储串值时,除头指针外还可附设一个尾指针指示链表中的最后一个结点,并给出当前串的长度。称如此定义的串存储结构为块链结构。
在链式存储方式中,结点大小的选择和顺序存储方式的格式选择一样都很重要,它直接影响着串处理的效率。在各种串的处理系统中,所处理的串往往很多或很长,例如一本书的几百万个字符,情报资料的成千上万个条目。这要求我们考虑串值的存储密度。存储密度可定义为:
存储密度=串值所占的存储位/实际分配的存储位

例:S=‘ABCDEFGHI’



以块链作存储结构时实现串的操作很不方便,如在串中插入一个子串时可能需要分割结点,联接两个串时,若第一个串的最后一个节点没有填满时还需要添加其它字符等等。但在应用程序中,可将串的链表存储结构和串的定长结构结合使用。例如在正文编辑系统中,整个“正文”可以看成是一个串,每一行是一个子串,构成一个结点,即:同一行的串用定长结构,而行和行之间用指针相连。