/**
* 实验题目:
* 实现链串各种基本运算的算法
* 实验目的:
* 领会链串存储结构和掌握链串中各种基本运算的算法设计
* 实验内容:
* 实现链串的各种基本运算
* 1、建立串s="abcdefghijklmn"和串s1="123"
* 2、输出串s
* 3、输出串s的长度
* 4、在串s的第9个字符位置插入串s1而产生串s2
* 5、输出串s2
* 6、删除串s第2个字符开始的5个字符而产生串s2
* 7、输出串s2
* 8、将串s第2个字符开始的5个字符替换成串s1而产生串s2
* 9、输出串s2
* 10、提取串s的第2个字符开始的10个字符而产生串s3
* 11、输出串s3
* 12、将串s1和串s2连接起来而产生串s4
* 13、输出串s4
*/
#include <stdio.h>
#include <malloc.h>
#include <stdbool.h>
typedef struct snode
{
char data; // 数据域
struct snode *next; // 指针域
}LinkStrNode; // 声明链串结点类型
/*-----------------将字符串常量赋给串s--------------------*/
static void str_assign(LinkStrNode *&s, char cstr[])
{
int index;
LinkStrNode *p, *r;
s = (LinkStrNode *)malloc(sizeof(LinkStrNode)); // 动态分配存储空间
r = s; // r指向新建链串的尾结点
for(index = 0; cstr[index] != '\0'; index++)
{
p = (LinkStrNode *)malloc(sizeof(LinkStrNode)); // 创建新的数据结点p
p->data = cstr[index]; // 新数据结点p的数据域赋值
r->next = p; // 尾插法建链表
r = p; // r指向新建的数据结点p
}
r->next = NULL; // 尾结点的next域为空
}
/*-----------------销毁串--------------------*/
static void destroy_str(LinkStrNode *&s)
{
LinkStrNode *pre = s; // pre指向链表头结点
LinkStrNode *p = s->next; // p指向链表中的第一个数据结点
while(p != NULL) // 扫描链串s
{
free(pre); // 释放pre结点
// pre,p同步后移一个结点
pre = p;
p = p->next;
}
// 循环结束时,p为NULL,pre指向尾结点,释放它
free(pre);
}
/*-----------------串复制--------------------*/
static void str_copy(LinkStrNode *&s, LinkStrNode *t) // 串t复制给串s
{
LinkStrNode *p = t->next;
LinkStrNode *q;
LinkStrNode *r;
s = (LinkStrNode *)malloc(sizeof(LinkStrNode));
s->next = NULL;
r = s; // r始终指向尾结点
while(p != NULL) // 将t的所有结点复制到s
{
q = (LinkStrNode *)malloc(sizeof(LinkStrNode));
q->data = p->data;
q->next = NULL;
r->next = q;
r = q;
p = p->next;
}
// 尾结点的next域置为NULL
r->next = NULL;
}
/*-----------------判断串相等--------------------*/
static bool str_equal(LinkStrNode *s, LinkStrNode *t)
{
LinkStrNode *p = s->next;
LinkStrNode *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
return false;
}
/*-----------------求串长度--------------------*/
static int str_length(LinkStrNode *s)
{
int len = 0;
LinkStrNode *p = s->next;
while(p != NULL)
{
len++;
p = p->next;
}
return len;
}
/*-----------------串连接--------------------*/
static LinkStrNode * str_concat(LinkStrNode *s, LinkStrNode *t)
{
LinkStrNode *str;
LinkStrNode *p = s->next;
LinkStrNode *q;
LinkStrNode *r;
str = (LinkStrNode *)malloc(sizeof(LinkStrNode));
str->next = NULL;
r = str; // r指向新建链串的尾结点
// 将s的所有结点复制到str
while(p != NULL)
{
q = (LinkStrNode *)malloc(sizeof(LinkStrNode));
q->data = p->data;
q->next = NULL;
r->next = q;
r = q;
p = p->next;
}
p = t->next;
// 将t的所有结点复制到str
while(p != NULL)
{
q = (LinkStrNode *)malloc(sizeof(LinkStrNode));
q->data = p->data;
q->next = NULL;
r->next = q;
r = q;
p = p->next;
}
// 尾结点的next域置为NULL
r->next = NULL;
return str;
}
/*-----------------求子串--------------------*/
static LinkStrNode * sub_str(LinkStrNode *s, int pos, int len)
{
int index;
LinkStrNode *str;
LinkStrNode *p = s->next;
LinkStrNode *q;
LinkStrNode *r;
str = (LinkStrNode *)malloc(sizeof(LinkStrNode)); // 动态分配内存空间
str->next = NULL;
r = str; // r指向新建链串的尾结点
if((pos <= 0) || (pos > str_length(s)) || (len < 0) || (pos + len - 1 > str_length(s))) // 参数不正确时返回空串
return str;
for(index = 0; index < pos - 1; index++)
p = p->next;
for(index = 1; index <= len; index++) // 将s的第pos个结点开始的len个结点复制到str
{
q = (LinkStrNode *)malloc(sizeof(LinkStrNode));
q->data = p->data;
q->next = NULL;
r->next = q;
r = q;
p = p->next;
}
r->next = NULL;
return str;
}
/*-----------------插入子串--------------------*/
static LinkStrNode * ins_str(LinkStrNode *s, int pos, LinkStrNode *t)
{
int index;
LinkStrNode *str;
LinkStrNode *p = s->next;
LinkStrNode *p1 = t->next;
LinkStrNode *q;
LinkStrNode *r;
str = (LinkStrNode *)malloc(sizeof(LinkStrNode)); // 动态分配内存空间
str->next = NULL;
r = str; // r指向新建链串的尾结点
if(pos <= 0 || pos > str_length(s) + 1) // 参数不正确时返回空串
return str;
for(index = 1; index < pos; index++) // 将s的前pos个结点复制到str
{
q = (LinkStrNode *)malloc(sizeof(LinkStrNode)); // 新建数据结点q
q->data = p->data; // 对新建数据结点q数据域赋值
q->next = NULL;
r->next = q; // 尾插法建立链表
r = q; // r指向新建数据结点q
p = p->next; // p后移一个结点
}
while(p1 != NULL) // 将t的所有结点复制到str
{
q = (LinkStrNode *)malloc(sizeof(LinkStrNode));
q->data = p1->data;
q->next = NULL;
r->next = q;
r = q;
p1 = p1->next;
}
while(p != NULL) // 将结点p及其后的结点复制到str
{
q = (LinkStrNode *)malloc(sizeof(LinkStrNode));
q->data = p->data;
q->next = NULL;
r->next = q;
r = q;
p = p->next;
}
r->next = NULL; // 尾结点的next域为空
return str;
}
/*-----------------删除子串--------------------*/
static LinkStrNode * del_str(LinkStrNode *s, int pos, int len)
{
int index;
LinkStrNode *str;
LinkStrNode *p = s->next;
LinkStrNode *q;
LinkStrNode *r;
str = (LinkStrNode *)malloc(sizeof(LinkStrNode));
str->next = NULL;
r = str;// r指向新建链串的尾结点
if((pos <= 0) || (pos > str_length(s)) || (len < 0) || (pos + len - 1 > str_length(s))) // 参数不正确时返回空串
return str;
for(index = 0; index < pos - 1; index++) // 将s的前pos - 1个结点复制到str
{
q = (LinkStrNode *)malloc(sizeof(LinkStrNode));
q->data = p->data;
q->next = NULL;
r->next = q;
r = q;
p = p->next;
}
// 让p沿next跳len个结点
for(index = 0; index < len; index++)
p = p->next;
while(p != NULL) // 将结点p及其后的结点复制到str
{
q = (LinkStrNode *)malloc(sizeof(LinkStrNode));
q->data = p->data;
q->next = NULL;
r->next = q;
r = q;
p = p->next;
}
r->next = NULL; // 尾结点的next域为空
return str;
}
/*-----------------替换子串--------------------*/
static LinkStrNode * rep_str(LinkStrNode *s, int pos, int len, LinkStrNode *t)
{
int index;
LinkStrNode *str;
LinkStrNode *p = s->next;
LinkStrNode *p1 = t->next;
LinkStrNode *q;
LinkStrNode *r;
str = (LinkStrNode *)malloc(sizeof(LinkStrNode));
str->next = NULL;
r = str; // r指向新建链串的尾结点
if((pos <= 0) || (pos > str_length(s)) || (len < 0) || (pos + len - 1 > str_length(s))) // 参数不正确时返回空串
return str;
// 将s的前pos - 1个结点复制到str
for(index = 0; index < pos - 1; index++)
{
q = (LinkStrNode *)malloc(sizeof(LinkStrNode));
q->data = p->data;
q->next = NULL;
r->next = q;
r = q;
p = p->next;
}
// 让p沿next跳len个结点
for(index = 0; index < len; index++)
p = p->next;
// 将t的所有结点复制到str
while(p1 != NULL)
{
q = (LinkStrNode *)malloc(sizeof(LinkStrNode));
q->data = p1->data;
q->next = NULL;
r->next = q;
r = q;
p1= p1->next;
}
// 将结点p及其后的结点复制到str
while(p != NULL)
{
q = (LinkStrNode *)malloc(sizeof(LinkStrNode));
q->data = p->data;
q->next = NULL;
r->next = q;
r = q;
p = p->next;
}
// 将尾结点的next域设置为NULL
r->next = NULL;
return str;
}
/*-----------------输出串s--------------------*/
static void disp_str(LinkStrNode *s)
{
LinkStrNode *p = s->next;
while(p != NULL)
{
printf("%c", p->data);
p = p->next;
}
printf("\n");
}
int main(int argc, char *argv[])
{
LinkStrNode *s, *s1, *s2, *s3, *s4;
printf("链串的基本运算如下:\n");
printf(" (1)建立串s和串s1\n");
str_assign(s, "abcdefghijklmn");
str_assign(s1, "123");
printf(" (2)输出串s:");
disp_str(s);
printf(" (3)串s的长度:%d\n", str_length(s));
printf(" (4)在串s的第9个字符位置插入串s1而产生串s2\n");
s2 = ins_str(s, 9, s1);
printf(" (5)输出串s2:");
disp_str(s2);
printf(" (6)删除串s第2个字符开始的3个字符而产生串s2\n");
s2 = del_str(s, 2, 3);
printf(" (7)输出串s2:");
disp_str(s2);
printf(" (8)将串s第2个字符开始的5个字符替换成串s1而产生串s2\n");
s2 = rep_str(s, 2, 5, s1);
printf(" (9)输出串s2:");
disp_str(s2);
printf(" (10)提取串s的第2个字符开始的10个字符而产生串s3\n");
s3 = sub_str(s, 2, 10);
printf(" (11)输出串s3:");
disp_str(s3);
printf(" (12)将串s1和串s2连接起来而产生串s4\n");
s4 = str_concat(s1,s2);
printf(" (13)输出串s4:");
disp_str(s4);
destroy_str(s);
destroy_str(s1);
destroy_str(s2);
destroy_str(s3);
destroy_str(s4);
return 0;
}
测试结果:
链串的基本运算如下:
(1)建立串s和串s1
(2)输出串s:abcdefghijklmn
(3)串s的长度:14
(4)在串s的第9个字符位置插入串s1而产生串s2
(5)输出串s2:abcdefgh123ijklmn
(6)删除串s第2个字符开始的3个字符而产生串s2
(7)输出串s2:aefghijklmn
(8)将串s第2个字符开始的5个字符替换成串s1而产生串s2
(9)输出串s2:a123ghijklmn
(10)提取串s的第2个字符开始的10个字符而产生串s3
(11)输出串s3:bcdefghijk
(12)将串s1和串s2连接起来而产生串s4
(13)输出串s4:123a123ghijklmn