以结点大小为1,且带有头结点的链表结构表示串,实现串的六种串的基本操作StrAssign,StrCopy,StrCompare,StrLength,Concat和SubString的函数

70 篇文章 3 订阅
30 篇文章 11 订阅

以结点大小为1,且带有头结点的链表结构表示串,
实现串的六种串的基本操作StrAssign,StrCopy,StrCompare,
StrLength,Concat和SubString的函数 

/*
以结点大小为1,且带有头结点的链表结构表示串,
实现串的六种串的基本操作StrAssign,StrCopy,StrCompare,
StrLength,Concat和SubString的函数 
*/

//结点 
typedef struct node{
	char data;
	struct node *next;
}node,*pnode;
#include <stdio.h>
#include <malloc.h>
#define N 51
//依据字符数组 构建 链队列
pnode create_link(char c[]);
//释放链队列
void free_link(pnode a);
//打印 串 
void print_linkstring(pnode a);
//成员函数assign()用于分配,把一个 string b对象的从index下标开始的部分内容拷贝到另一个 string a对象上并覆盖原数据。
pnode StrAssign(pnode a,pnode b,int index);//--1
//串的复制 操作 b复制给a 
pnode StrCopy(pnode a,pnode b);//--2
//串的比较操作 
void StrCompare(pnode a,pnode b);//--3
//获取串的长度 
int StrLength(pnode a);//--4
//串的连接 b连接到a的末尾 
pnode Concat(pnode a,pnode b);//--5
//用于截取字符串的某部分,其基本语法为substring(字符串,起始位置(下标),截取长度)
pnode SubString(pnode a,int begin,int length);//--6

//主函数 
int main()
{
	//test_one
	pnode a,b,sub;
	char c1[N] = {'a','b','c','d','e','f','g','h','f','a','b','c','d','e','f','g','h','f'};
	char c2[N] = {'a','b','g','f','e','d','c','b','a'};
	a = create_link(c1);b = create_link(c2);//依据字符数组 构建链队列 
	//打印各串
	print_linkstring(a);
	print_linkstring(b);
//	print_string(sub);

	//test each function
	
	//a = StrAssign(a,b,2);//分配 --1
	//print_linkstring(a);
	
	
	
	//a = StrCopy(a,b);//--2
	//print_linkstring(a);
	
	
	
	//StrCompare(a,b);//--3
	
	
	
	//printf("a: %d b: %d",StrLength(a),StrLength(b));//--4
	
	
	
	//Concat(a,b);//--5
	//print_linkstring(a);
	
	
	
	sub = SubString(a,10,3);
	print_linkstring(sub);
	
	
	//释放a,b 
	free_link(a);
	free_link(b);
	
	return 0;
}

//成员函数assign()用于分配,把一个 string b对象的从 index下标 开始的部分内容拷贝到另一个 string a对象上。
pnode StrAssign(pnode a,pnode b,int index)//--1
{
	//a,b不为空 
	if(a == NULL || b == NULL)
	{
		return NULL;
	}
	//由于是覆盖式拷贝 直接释放a就行
	free_link(a);
	
	//a为空后,开始寻找拷贝点,寻找到后,把后面值 赋值到数组,然后根据这个数组重新构造a链表 
	int count = 0;
	pnode p = b->next;
	while(p != NULL)
	{
		count ++;
		if(count == index + 1)//找到元素位置 
		{
			break;
		}
		p = p->next;
	}
	
	//字符数组
	char c[N] = {'\0'};
	int k = 0; 
	while(p != NULL)
	{
		c[k ++] = p->data;
		p = p->next;
	}
	
	//然后依据这个矩阵 创建一个以a为头结点 的链表 
	a = create_link(c);

	return a;
}
//串的复制 操作 b复制给a 
pnode StrCopy(pnode a,pnode b)//--2
{
	//b不为空 
	if(b == NULL)
	{
		return NULL;
	}
	
	//由于是覆盖式拷贝 直接释放a就行
	free_link(a);
	
	//字符数组
	char c[N] = {'\0'};
	int k = 0;pnode p = b->next;
	while(p != NULL)
	{
		c[k ++] = p->data;
		p = p->next;
	}
	//然后依据这个矩阵 创建一个以a为头结点 的链表 
	a = create_link(c);
	
	return a;
}
//串的比较操作 
void StrCompare(pnode a,pnode b)//--3
{
	pnode p1 = a->next,p2 = b->next;
	//比较 
	while(  p1 != '\0' || p2 != '\0')
	{
		//值相等 
		if(p1->data == p2->data)
		{
			//后移 
			p1 = p1->next;
			p2 = p2->next;
			continue;
		}
		else;
		
		if(p1->data > p2->data)//前者值大 
		{
			printf("前者首次不相同字符大,前者大");
		}
		else if(p1->data < p2->data)//后者值大 
		{
			printf("后者首次不相同字符大,后者大");
		}
		else;

		break;
	}
	
	if(p1 == '\0' && p2 == '\0')//同时结束 
	{
		printf("一样大");
	}
	else if(p1 != '\0' && p2 == '\0')//后者先结束 
	{
		printf("后者字符少,前者大");
	}
	else if(p1 == '\0' && p2 != '\0')//前者先结束 
	{
		printf("前者字符少,后者大");
	}
	else;
	
	return;
}

