数据结构链串的基本操作(C语言)
·
关于顺序串的操作:
目录
链串跟链表一样,就是数据域的类型只能是char型,其他都没啥大改动,可以直接看功能实现函数部分。
这个链串不知道哪里没有操作正确,导致创建的串前面有一个垃圾值,不知道怎么去掉,所以我的程序是配合着那个垃圾值写的,可能跟正常单链表、链串的某些操作不一样。
垃圾值:

//主函数部分
#include<stdio.h>
#include<malloc.h>
#include<assert.h>
typedef struct LinkString {
char data;
struct LinkString* next;
}String;
int main() {
system("title 链串");
//创建串
String LS;
String* s=&LS;
printf("请先初始化一个串:");
s=InitString(s);
printf("初始化成功!\n");
//创建一个辅助串,用来插入、比较、替换等需要两个串的操作
String* str = (String*)malloc(sizeof(String));
//创建几个变量,用来作选择值、位置值、函数返回值
int chose = 0;
int index = 0;
int num = 0;
while (1) {
printf("--当前串为:");
PrintString(s); //打印串
printf("\n");
printf("--当前串长:%d\n",my_strlen(s));
menu(); //菜单
scanf("%d", &chose);
getchar();
switch (chose) {
//串插入
case 1:
printf("请输入要插入的串:");
str = InitString(str); //先初始化辅助串作要插入的串
printf("请输入要插入的位置:");
scanf("%d", &index); //插入的位置,第一个结点的位置是1
s = InsertString(s, str,index-1);
printf("插入成功!\n----------------------\n");
break;
//串删除
case 2:printf("请输入要删除的串:");
str = InitString(str); //先初始化辅助串作要删除的串
if (my_strstr(s, str) == -1) { //先判断是否是子串,不是就不嫩删除
printf("不是子串无法删除!\n----------------------\n");
break;
}
s = DeleteString(s, str);
printf("删除成功!\n----------------------\n");
break;
//串连接
case 3:
printf("请输入要连接的串:");
str = InitString(str); //先初始化辅助串作要连接的串
s = ConcattString(s, str);
printf("连接成功!\n----------------------\n");
break;
//串比较
case 4:
printf("请输入要比较的串:");
str = InitString(str); //先初始化辅助串作要比较的串
num = my_strcmp(s, str); //相等、大于、小于都会返回值
PrintString(s); //打印源串
if (num == 0) {
printf("等于");
}
if (num > 0) {
printf("大于");
}
if (num < 0) {
printf("小于");
}
PrintString(str); //打印比较的串
printf("\n----------------------\n");
break;
//判子串
case 5:
printf("请输入要判断的串:");
str = InitString(str); //先初始化辅助串作要判断的串
num = my_strstr(s, str); //是不是子串都会返回值
PrintString(str); //打印源串
if (num == 0)
printf("是");
else
printf("不是");
PrintString(s); //打印判断的串
printf("的子串。\n----------------------\n");
break;
//串拷贝
case 6:
printf("请输入要拷贝的串:");
str = InitString(str); //先初始化辅助串作要拷贝的串
s = my_strcpy(s, str);
printf("拷贝成功!\n----------------------\n");
break;
//串替换
case 7:
printf("请输入要替换的串:");
str = InitString(str); //先初始化辅助串作要替换的串
printf("请输入替换的位置:");
scanf("%d", &index);
s = ReplaceString(s, str,index);
printf("替换成功!\n----------------------\n");
break;
//退出
case 0:return;
default:printf("输入错误!重新输入:\n");
}
}
return 0;
}
//菜单
void menu() {
printf("----------------------\n");
printf("请选择:\n");
printf("**********************\n");
printf("****链*串*的*操*作****\n");
printf("**1、插入 2、删除**\n");
printf("**3、连接 4、比较**\n");
printf("**5、子串 6、拷贝**\n");
printf("**7、替换 0、退出**\n");
printf("**********************\n");
}
//初始化
//初始化
String* InitString(String* s) {
s = (String*)malloc(sizeof(String));
s->next = NULL;
//用一个str指针代替操作
String* str = s;
//读到换行符时退出
while (str->data!='\n') {
String* new = (String*)malloc(sizeof(String));
new->data = getchar();
new->next = str->next;
str->next = new;
str = new;
}
//因为退出循环时,str的值是'\n',给它换成'\0'
str->data = '\0';
str->next = NULL;
return s;
}
//串插入
//串插入
String* InsertString(String* s, String* str, int index) {
//断言,不满足以下条件程序报错退出
assert(index >= 0 && index <= my_strlen(s));
//用两个指针代替操作
String* s1 = s;
String* s2 = str;
//先把指针移到要插入的位置处
while (index--) {
s1 = s1->next;
}
//然后把要插入的串的指针移到最后
while (s2->next) {
s2 = s2->next;
}
//因为每个串最后都是'\0',所以给他覆盖掉
s2->data = s1->next->data;
s2->next = s1->next->next;
s1->next = str->next;
return s;
}
//求子串位置
//子串位置
int IndexString(String* s, String* str) {
//从第一个结点开始比较,值一样便是子串位置
String* s1 = s->next;
str = str->next;
//起始位置为1
int index = 1;
while (1) {
if (s1->data == str->data)
return index;
s1 = s1->next;
index++;
}
}
//串删除
//串删除
String* DeleteString(String* s, String* str) {
//先得到子串的位置
int index = IndexString(s, str);
//在得到子串的长度
int length = my_strlen(str);
//建两个前后指针
String* front = s;
String* s1 = s->next;
//先把后指针移到删除的位置,前指针移动删除的前一个位置
while (index!=1) {
front = front->next;
s1 = s1->next;
index--;
}
//把后指针往后移动要删除子串的长度那么多个位置
for (int i = 0; i < length; i++) {
s1 = s1->next;
}
//然后前指针直接指向后指针,中间的就被删掉了
front->next = s1;
return s;
}
//串连接
//串连接
String* ConcattString(String* s,String* str) {
String * s1 = s;
while (1) {
s1 = s1->next;
//当指针来到'\0'处,说明是末尾了,那么就直接连接并且把'\0'覆盖掉
if (s1->data == '\0') {
s1->data = str->next->data;
s1->next = str-> next->next;
return s;
}
}
}
//串比较
//串比较
/*比较的是字符的ASCII码值*/
int my_strcmp(String* s, String* str) {
//有一个串为空时就退出循环
while (s && str) {
if (s->data > str->data)
return 1;
if (s->data < str->data)
return -1;
if (s->data == str->data) {
s = s->next;
str = str->next;
}
}
//推出了循环说明目前两串已比较的值都是相等的
//需要在比较下那个串已经比较完了,没完的那个串大
if (s == NULL && str == NULL)
return 0;
if (s != NULL)
return 1;
else
return -1;
}
//串打印
//串打印
void PrintString(String* str) {
str = str->next;
while (str->data!='\0') {
printf("%c", str->data);
str = str->next;
}
}
//串长度
//串长度
int my_strlen(String* str) {
int count = 0;
while (str->data!='\0') {
count++;
str = str->next;
}
//因为串的开头有一个;垃圾值,所以减去他的长度,如果没有就不用建
return count-1;
}
//判断是否子串
//判子串
int my_strstr(String* s, String* str) {
//建两个指针,以前一后,都从第一个值开始
String* s1 = s->next;
String* s2 = s->next;
//str从第一个值开始
str = str->next;
//定义两个变量作指针用来计数
int front = 1;
int rear = 1;
//求长度
int length = my_strlen(str);
while (s2 && str) {
//如果两值相等,str和s2往后移动继续比较,并且rear+1
if (s2->data == str->data) {
s2 = s2->next;
str = str->next;
rear++;
}
//如果不等,str不动,把s1移动到s2的位置重新开始,front也移动到rear
else {
s2 = s2->next;
rear++;
front = rear;
s1 = s2;
}
//如果front和rear的差值等于了str'的长度,说明str是s的子串
if (rear-front== length)
return 0;
}
//退出了循环说明不是子串
return -1;
}
//串拷贝
//串拷贝
String* my_strcpy(String* s, String* str) {
String* s1 = s;
//直接把str里的所有结点包括'\0'赋值给s就行
while (str) {
s1->data = str->data;
s1 = s1->next;
str = str->next;
}
return s;
}
//串替换
//串替换
String* ReplaceString(String* s, String* str,int index) {
String* s1 = s;
//先找到替换的位置
while (index--) {
s1 = s1->next;
}
str = str->next;
//然后开始赋值
while (str->data) {
s1->data = str->data;
s1 = s1->next;
str = str->next;
}
return s;
}
关于单链表的操作:
更多推荐
所有评论(0)