# 数据结构C语言版_串的块链存储表示和实现

**Topics:**Void type

**Pages:**14 (1320 words)

**Published:**November 7, 2013

数据结构C语言版 串的块链存储表示和实现

P78

编译环境：Dev-C++ 4.9.9.2

日期：2011年2月12日

*/

#include

#include

#include

#include

// LString.h 串的块链存储表示

#define CHUNKSIZE 4 // 可由用户定义的块大小

typedef struct Chunk

{

char ch[CHUNKSIZE];//块的数据域

struct Chunk *next;//块的指针域

}Chunk;

typedef struct

{

Chunk *head,// 串的头指针

*tail;// 串的尾指针

int curlen;// 串的当前长度

}LString;

char blank = '#';// 全局变量,用于填补空余

// 初始化(产生空串)字符串T。

void InitString(LString *T)

{

(*T).curlen=0;

(*T).head=NULL;

(*T).tail=NULL;

}

// 生成一个其值等于chars的串T(要求chars中不包含填补空余的字符) // 成功返回1，否则返回0

int StrAssign(LString *T,char *chars)

{

int i,j,k,l;

Chunk *p,*q;

i=strlen(chars); // i为串的长度

if(!i||strchr(chars,blank)) // 串长为0或chars中包含填补空余的字符

return 0;

(*T).curlen=i;

j=i/CHUNKSIZE;// j为块链的结点数，块的个数

if(i%CHUNKSIZE)//不足一个块的，当成一个块即块数加1

j++;

for(k=0;knext=p;

q=p;

}

for(l=0;lch+l)=*chars++;

if(!*chars) // 最后一个链块

{

(*T).tail=q;

q->next=NULL;

for(;lch+l)=blank;

}

}

return 1;

}

// 由串S复制得串T(连填补空余的字符一块拷贝) int StrCopy(LString *T,LString S)

{

Chunk *h=S.head,*p,*q;

(*T).curlen=S.curlen;

if(h)

{

p=(*T).head=(Chunk*)malloc(sizeof(Chunk));

*p=*h; // 复制1个结点

h=h->next;

while(h)//没到队尾，继续复制块

{

q=p;

p=(Chunk*)malloc(sizeof(Chunk));

q->next=p;

*p=*h;

h=h->next;

}

p->next=NULL;

(*T).tail=p;

return 1;

}

else

return 0;

}

// 若S为空串,则返回1,否则返回0

int StrEmpty(LString S)

{

if(S.curlen) // 非空

return 0;

else

return 1;

}

// 若S>T,则返回值>0;若S=T,则返回值=0;若Sch+jt)==blank) // 跳过填补空余的字符

{

jt++;

if(jt==CHUNKSIZE)

{

pt=pt->next;

jt=0;

}

}; // *(pt->ch+jt)为T的第i个有效字符

if(*(ps->ch+js)!=*(pt->ch+jt))

return *(ps->ch+js)-*(pt->ch+jt);

else // 继续比较下一个字符

{

js++;

if(js==CHUNKSIZE)

{

ps=ps->next;

js=0;

}

jt++;

if(jt==CHUNKSIZE)

{

pt=pt->next;

jt=0;

}

}

}

return S.curlen-T.curlen;

}

// 返回S的元素个数,称为串的长度

int StrLength(LString S)

{

return S.curlen;

}

// 将S清为空串

int ClearString(LString *S)

{

Chunk *p,*q;

//释放空间，并置空

p=(*S).head;

while(p)

{

q=p->next;

free(p);

p=q;

}

(*S).head=NULL;

(*S).tail=NULL;

(*S).curlen=0;

return 1;

}

// 用T返回由S1和S2联接而成的新串

int Concat(LString *T,LString S1,LString S2)

{

LString a1,a2;

InitString(&a1);

InitString(&a2);

StrCopy(&a1,S1);

StrCopy(&a2,S2);

(*T).curlen=S1.curlen+S2.curlen;

(*T).head=a1.head;

a1.tail->next=a2.head;

(*T).tail=a2.tail;

return 1;

}

// 用Sub返回串S的第pos个字符起长度为len的子串。 int SubString(LString *Sub, LString S,int pos,int len)

{

Chunk *p,*q;

int i,k,n,

flag=1;//用来标志复制是否完成，1完成，0未完成

if(posS.curlen||lenS.curlen-pos+1)

return 0;

n=len/CHUNKSIZE;

if(len%CHUNKSIZE)

n++; // n为块的个数

p=(Chunk*)malloc(sizeof(Chunk));

(*Sub).head=p;// 生成空的Sub串

for(i=1;inext=q;

p=q;

}

p->next=NULL;

(*Sub).tail=p;

(*Sub).curlen=len;

for(i=len%CHUNKSIZE; ich+i)=blank; // 填充Sub尾部的多余空间

q=(*Sub).head; // q指向Sub串即将复制的块

i=0;// i指示即将复制的字符在块中的位置

p=S.head;// p指向S串的当前块

n=0;// n指示当前字符在串中的序号

while(flag)

{

for(k=0; kch+k)!=blank)

{

n++;

if(n>=pos&&nnext;

i=0;

}

*(q->ch+i)=*(p->ch+k);

i++;

if(n==pos+len-1) // 复制结束

{

flag=0;

break;

}

}

}

p=p->next;

}

return 1;

}

// T为非空串。若主串S中第pos个字符之后存在与T相等的子串, // 则返回第一个这样的子串在S中的位置,否则返回0 int Index(LString S,LString T,int pos)

{

int i,n,m;

LString sub;

if(pos>=1 && posnext;//h指向下一个块

}

*(q+n)=0;// 串结束符

ClearString(S);// 清空S

StrAssign(S,q); // 重新生成S

}

// 在串S的第pos个字符之前插入串T

int StrInsert(LString *S,int pos,LString T)

{

int i,j,k;

Chunk *p,*q;

LString t;

if(posStrLength(*S)+1) // pos超出范围

return 0;

StrCopy(&t,T); // 复制T为t

Zip(S); // 去掉S中多余的填补空余的字符

i=(pos-1)/CHUNKSIZE; //...

Please join StudyMode to read the full document