//获取串的长度 
int StrLength(pnode a)//--4
{
	int length = 0;
	pnode p = a->next;
	while(p != NULL ){p = p->next;length ++;}
	return length;
}

//串的连接 b连接到a的末尾 
pnode Concat(pnode a,pnode b)//--5
{
	
	pnode tail = a;
	//找到a链表的末尾 
	while(tail->next != NULL)
	{
		tail = tail->next;
	}
	
	//链接b的第一个元素结点 
	tail->next = b->next;
	//连接完毕释放b的头结点 
	free_link(b);
	b = NULL;
	
	return a;
}

//用于截取字符串的某部分,其基本语法为substring(字符串,起始位置(下标),截取长度)
pnode SubString(pnode a,int begin,int length)//--6
{
	if(begin < 0 || length <= 0)
	{
		printf("begin,或length 不符合规制!");
		return NULL;
	}
	
	pnode p = a->next;
	//类似于strcopy操作,先把a中要截取的数据 放入一个字符数组
	char c[N] = {'\0'}; 
	//先找到起始位置 
	int k = 0;
	while(p != NULL)
	{
		k ++;
		//找到起始位置 
		if(k == begin + 1)
		{
			break;
		}
		p = p->next;
	}
	//开始赋值 到数组 
	k = 0;
	while(p != NULL)
	{
		k ++;
		c[k - 1] = p->data;
		//限制长度 
		if(k == length)
		{
			break;
		}
		p = p->next;
	}
	
	//依据数组构造一个新的sub链表 
	pnode sub = NULL;
	sub = create_link(c);
	
	return sub;
}
//打印 串 
void print_linkstring(pnode a)
{

	if(a == NULL)
	{
		printf("a is null,error!");
		return;
	}
	else;
	

	pnode q = a->next;
	while(q != NULL)
	{
		printf("%c ",q->data);
		q = q->next;
	}
	
	printf("\n");
	return;
}

//释放链队列
void free_link(pnode a)
{
	//已经释放过 
	if(a == NULL)
	{
		return;
	}
	else;
	
	pnode p = a->next;
	while(p != NULL)
	{
		//剔除p结点 
		a->next = p->next;
		//释放 
		free(p);
		//继续初始化 p 
		p = a->next;
	}
	//结点完毕 释放头结点 
	free(a); 
	
	a = NULL;//置头结点指针,p指针为空
	p = NULL;
	return;
} 
//依据字符数组 构建 链队列
pnode create_link(char c[])
{
	//依据字符数组 构建 链队列
	int size = sizeof(node);
	pnode a = (pnode)malloc(size);
	a->next = NULL;
	a->data = '\0';
	pnode head = a;//头结点
	//构建数据结点 
	int i = 0;
	pnode p = NULL;
	while(c[i] != '\0')
	{
		//初始p 
		p = (pnode)malloc(size);
		p->next = NULL;
		p->data = c[i];
		//链接p 
		head->next = p;
		head = p;//后移
		
		//遍历字符数组
		i ++; 
	}
	return a;
}

 均已通过测试。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用C语言实现的带表头结点链表逆置操作的程序: ```c #include<stdio.h> #include<stdlib.h> typedef struct node { int data; struct node *next; } Node, *List; List createList() { // 创建带表头结点的单链表 List head = (List)malloc(sizeof(Node)); head->next = NULL; return head; } void insertList(List head, int data) { // 在表头插入新节点 Node *newNode = (Node*)malloc(sizeof(Node)); newNode->data = data; newNode->next = head->next; head->next = newNode; } void printList(List head) { // 遍历并输出单链表 Node *p = head->next; while (p != NULL) { printf("%d ", p->data); p = p->next; } printf("\n"); } void reverseList(List head) { // 将单链表逆置 Node *p = head->next, *q = NULL; head->next = NULL; while (p != NULL) { q = p; p = p->next; q->next = head->next; head->next = q; } } int main() { List myList = createList(); insertList(myList, 1); insertList(myList, 2); insertList(myList, 3); insertList(myList, 4); printf("原链表:"); printList(myList); reverseList(myList); printf("逆置后的链表:"); printList(myList); return 0; } ``` 在这个程序中,我们首先定义了一个结构体 `Node` 来表示链表的节点,我们使用 `typedef` 关键字将 `Node` 定义为 `List` 类型,这样 `List` 就可以作为单链表的类型使用。在创建单链表时,我们需要为其加上一个表头结点,因此定义了 `createList` 函数来创建带表头结点的单链表,并返回表头结点的指针。 在插入新节点时,我们是在表头插入的,因此定义了 `insertList` 函数实现在表头插入新节点。在输出单链表时,我们使用 `printList` 函数来遍历单链表,并输出每个节点的值。 在逆置单链表时,我们使用 `reverseList` 函数实现。我们首先定义两个指针 `p` 和 `q`,分别指向当前节点和它的前驱节点。我们从头节点开始,将头节点的下一个节点断开,然后将这个节点移到头节点之后,重复这个过程,直到整个单链表都被遍历完毕,最后头节点的下一个节点就是逆置后的单链表的头节点。 在主函数中,我们先创建一个带表头结点的单链表,然后插入一些节点,输出原始单链表,调用 `reverseList` 函数逆置单链表,输出逆置后的单链表

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值