第11次oj链表
问题 A: 实验11_4_初识链表
题目描述
已知一个正整数序列,个数未知,但至少有一个元素,你的任务是建立一个单链表,并使用该链表存储这个正整数序列,然后统计这个序列中元素的最大值与最小值,计算序列全部元素之和。正整数的输入用-1作为结束标志,注意-1不算这个正整数序列中的元素(不要统计-1)。
输入
一个正整数序列,正整数序列元素的个数未知,但以输入“-1”结束,输入“-1”前至少输入一个正整数。序列中的元素范围在1—999999999之间。
输出
三个正整数,即最大值、最小值、所有元素之和。
数据最多的测试用例节点数在1000这个数量级,所有整数可以用int型存储。
请注意输入输出格式。
样例输入 Copy
1 4 99 21 50 61 32 4 -1
样例输出 Copy
The maximum,minmum and the total are:99 1 272
/* 单链表 存储整数序列 计算:最大最小,和
@author: 赵雨腾
@data: 12th March 2020
@input: 1 4 99 21 50 61 32 4 -1
@output: The maximum,minmum and the total are:99 1 272
*/
#include<stdio.h>
#include<stdlib.h>
#define ElementType int
struct listNode{
ElementType data;
struct listNode * nextPtr;
};
typedef struct listNode LISTNODE;
typedef LISTNODE * LISTNODEPTR;
/*LISTNODEPTR:指向LISTNODE指针*/
void createListHead(LISTNODEPTR * headPtrPtr);//创建空头
void insertEnd2(LISTNODEPTR *lastPtrPtr, ElementType value);//尾插2
void destroyList(LISTNODEPTR headPtr);//free
void printfList(LISTNODEPTR currentPtr);//打印
int main(void)
{
LISTNODEPTR headPtr,lastPtr,currentPtr;
createListHead(&headPtr);//创建空头
lastPtr=headPtr;//尾指针就是空头
int num,sum,max,min;
sum=0;
scanf("%d",&num);
max=num;
min=num;
//链表创建
while(num!=-1){
insertEnd2(&lastPtr,num);
scanf("%d",&num);
}
// printfList(headPtr);//打印
//跳过 空头
currentPtr=headPtr->nextPtr;
if(currentPtr!=NULL)
{
while(currentPtr!=NULL){
if(max<currentPtr->data)
{
max=currentPtr->data;
}
if(min>currentPtr->data)
{
min=currentPtr->data;
}
sum=sum+currentPtr->data;
currentPtr=currentPtr->nextPtr;
}
}
printf("The maximum,minmum and the total are:%d %d %d",max,min,sum);
destroyList(headPtr);//free
}
//空头
void createListHead(LISTNODEPTR * headPtrPtr){
*headPtrPtr=(LISTNODEPTR)malloc(sizeof(LISTNODE));
(*headPtrPtr)->nextPtr=NULL;
}
//尾插
void insertEnd2(LISTNODEPTR *lastPtrPtr, ElementType value){
LISTNODEPTR newPtr;
newPtr=(LISTNODEPTR)malloc(sizeof(LISTNODE));
if(newPtr!=NULL){
// 上膛
newPtr->data =value;
newPtr->nextPtr =NULL;
// 链接
(*lastPtrPtr)->nextPtr=newPtr;
//修正
*lastPtrPtr =newPtr;
}
}
//free
void destroyList(LISTNODEPTR headPtr){
LISTNODEPTR tempPtr;
while(headPtr!=NULL){
tempPtr =headPtr;
headPtr =headPtr->nextPtr;
free(tempPtr);
}
}
//打印
void printfList( LISTNODEPTR currentPtr)
{
//跳过 空节点
currentPtr=currentPtr->nextPtr;
if(currentPtr!=NULL)
{
//打印
printf("The list is:\n");
while(currentPtr!=NULL){
printf("%d-->",currentPtr->data);
currentPtr=currentPtr->nextPtr;
}
printf("NULL\n\n");
}
}
问题 B: 实验11_10_链表排序
题目描述
已知一个正整数组成的无序序列,个数未知,但至少有一个元素,你的任务是建立一个单链表,并使用该链表存储这个正整数序列,然后将这个链表进行排序,使得排序后的链表为递增序列。正整数的输入用-1作为结束标志,注意-1不算这个正整数序列中的元素(不要统计-1)。在排序的过程中,你可以自己选择排序算法(冒泡排序、选择排序等),但必须是通过修改结点的指针域来进行排序,而不是对结点的数据域进行修改。程序结束后要释放所有节点占据的空间。
输入
一个元素个数未知的正整数序列,以输入“-1”结束,输入“-1”前至少输入一个正整数。
输出
经过排序后的链表,每个元素后有一个空格,注意最后一个元素后只有换行符。
数据最多的测试用例节点数在1000这个数量级,所有整数可以用int型存储。
请注意输入输出格式。
样例输入 Copy
49 38 65 97 76 13 27 49 -1
样例输出 Copy
The new list is:13 27 38 49 49 65 76 97
/* 单链表 排序
@author: 赵雨腾
@data: 12th March 2020
@input: 49 38 65 97 76 13 27 49 -1
@output: The new list is:13 27 38 49 49 65 76 97
*/
#include<stdio.h>
#include<stdlib.h>
#define ElementType int
struct listNode{
ElementType data;
struct listNode * nextPtr;
};
typedef struct listNode LISTNODE;
typedef LISTNODE * LISTNODEPTR;
int getSize (LISTNODEPTR currentPtr);//长度
void bubbleSort(LISTNODEPTR headPtr,int len);//冒泡
void createListHead(LISTNODEPTR * headPtrPtr);//创建空头
void insertEnd2(LISTNODEPTR *lastPtrPtr, ElementType value);//尾插2
void destroyList(LISTNODEPTR headPtr);//free
void printfList(LISTNODEPTR currentPtr);//打印
int main(void)
{
LISTNODEPTR headPtr,lastPtr,currentPtr;
createListHead(&headPtr);//创建空头
lastPtr=headPtr;//尾指针就是空头
int num,len;
scanf("%d",&num);
//链表创建
while(num!=-1){
insertEnd2(&lastPtr,num);
scanf("%d",&num);
}
len=getSize(headPtr); //长度
bubbleSort(headPtr,len); //冒泡
printf("The new list is:") ;
printfList(headPtr);//打印
destroyList(headPtr);//free
}
//长度
int getSize (LISTNODEPTR currentPtr){
int num=-1;/*-1的初始值是为了抵消空节点的计数*/
while(currentPtr!=NULL){
num++;
currentPtr=currentPtr->nextPtr;
}
return (num);
}
//冒泡 排序
void bubbleSort(LISTNODEPTR headPtr,int len)
{
LISTNODEPTR previousPtr,currentPtr,backPtr,tempPtr;
int i,j;
for(i=len-1;i>=1;i--)
{
previousPtr =headPtr;
currentPtr =previousPtr->nextPtr;
backPtr =currentPtr->nextPtr;
// tempPtr =backPtr->nextPtr;
for(j=0;j<=i-1;j++)
{
if(currentPtr->data > backPtr->data)
{
tempPtr =backPtr->nextPtr;
//交换 current back 指针域
previousPtr->nextPtr =backPtr;
backPtr->nextPtr =currentPtr;
currentPtr->nextPtr =tempPtr;
//p b c 修正
previousPtr=backPtr;
currentPtr=currentPtr;
backPtr=currentPtr->nextPtr;
}
else
{
//p c b 修正
previousPtr =currentPtr;
currentPtr =backPtr;
backPtr =backPtr->nextPtr;
}
}
}
}
//空头
void createListHead(LISTNODEPTR * headPtrPtr){
*headPtrPtr=(LISTNODEPTR)malloc(sizeof(LISTNODE));
(*headPtrPtr)->nextPtr=NULL;
}
//尾插
void insertEnd2(LISTNODEPTR *lastPtrPtr, ElementType value){
LISTNODEPTR newPtr;
newPtr=(LISTNODEPTR)malloc(sizeof(LISTNODE));
if(newPtr!=NULL){
// 上膛
newPtr->data =value;
newPtr->nextPtr =NULL;
// 链接
(*lastPtrPtr)->nextPtr=newPtr;
//修正
*lastPtrPtr =newPtr;
}
}
//free
void destroyList(LISTNODEPTR headPtr){
LISTNODEPTR tempPtr;
while(headPtr!=NULL){
tempPtr =headPtr;
headPtr =headPtr->nextPtr;
free(tempPtr);
}
}
//打印
void printfList( LISTNODEPTR currentPtr)
{
//跳过 空节点
currentPtr=currentPtr->nextPtr;
if(currentPtr!=NULL)
{
//打印
while(currentPtr!=NULL){
printf("%d ",currentPtr->data);
currentPtr=currentPtr->nextPtr;
}
}
}
问题 C: 实验11_11_链表匹配
题目描述
已知两个由正整数组成的无序序列A、B,每个序列的元素个数未知,但至少有一个元素。你的任务是判断序列B是否是序列A的连续子序列。假设B是“1 9 2 4 18”,A是“33 64 1 9 2 4 18 7”,B是A的连续子序列;假设B是“1 9 2 4 18”,A是“33 1 9 64 2 4 18 7”,B不是A的连续子序列。
要求:
建立两个单链表A、B用于存储两个正整数序列,然后按照题目的要求,判断链表B是否是链表A的连续子序列。正整数的输入用-1作为结束标志,注意-1不算这个正整数序列中的元素(不要统计-1)。在程序结束前要释放链表A、B中的所有节点。
输入
依次输入两个乱序的正整数序列A、B,序列中元素个数未知,但每个序列至少有一个元素,并以输入“-1”结束,每个序列占一行。
输出
如果序列B是序列A的连续子序列,则输出“ListB is the sub sequence of ListA.”,否则输出“ListB is not the sub sequence of ListA.”。
数据最多的测试用例节点数在100这个数量级,所有整数可以用int型存储。
请注意输入输出格式。
样例输入 Copy
Sample 1:
5 4 3 2 1 -1
3 2 1 -1
Sample 2:
1 2 3 4 5 6 7 8 9 -1
1 2 3 4 5 6 7 8 0 -1
样例输出 Copy
Sample 1:
ListB is the sub sequence of ListA.
Sample 2:
ListB is not the sub sequence of ListA.
/* 判断子数列
@author: 赵雨腾
@data: 13th March 2020
@input:
Sample 1:
5 4 3 2 1 -1
3 2 1 -1
Sample 2:
1 2 3 4 5 6 7 8 9 -1
1 2 3 4 5 6 7 8 0 -1
@output:
Sample 1:
ListB is the sub sequence of ListA.
Sample 2:
ListB is not the sub sequence of ListA.
*/
#include<stdio.h>
#include<stdlib.h>
#define ElementType int
struct listNode{
ElementType data;
struct listNode * nextPtr;
};
typedef struct listNode LISTNODE;
typedef LISTNODE * LISTNODEPTR;
/*LISTNODEPTR:指向LISTNODE指针*/
void createListHead(LISTNODEPTR * headPtrPtr);//创建空头
void insertEnd2(LISTNODEPTR *lastPtrPtr, ElementType value);//尾插2
void destroyList(LISTNODEPTR headPtr);//free
int seekSubsequence(LISTNODEPTR headPtr1,LISTNODEPTR headPtr2);//寻找子列
int main(void)
{
LISTNODEPTR headPtr1,headPtr2,lastPtr1,lastPtr2;
createListHead(&headPtr1);//创建空头
lastPtr1=headPtr1;//尾指针就是空头
createListHead(&headPtr2);
lastPtr2=headPtr2;
//链表创建
int num;
scanf("%d",&num);
while(num!=-1){
insertEnd2(&lastPtr1,num);
scanf("%d",&num);
}
scanf("%d",&num);
while(num!=-1){
insertEnd2(&lastPtr2,num);
scanf("%d",&num);
}
//判断是否为 连续子序列
if(seekSubsequence(headPtr1,headPtr2)){
printf("ListB is the sub sequence of ListA.");
}
else{
printf("ListB is not the sub sequence of ListA.");
}
destroyList(headPtr1);//free
destroyList(headPtr2);
}
//寻找子列(返回 1 || 0
int seekSubsequence(LISTNODEPTR headPtr1,LISTNODEPTR headPtr2)
{
LISTNODEPTR currentPtr1,currentPtr2,markLoc1;
markLoc1 =headPtr1->nextPtr;
currentPtr1 =markLoc1;
currentPtr2 =headPtr2->nextPtr;
int find=0;
while (find==0&&markLoc1!=NULL)
{
//匹对 两个链表 的 首个数据
if(markLoc1->data == currentPtr2->data)
{
currentPtr1=markLoc1;
//首数据匹配,再一一对应 后面的数据
while(currentPtr2!=NULL && currentPtr1!=NULL){
if(currentPtr1->data == currentPtr2->data){
currentPtr1=currentPtr1->nextPtr;
currentPtr2=currentPtr2->nextPtr;
}
else{
break;
}
}
//全部匹配 返回 1 否则 current2 返回第一个节点,markLoc跳到下一个 节点
if(currentPtr2==NULL){
find=1;
}
else{
currentPtr2=headPtr2->nextPtr;
markLoc1=markLoc1->nextPtr;
}
}
//首个数据未匹配 markLoc跳到下一个 节点
else
{
markLoc1=markLoc1->nextPtr;
}
}
return find;
}
//空头
void createListHead(LISTNODEPTR * headPtrPtr){
*headPtrPtr=(LISTNODEPTR)malloc(sizeof(LISTNODE));
(*headPtrPtr)->nextPtr=NULL;
}
//尾插
void insertEnd2(LISTNODEPTR *lastPtrPtr, ElementType value){
LISTNODEPTR newPtr;
newPtr=(LISTNODEPTR)malloc(sizeof(LISTNODE));
if(newPtr!=NULL){
// 上膛
newPtr->data =value;
newPtr->nextPtr =NULL;
// 链接
(*lastPtrPtr)->nextPtr=newPtr;
//修正
*lastPtrPtr =newPtr;
}
}
//free
void destroyList(LISTNODEPTR headPtr){
LISTNODEPTR tempPtr;
while(headPtr!=NULL){
tempPtr =headPtr;
headPtr =headPtr->nextPtr;
free(tempPtr);
}
}
问题 D: 实验11_13_链表交换
题目描述
已知一个正整数序列,序列元素个数未知,但至少有两个元素,你的任务是建立一个单链表用于存储这个正整数序列。然后实现交换此链表中任意指定的两段,第一段为[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型存储。
请注意输入输出格式。
样例输入 Copy
1 2 3 4 5 6 7 8 9 10 -1
1 1 4 7
样例输出 Copy
The new list is:4 5 6 7 2 3 1 8 9 10
/* 链表交换
@author: 赵雨腾
@data: 12th March 2020
样例输入 Copy
1 2 3 4 5 6 7 8 9 10 -1
1 1 4 7
样例输出 Copy
The new list is:4 5 6 7 2 3 1 8 9 10
*/
#include<stdio.h>
#include<stdlib.h>
#define ElementType int
struct listNode{
ElementType data;
struct listNode * nextPtr;
};
typedef struct listNode LISTNODE;
typedef LISTNODE * LISTNODEPTR;
/*LISTNODEPTR:指向LISTNODE指针*/
void createListHead(LISTNODEPTR * headPtrPtr);//创建空头
void insertEnd2(LISTNODEPTR *lastPtrPtr, ElementType value);//尾插2
void destroyList(LISTNODEPTR headPtr);//free
void printfList(LISTNODEPTR currentPtr);//打印
void swapList(LISTNODEPTR headPtr);//交换
LISTNODEPTR getLocation(LISTNODEPTR headPtr,int loc);//获得 第loc个节点的位置
int main(void)
{
LISTNODEPTR headPtr,lastPtr;
createListHead(&headPtr);//创建空头
lastPtr=headPtr;//尾指针就是空头
//链表创建
int num;
scanf("%d",&num);
while(num!=-1){
insertEnd2(&lastPtr,num);
scanf("%d",&num);
}
swapList(headPtr);
printf("The new list is:");
printfList(headPtr);
destroyList(headPtr);//free
}
//交换
void swapList(LISTNODEPTR headPtr)
{
//定义域 s前为 ss, 定义域 t后为 tt
LISTNODEPTR s1ptr,t1ptr,s2ptr,t2ptr,ss1ptr,tt1ptr,ss2ptr,tt2ptr;
int s1,t1,s2,t2;
scanf("%d %d %d %d",&s1,&t1,&s2,&t2);
//用temptr 保存 t2ptr->nextPtr
ss1ptr =getLocation(headPtr,s1-1);
t1ptr =getLocation(headPtr,t1);
ss2ptr =getLocation(headPtr,s2-1);
t2ptr =getLocation(headPtr,t2);
s1ptr=ss1ptr->nextPtr;
s2ptr=ss2ptr->nextPtr;
LISTNODEPTR temptr;
temptr=t2ptr->nextPtr;
if(t1ptr->nextPtr == s2ptr)
{
ss1ptr->nextPtr =s2ptr;
t2ptr->nextPtr =s1ptr;
t1ptr->nextPtr =temptr;
}
else
{
ss1ptr->nextPtr =s2ptr;
t2ptr->nextPtr =t1ptr->nextPtr;
ss2ptr->nextPtr =s1ptr;
t1ptr->nextPtr =temptr;
}
}
//获得 第loc个 节点的位置
LISTNODEPTR getLocation(LISTNODEPTR headPtr,int loc)
{
LISTNODEPTR currentPtr;
int count=0;
currentPtr =headPtr;
while(count != loc){
currentPtr =currentPtr->nextPtr;
count++;
}
return currentPtr;
}
//空头
void createListHead(LISTNODEPTR * headPtrPtr){
*headPtrPtr=(LISTNODEPTR)malloc(sizeof(LISTNODE));
(*headPtrPtr)->nextPtr=NULL;
}
//尾插
void insertEnd2(LISTNODEPTR *lastPtrPtr, ElementType value){
LISTNODEPTR newPtr;
newPtr=(LISTNODEPTR)malloc(sizeof(LISTNODE));
if(newPtr!=NULL){
// 上膛
newPtr->data =value;
newPtr->nextPtr =NULL;
// 链接
(*lastPtrPtr)->nextPtr=newPtr;
//修正
*lastPtrPtr =newPtr;
}
}
//free
void destroyList(LISTNODEPTR headPtr){
LISTNODEPTR tempPtr;
while(headPtr!=NULL){
tempPtr =headPtr;
headPtr =headPtr->nextPtr;
free(tempPtr);
}
}
//打印
void printfList( LISTNODEPTR currentPtr)
{
//跳过 空节点
currentPtr=currentPtr->nextPtr;
if(currentPtr!=NULL)
{
//打印
while(currentPtr!=NULL){
printf("%d ",currentPtr->data);
currentPtr=currentPtr->nextPtr;
}
}
}