拆分链表
题目描述
已知有一个乱序的字符序列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);
}