**
数据结构—(串**(String)**)
**
串的定义:串是由任意多个字符组成的有限数列,可以为数字、字母、其他。
通常一个串含有(主串与子串),而子串在主串中的位置以子串在主串中的第一个字符位置来表示。而当串中元素为空格时为空串,串操作一般用于文本编辑。它与一般数据结构的区别在于其数据类型为 “字符集”。
【串的分类】:按存储方式:顺序存储(定长顺序)、链式存储与堆分配存储。
【顺序存储】:用一确定长度的字符数组存储串中的字符序列,串的长度不能大于数组的存储空间,对于超出长度的进行舍去。定长顺序表示在C语言中,可通过定义字符数组进行存储,在通过函数strlen统计字符个数。注意字符数组的结束标志 ‘/0’ 会占据一个字节的存储空间, 或者通过定义一个变量Length来存放串长。
【链式存储】:串结构与线性结构类似都可以通过链表进行存储,对于一个节点存入多个储数据元素的链式存储模式称为“块链”。这种存储结构通常不设有头结点和双链结构,但链尾会有设有指针,其长度表示可以通过定义指针变量存储。
【代码】:
#define StringSize 100
typedef struct{
char str[StringSize]; //存储空间
struct StringC *next; //指针域
}StringC;
typedef struct {
StringC *head, *tail; //头结点与尾指针
int length; //定义一个存储长度
}
}
【块链的表示】:块链的存储通常用密度表示,密度的大小与节点大小和存储方式有关,节点大小的调整通常用让一个节点存储多个串值,而针对于串长不等于节点大小时通常会填充一些特殊字符。但串的密度太大通常会引起数据移动的不便。
【堆存储表示】:通过堆内存的动态分配函数malloc()与 free(),为新串分配一定长度的存储空间。
【简单串的存储结构】:
#define StringSize 100;
typedef struct {
char str[StringSize];
int length; //串长度
}chString;
【基本运算】
1-串的赋值–(Sassign).
2-串是否为空–(Sempty)
3-串长度的判断–(Slength)
4-串的复制 --(Scopy)
5-串的比较大小–(Scompare)
6-串的插入–(Sinsert)
7-串的删除(第几个位置与多少长度)–(Sdelete)
8-串的连接–(Sconct)
9-串的清空–(Sclear)
【1-串的赋值–(Sassign)】
void Sassign(chString *S,char cstr[]){
int i=0;
for(i=0;cstr[i]!='\0';i++)
S->str[i]=cstr[i]; //将数组cstr[]中的元素赋值给S
S->length=i;
}
【 2-串是否为空–(Sempty)】
int StrEmpty(chString S){
if(S.length==0)
return 1;
else
return 0;
}
【3.串长度的判断–(Slength)】
int Slength(chString S){
return S.length;
}
【4-串的复制 --(Scopy)】
void Scopy(chString *T;chString S){
int i;
for(i=0;i<S.length;i++) //将串S的字符串赋值给T;
T->str[i]=S.str[i]; //将串S的字符复制给T;
T->length=S.length; //将串s的长度赋值给T;
}
【5-串的比较大小–(Scompare)】
int Scompare(chString S, chString T)
{
int i;
for(i=0;i<S.length && i<T.length;i++)
if(S.str[i] !=T.str[i]) //比较两个字符是否相等
return (S.str[i]-T.str[i]); //返回两个字符的ASCII码值;
return (S.length-T.length); // 比较完毕则返回两个串的长度差值。
}
【6-串的插入–(Sinsert)】
int Sinsert (chString *S,int pos,chString T){
int i;
if(pos<0|| pos-1>S->length){
printf("插入的位置不正确\n");
return 0;
}
if(S->length+T.length<=StringSize) {
//在存储空间足够的情况下
for(i=S->length+T.length-1;i>=pos+T.length-1;i--)
//在插入子串T前将串S中的第pos位置后的字符移动len个位置
S->str[i]=S->str[i-T.length];
for(i=0;i<T.length;i++)
s->str[pos+i-1]=T.str[i]; //将串T插入串S中
S->length=S->length+T.length;
}
else if(pos+T.length<=StringSize)
{
//或者串T可以被完全插入到串S中,但会导致串S中的部分字符被舍去
for(i=StringSize;i>T.length+pos-1;i--)
S->str[i]=S->str[i-T.length]; //将pos以后的字符整体移动到最后
for(i=0;i<T.length;i++)
S->str[i+pos-1]=T.str[i];
S->length=StringSize;
return 0;
}
//又或者串T不可以被完全插入到串S中,则将串T中的部分字符被舍去
else{
for(i=0;i<StringSize;i++) //将串T直接插入到串S中
S->str[i+pos-1]=T.str[i];
S->length