拆分链表

拆分链表
题目描述
已知有一个乱序的字符序列L,序列中的字符可能是英文字母、数字字符或其它字符,字符的个数未知,每个字符之间用空格分开。字符序列用“-1”作为输入结束标志,这里你要把-1当做一个字符串对待,并且不算作字符序列中的元素。如下即为一个合法的字符序列:“a c 3 b a d 6 , & j m 8 7 2 V -1”。你的任务是将这个字符序列拆分为三个独立的序列A、B和C,其中序列A存放序列L中的字母,序列B存放序列L中的数字,序列C存放序列L中的其他字符,然后,将序列A、B和C分别按照ASCII码的大小关系进行升序排序。最终序列L将变为空序列。
要求:
建立四个单链表,分别存储序列L、A、B、C中的元素。字符序列的输入用“-1”作为结束标志。建立链表L时,建议使用scanf(“%s”,s);来读取字符序列中的字符,即把单独的字符看做一个字符串读取。当L建立后,你要按照问题描述中所述,将L拆分为A、B、C三个链表,然后对每个链表都进行排序,这部分的操作都应该是对指针进行修改,而不是删除节点与建立新节点。在程序结束前要释放链表A、B、C中的所有节点。
输入
一个乱序的字符序列,序列元素的个数未知,以输入“-1”结束,输入“-1”前可能没有其它元素,每个字符序列占一行。
输出
链表A中的元素,占一行;然后是链表B中的元素,占一行。最后是链表C中的元素,占一行。每行的每个元素后有一个空格,注意最后一个元素后只有换行符,如果某个链表为空则,则输出“There is no item in X list.”
数据最多的测试用例节点数在100这个数量级。
Sample 1:
The list A is: V a a b c d j m
The list B is: 2 3 6 7 8
The list C is: & ,

Sample 2:
The list A is: K a a a d m m p v z
The list B is: 0 1 2 9
There is no item in C list.

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct link
{
	char data;
	struct link* next;
}Link;
typedef struct list
{
	Link* head;
	int len;
}List;
void Init(List* L);
void InitList(List* L);//初始化头节点
void apart(List* L, List* A, List* B, List* C);
void sort(List* L);
void Pint(List* A, List* B, List* C);
void Clear(List* L);
int main()
{
	List L, A, B, C;
	Link* ptr;
	L.head = NULL; A.head = NULL;
	B.head = NULL; C.head = NULL;
	L.len = 0; A.len = 0;
	B.len = 0; C.len = 0;
	Init(&L);
	InitList(&A);
	InitList(&B);
	InitList(&C);
	apart(&L, &A, &B, &C);
	sort(&A);
	sort(&B);
	sort(&C);
	Pint(&A, &B, &C);
	Clear(&L);
	Clear(&A);
	Clear(&B);
	Clear(&C);

	return 0;
}
void Init(List* L)
{
	int count = 0;
	char s[3];
	L->head = (Link*)malloc(sizeof(Link));//头节点
	L->head->data = 0;
	L->head->next = NULL;
	Link* ptr = L->head;
	scanf("%s", &s);
	getchar();
	while (strcmp("-1", s))
	{
		ptr->next = (Link*)malloc(sizeof(Link));
		ptr = ptr->next;
		ptr->data = s[0];
		ptr->next = NULL;
		scanf("%s", &s);
		getchar();
		count++;
	}
	L->len = count;
}
void InitList(List* L)
{
	L->head = (Link*)malloc(sizeof(Link));
	L->head->next = NULL;
	L->head->data = 0;
}
void apart(List* L, List* A, List* B, List* C)
{
	Link* ptr, * ptr1, * ptr2, * ptr3, *tmp;
	ptr = L->head;
	ptr1 = A->head;
	ptr2 = B->head;
	ptr3 = C->head;
	while (ptr != NULL && ptr->next != NULL)
	{
		if (ptr->next != NULL && (('a' <= ptr->next->data && ptr->next->data <= 'z') || ('A' <= ptr->next->data && ptr->next->data <= 'Z')))
		{
			ptr1->next = ptr->next;
			ptr->next = ptr->next->next;
			ptr1 = ptr1->next;
			ptr1->next = NULL;
			A->len++;
		}
		else if (ptr->next != NULL && '0' <= ptr->next->data && ptr->next->data <= '9')
		{
			ptr2->next = ptr->next;
			ptr->next = ptr->next->next;
			ptr2 = ptr2->next;
			ptr2->next = NULL;
			B->len++;
		}
		else if(ptr->next != NULL)
		{
			ptr3->next = ptr->next;
			ptr->next = ptr->next->next;
			ptr3 = ptr3->next;
			ptr3->next = NULL;
			C->len++;
		}
	}
}
void sort(List* L)
{
	if (L->head->next == NULL)
		return;
	Link* p1, *p2;
	int i = 0;
	for (i = 0; i < L->len; i++)//冒泡排序
	{
		p1 = L->head;
		while (p1->next->next != NULL)
		{
			if (p1->next->data > p1->next->next->data)
			{
				Link* ptr1 = p1->next;
				Link* ptr2 = p1->next->next;
				p1->next = ptr2;
				ptr1->next = ptr2->next;
				ptr2->next = ptr1;
			}
			p1 = p1->next;
		}
	}
}
void Pint(List* A, List* B, List* C)
{
	Link* ptr;
	if (A->head->next == NULL)
		printf("There is no item in A list.\n");
	else
	{
		printf("The list A is:");
		for (ptr = A->head->next; ptr != NULL; ptr = ptr->next)
		{
			printf(" %c", ptr->data);
		}
		printf("\n");
	}

	if (B->head->next == NULL)
		printf("There is no item in B list.\n");
	else
	{
		printf("The list B is:");
		for (ptr = B->head->next; ptr != NULL; ptr = ptr->next)
		{
			printf(" %c", ptr->data);
		}
		printf("\n");
	}
	if (C->head->next == NULL)
		printf("There is no item in C list.\n");
	else
	{
		printf("The list C is:");
		for (ptr = C->head->next; ptr != NULL; ptr = ptr->next)
		{
			printf(" %c", ptr->data);
		}
		printf("\n");
	}
}
void Clear(List* L)
{
	if (L->head->next == NULL)
	{
		free(L->head);
		L->head = NULL;
		return;
	}
	Link* p1, *p2 = L->head;
	for (p1 = L->head->next; p1 != NULL; p1 = p1->next)
	{
		free(p2);
		p2 = p1;
	}
	free(p2);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值