题目描述
已知一个正整数序列,序列元素个数未知,但至少有两个元素,你的任务是建立一个单链表用于存储这个正整数序列。然后实现交换此链表中任意指定的两段,第一段为[s1,t1],第二段[s2,t2]。s1、t1、s2、t2代表链表的第几个节点,且满足s1<=t1,s2<=t2,t1<s2,s2一定小于等于链表节点的总个数。正整数的输入用-1作为结束标志,注意-1不算这个正整数序列中的元素(不要统计-1)。最后将链表的全部节点释放。
输入
输入一个正整数序列,以输入“-1”结束,序列中元素个数未知,但输入“-1”前至少输入两个正整数。然后是四个整数,即为s1、t1、s2、t2。
输出
经过处理后的新链表,每个元素后有一个空格,注意最后一个元素后只有换行符。
数据最多的测试用例节点数在100这个数量级,所有整数可以用int型存储。
请注意输入输出格式。
#include <stdio.h>
#include <stdlib.h>
typedef struct node{
int data;
struct node * nextPtr;
}LISTNODE, * LISTNODEPTR;
void createListHead(LISTNODEPTR *,LISTNODEPTR *);
void insertEnd(LISTNODEPTR *,int);
void exchangeList(LISTNODEPTR,int,int,int,int);
LISTNODEPTR createPreviousPtr(LISTNODEPTR,int);
LISTNODEPTR createNextPtr(LISTNODEPTR,int);
void printList(LISTNODEPTR);
void freeList(LISTNODEPTR);
int main(){
LISTNODEPTR headPtr,lastPtr;
createListHead(&headPtr,&lastPtr);
int value;
scanf("%d",&value);
while(value != -1){
insertEnd(&lastPtr,value);
scanf("%d",&value);
}
int s1,t1,s2,t2;
scanf("%d %d %d %d",&s1,&t1,&s2,&t2);
exchangeList(headPtr,s1,t1,s2,t2);
printList(headPtr);
freeList(headPtr);
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,int value){
LISTNODEPTR newPtr = malloc(sizeof(LISTNODE));
if(newPtr != NULL){
newPtr->data = value;
newPtr->nextPtr = NULL;
(*lastPtrPtr)->nextPtr = newPtr;
(*lastPtrPtr) = newPtr;
}
else{
printf("Error!-102");
}
}
void exchangeList(LISTNODEPTR headPtr,int s1,int t1,int s2,int t2){
LISTNODEPTR previousPtrs1,nextPtrt1,previousPtrs2,nextPtrt2;
previousPtrs1 = createPreviousPtr(headPtr,s1);
previousPtrs2 = createPreviousPtr(headPtr,s2);
nextPtrt1 = createNextPtr(headPtr,t1);
nextPtrt2 = createNextPtr(headPtr,t2);//创造要交换的位置之前与之后的指针
LISTNODEPTR previousPtrs1next = previousPtrs1->nextPtr;
LISTNODEPTR previousPtrs2next = previousPtrs2->nextPtr;
LISTNODEPTR nextPtrt1next = nextPtrt1->nextPtr;
LISTNODEPTR nextPtrt2next = nextPtrt2->nextPtr;//设置临时变量,防止指针改变后造成混乱
if(t1+1 == s2){
previousPtrs1->nextPtr = previousPtrs2next;
previousPtrs2->nextPtr = nextPtrt2next;
nextPtrt2->nextPtr = previousPtrs1next;
}//相邻情况
else{
previousPtrs1->nextPtr = previousPtrs2next;
previousPtrs2->nextPtr = previousPtrs1next;
nextPtrt1->nextPtr = nextPtrt2next;
nextPtrt2->nextPtr = nextPtrt1next;
}//不相邻情况
}
LISTNODEPTR createPreviousPtr(LISTNODEPTR headPtr,int s){
s--;//让推进的次数少一次
while(s--){
headPtr = headPtr->nextPtr;
}
return headPtr;
}
LISTNODEPTR createNextPtr(LISTNODEPTR headPtr,int t){
while(t--){
headPtr = headPtr->nextPtr;
}
return headPtr;
}
void printList(LISTNODEPTR headPtr){
printf("The new list is:");
while(headPtr->nextPtr->nextPtr != NULL){
headPtr = headPtr->nextPtr;
printf("%d ",headPtr->data);
}
headPtr = headPtr->nextPtr;
printf("%d\n",headPtr->data);
}
void freeList(LISTNODEPTR headPtr){
LISTNODEPTR tempPtr = headPtr;
while(headPtr != NULL){
headPtr = headPtr->nextPtr;
free(tempPtr);
tempPtr = headPtr;
}
}