赞
踩
串的链式存储结构与线性表是相似的,但是在链式存储结构中每个节点的数据域可以是一个字符,或者多个字符。如果每个节点的数据域是以一个字符存储的话,由于内存对齐的的影响下,链串的存储密度较小,因此会存在浪费。
如果每个节点的数据域是以四个字符存储的话,链串的存储密度较大,即便在内存对齐的的影响下,也不容易浪费空间。
关于内存对齐,假设每个节点的数据域以一个字符存储,定义的链串数据结构如下:
typedef struct snode
{
char data; //数据域
struct snode *next; //指针域
} LiString;
在上面用C语言定义的数据结构中,节点的数据域是用一个字节来存储一个字符,但是当分配内存时,会进行内存对齐,也就是说,snode节点的数据域会占用4字节的,但是每个节点只使用了一个字节。
需要明白的是,一个节点存储多少字符需要根据实际的情况来决定的,因为这会直接影响到串处理的效率。总体来说,串的链式存储结构不如顺序存储结构存储灵活,性能也不如顺序存储结构,因此,在大多数情况使用串的顺序存储结构比较多。
1.串赋值:StrAssign(s,cstr)
将一个字符串常量cstr赋给串s(采用尾插法)
void StrAssign(LiString *&s,char cstr[])
{
int i;
LiString *r,*p;
s=(LiString *)malloc(sizeof(LiString));
r=s; //r始终指向尾节点
for (i=0; cstr[i]!='\0'; i++)
{
p=(LiString *)malloc(sizeof(LiString));
p->data=cstr[i];
r->next=p;
r=p;
}
r->next=NULL;
}
2.串复制: StrCopy(s,t)
将串t复制给串s
void StrCopy(LiString *&s,LiString *t)
{
LiString *p=t->next,*q,*r;
s=(LiString *)malloc(sizeof(LiString));
r=s; //r始终指向串s的尾节点
while (p!=NULL) //p将串t的所有节点复制到串s中
{
q=(LiString *)malloc(sizeof(LiString));
q->data=p->data;
r->next=q;
r=q;
p=p->next;
}
r->next=NULL;
}
3.判串相等:StrEqual(s,t)
若两个串s与t相等返回真(1);否则返回假(0)
bool StrEqual(LiString *s,LiString *t)
{
LiString *p=s->next,*q=t->next;
while (p!=NULL && q!=NULL && p->data==q->data)
{
p=p->next;
q=q->next;
}
if (p==NULL && q==NULL)
return true;
else
//说明p和q有一个不为空
return false;
}
4.求串长:StrLength(s)
int StrLength(LiString *s)
{
int i=0;
LiString *p=s->next;
while (p!=NULL)
{
i++;
p=p->next;
}
return i;
}
5.串连接:Concat(s,t)
将两个串s和t连接形成新串,返回这个新串。
LiString *Concat(LiString *s,LiString *t)
{
LiString *str,*p=s->next,*q,*r;
//新串str
str=(LiString *)malloc(sizeof(LiString));
r=str;
//将s的所有节点复制到str
while (p!=NULL)
{
q=(LiString*)malloc(sizeof(LiString));
q->data=p->data;
r->next=q;
r=q;
p=p->next;
}
p=t->next;
//将t的所有节点复制到str
while (p!=NULL)
{
q=(LiString*)malloc(sizeof(LiString));
q->data=p->data;
r->next=q;
r=q;
p=p->next;
}
r->next=NULL;
return str;
}
6.求子串: SubStr(s,i,j)
返回串s中从第i个字符开始的、由连续j个字符组成的子串。
参数不正确时返回一个空串 (1≤i≤StrLength(s))
LiString *SubStr(LiString *s,int i,int j)
{
int k;
LiString *str,*p=s->next,*q,*r;
str=(LiString *)malloc(sizeof(LiString));
str->next=NULL;
r=str; //r指向新串str的尾节点
if (i<=0 || i>StrLength(s) || j<0 || i+j-1>StrLength(s))
return str; //参数非法时的处理
//移动到串s的第i个节点
for (k=0; k<i-1; k++)
p=p->next;
//将s的第i个节点开始的j个节点复制到str
for (k=1; k<=j; k++)
{
q=(LiString *)malloc(sizeof(LiString));
q->data=p->data;
r->next=q;
r=q;
p=p->next;
}
//将尾节点的next置为NULL
r->next=NULL;
return str;
}
7.输出串:DispStr(s)
void DispStr(LiString *s)
{
LiString *p=s->next;
while (p!=NULL)
{
printf("%c",p->data);
p=p->next;
}
printf("\n");
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。