实验11_15_拆分链表

题目描述

已知有一个乱序的字符序列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这个数量级。
请注意输入输出格式。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct node{
	char s[3];
	struct node * nextPtr;
}LISTNODE, * LISTNODEPTR;
void createListHead(LISTNODEPTR *,LISTNODEPTR *);
void insertEnd(LISTNODEPTR *,char *);
void splitList(LISTNODEPTR,LISTNODEPTR,LISTNODEPTR,LISTNODEPTR);
void bubbleSort(LISTNODEPTR);
int isEmpty(LISTNODEPTR);
void printList(LISTNODEPTR);
void freeList(LISTNODEPTR);
int main(){
	LISTNODEPTR headPtrL,lastPtrL,headPtrA,lastPtrA,headPtrB,lastPtrB,headPtrC,lastPtrC;
	createListHead(&headPtrL,&lastPtrL);
	createListHead(&headPtrA,&lastPtrA);
	createListHead(&headPtrB,&lastPtrB);
	createListHead(&headPtrC,&lastPtrC);
	char s[3];
	memset(s,0,3);
	scanf("%s",s);
	while((s[0] != '-') || (s[1] != '1')){
		insertEnd(&lastPtrL,s);
		memset(s,0,3);
		scanf("%s",s);
	}
	splitList(headPtrL,headPtrA,headPtrB,headPtrC);
	bubbleSort(headPtrA);
	bubbleSort(headPtrB);
	bubbleSort(headPtrC);
	if(isEmpty(headPtrA)){
		printf("There is no item in A list.\n");
	}
	else {
		printf("The list A is: ");
		printList(headPtrA);
	}
	if(isEmpty(headPtrB)){
		printf("There is no item in B list.\n");
	}
	else {
		printf("The list B is: ");
		printList(headPtrB);
	}
	
	if(isEmpty(headPtrC)){
		printf("There is no item in C list.\n");
	}
	else {
		printf("The list C is: ");
		printList(headPtrC);
	}
	freeList(headPtrL);
	freeList(headPtrA);
	freeList(headPtrB);
	freeList(headPtrC);
	return 0;
}
void createListHead(LISTNODEPTR * headPtrPtr,LISTNODEPTR * lastPtrPtr){
	(*headPtrPtr) = malloc(sizeof(LISTNODE));
	if((*headPtrPtr) != NULL){
		(*headPtrPtr)->nextPtr = NULL;
		(*lastPtrPtr) = (*headPtrPtr);
	}
	else{
		printf("Error!-101");
	}
}
void insertEnd(LISTNODEPTR * lastPtrPtr,char * s){
	LISTNODEPTR newPtr = malloc(sizeof(LISTNODE));
	if(newPtr != NULL){
		int i;
		for(i = 0;i < 3;i++){
			newPtr->s[i] = s[i];
		}
		newPtr->nextPtr = NULL;
		(*lastPtrPtr)->nextPtr = newPtr;
		(*lastPtrPtr) = newPtr;
	}
}
void splitList(LISTNODEPTR headPtrL,LISTNODEPTR headPtrA,LISTNODEPTR headPtrB,LISTNODEPTR headPtrC){
	LISTNODEPTR previousPtr = headPtrL,currentPtr = headPtrL->nextPtr;
	while(currentPtr != NULL){
		if((currentPtr->s[0]>='A'&&currentPtr->s[0]<='Z')||(currentPtr->s[0]>='a'&&currentPtr->s[0]<='z')){
			headPtrA->nextPtr = currentPtr;
			headPtrA = currentPtr;
			previousPtr->nextPtr = currentPtr->nextPtr;
			currentPtr->nextPtr = NULL;
			currentPtr = previousPtr->nextPtr;
		}
		else if(currentPtr->s[0]>='0'&&currentPtr->s[0]<='9'){
			headPtrB->nextPtr = currentPtr;
			headPtrB = currentPtr;
			previousPtr->nextPtr = currentPtr->nextPtr;
			currentPtr->nextPtr = NULL;
			currentPtr = previousPtr->nextPtr;
		}
		else{
			headPtrC->nextPtr = currentPtr;
			headPtrC = currentPtr;
			previousPtr->nextPtr = currentPtr->nextPtr;
			currentPtr->nextPtr = NULL;
			currentPtr = previousPtr->nextPtr;
		}
	}
}//将链表拆至A、B、C中
void bubbleSort(LISTNODEPTR headPtr){
	LISTNODEPTR previousPtr,currentPtr;
	LISTNODEPTR lastPtr = NULL;
	while(lastPtr != headPtr->nextPtr){
		previousPtr = headPtr;
		currentPtr = headPtr->nextPtr;
		while(currentPtr->nextPtr != lastPtr){
			if(currentPtr->s[0] > currentPtr->nextPtr->s[0]){
				previousPtr->nextPtr = previousPtr->nextPtr->nextPtr;
				currentPtr->nextPtr = currentPtr->nextPtr->nextPtr;
				previousPtr->nextPtr->nextPtr = currentPtr;
			}
			else currentPtr = currentPtr->nextPtr;
			previousPtr = previousPtr->nextPtr;
		}
		lastPtr = currentPtr;
	}
}//冒泡排序
int isEmpty(LISTNODEPTR headPtr){
	if(headPtr->nextPtr == NULL){
		return 1;
	}
	return 0;
}
void printList(LISTNODEPTR headPtr){
	while(headPtr->nextPtr->nextPtr != NULL){
		headPtr = headPtr->nextPtr;
		printf("%c ",headPtr->s[0]);
	}
	headPtr = headPtr->nextPtr;
	printf("%c\n",headPtr->s[0]);
}
void freeList(LISTNODEPTR headPtr){
	LISTNODEPTR tempPtr = headPtr;
	while(headPtr != NULL){
		headPtr = headPtr->nextPtr;
		free(tempPtr);
		tempPtr = headPtr;
	}
}
  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
链表归并是指将两个有序链表合并成一个有序链表的过程。实验11_9的目的是通过链表归并的实现,加深对链表操作的理解和应用。 具体实现步骤如下: 1. 定义一个链表结构体Node,包含一个整型数据域和一个指向下一个节点的指针域。 2. 定义一个链表归并函数merge,输入参数为两个链表的头节点指针head1和head2,输出参数为归并后的链表头节点指针head3。 3. 在merge函数内部,定义一个临时节点指针p,将其指向头节点较小的那个链表的头节点,将头节点较大的那个链表的头节点赋值给head3。 4. 在while循环中,判断p的指针域是否为空,如果为空,则将p的指针域指向头节点较大的那个链表的头节点,并将该链表的头节点指针head3赋值给p。 5. 在while循环中,判断p所指向的节点的数据域与另一个链表头节点的数据域的大小关系,将p的指针域指向数据域较小的节点。 6. 在while循环结束后,将剩余的节点直接接到归并后的链表尾部。 完整代码如下: ``` #include<iostream> using namespace std; struct Node{ int data; Node* next; }; Node* merge(Node* head1,Node* head2){ if(head1==NULL) return head2; if(head2==NULL) return head1; Node* head3=NULL; Node* p=NULL; if(head1->data<head2->data){ p=head1; head1=head1->next; } else{ p=head2; head2=head2->next; } head3=p; while(head1!=NULL&&head2!=NULL){ if(head1->data<head2->data){ p->next=head1; head1=head1->next; } else{ p->next=head2; head2=head2->next; } p=p->next; } if(head1!=NULL) p->next=head1; if(head2!=NULL) p->next=head2; return head3; } int main(){ Node* head1=new Node; Node* head2=new Node; Node* p1=head1; Node* p2=head2; int n,m; cout<<"请输入第一个链表的长度:"; cin>>n; cout<<"请输入第一个链表的元素:"; for(int i=0;i<n;i++){ int x; cin>>x; Node* node=new Node; node->data=x; p1->next=node; p1=node; } cout<<"请输入第二个链表的长度:"; cin>>m; cout<<"请输入第二个链表的元素:"; for(int i=0;i<m;i++){ int x; cin>>x; Node* node=new Node; node->data=x; p2->next=node; p2=node; } Node* head3=merge(head1->next,head2->next); cout<<"合并后的链表为:"; while(head3!=NULL){ cout<<head3->data<<" "; head3=head3->next; } cout<<endl; return 0; } ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值