Bootstrap

链表练习

1、合并两个有序链表

https://leetcode-cn.com/problems/merge-two-sorted-lists/
题目描述:将两个升序链表合并成一个新的升序链表并返回。新链表是通过拼接给定的两个链表的所有结点组成的。

示例1:
input:L1=[1,2,4]	L2=[1,3,4]
output:[1,1,2,3,4,4]
示例2:
input:L1=[]	L2=[]
output:[]
示例3:
input:L1=[]	L2=[0]
output:[0]
要求:
1、两个链表结点数目范围[0,50]
2、-100<=Node.value<=100

分析:这道题是总体来说就是对链表进行排序,输入两个有序链表,将两个链表合并成一个总的有序链表,首先选择链表类型,为避免冗余的讨论,我们可以选择带表头结点的循环链表。上一小节线性表的应用中,多项式的创建有一个要求就是多项式的每项指数降幂排列,其中选择的也是带表头结点的循环链表,降幂排列用到了链表的排序方式:在多项式的降幂排列中,从头遍历至尾,找到第一个小于当前幂的结点,开始链表插入,这一题我们可以认为是要求按照升幂排列,那么同样从头遍历至尾,找到第一个大于于当前幂的结点,开始链表插入

#include <bits/stdc++.h>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
using namespace std;
typedef int ElemType;
const int maxn=50;//最大长度 
const ElemType maxvalue=100;//结点元素最大值 取负为最小值 
typedef struct node{
	ElemType element;//数据域 
	struct node *next;//指针域 
}Node;
typedef struct headerList{
	int n;//有效长度 
	Node *head;//头指针 
}HeaderList;
void Init(HeaderList *h){//初始化运算 
	h->head=(Node*)malloc(sizeof(Node));
	h->n=0;
	h->head->next=h->head;
	h->head->element=maxvalue+2;
}
void Input(HeaderList *h){//输入运算 若输入非升序 强制升序 
	for(;;){//循环输入 
		Node *pre=h->head,*p=h->head->next;
		//p指针用于查找第一个比当前输入元素大的结点 pre指针认为是p的前驱 
		Node *q=(Node*)malloc(sizeof(Node));
		cin>>q->element;
		if(q->element<-maxvalue||q->element>maxvalue||h->n==maxn)//结束输入条件:输入值小(大)于最小(大)值或超过题目要求的最大长度50 
			break;
		while(p&&p->element<q->element){//循环查找第一个比当前输入元素大的结点 
			pre=p;
			p=p->next;
		}
		//将当前输入结点插入至pre和p之间 
		q->next=p;
		pre->next=q;
		h->n++; 
	}
}
void Output(HeaderList *h){//输出运算 
	Node *p=h->head->next;
	for(;p!=h->head;p=p->next)
		cout<<p->element<<" ";
	cout<<endl;
}
void Merge(HeaderList *h1,HeaderList *h2){//合并运算 将合并结果存入h2中 
	Node *p=h1->head->next,*temp;//temp用于将p中数据复制 便于添加至h2中 
	for(;p!=h1->head;p=p->next){
		Node *pre=h2->head,*q=h2->head->next;
		temp=(Node*)malloc(sizeof(Node));
		temp->element=p->element;//复制数据 
		while(q->element<=p->element){//循环查找第一个大于当前p结点元素的结点 
			pre=q;
			q=q->next;
		}
		//将当前temp结点插入至pre和p之间  
		temp->next=q;
		pre->next=temp;
	}
}
int main(int argc, char** argv) {
	HeaderList hl1,hl2;
	Init(&hl1);Init(&hl2);
	Input(&hl1);Input(&hl2);
	//Output(&hl1);Output(&hl2);
	Merge(&hl1,&hl2);
	Output(&hl2);
	return 0;
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2、删除排序链表中重复元素

https://leetcode-cn.com/problems/remove-duplicates-from-sorted-list/
题目描述:存在一个按升序排列的链表,给定头结点head,删除链表中所有重复元素,使得每个元素只出现一次。返回同样按升序排列的结果链表。

示例1:
input:head=[1,1,2]
output:[1,2]
示例2:
input:head=[1,1,2,3,3]
output:[1,2,3]
要求:
1、链表结点数目范围[0,300]
2、-100<=Node.value<=100

分析:题目有两大要求:升序输入和删除重复元素。升序输入与上一题相同;删除重复元素本质上就是链表的删除操作:定义两个结点指针,遍历链表,若两指针所指元素相等,删除第二个结点。

#include <bits/stdc++.h>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
using namespace std;
typedef int ElemType;
const int maxn=300;//最大长度 
const ElemType maxvalue=100;//结点元素最大值 取负为最小值 
typedef struct node{
	ElemType element;//数据域 
	struct node *next;//指针域 
}Node; 
typedef struct headerList{
	int n;//有效长度 
	Node *head;//头指针 
}HeaderList;
void Init(HeaderList *h){//初始化运算 
	h->head=(Node*)malloc(sizeof(Node));
	h->n=0;
	h->head->next=h->head;
	h->head->element=maxvalue+2;
}
void Input(HeaderList *h){//输入运算 
	for(;;){//循环输入 
		Node *pre=h->head,*p=h->head->next,*q;
		//p指针用于查找第一个比当前输入元素大的结点 pre指针认为是p的前驱
		q=(Node*)malloc(sizeof(Node));
		cin>>q->element;
		if(q->element<-maxvalue||q->element>maxvalue||h->n==maxn)
			break; 
		//结束输入条件:输入值小(大)于最小(大)值或超过题目要求的最大长度300
		while(p&&p->element<q->element){//循环查找第一个比当前元素大的结点 
			pre=p;
			p=p->next;
		}
		//将当前输入结点插入至pre和p之间
		q->next=p;
		pre->next=q;
		h->n++;
	}
}
void Output(HeaderList *h){//输出运算 
	Node *p=h->head->next;
	for(;p!=h->head;p=p->next)
		cout<<p->element<<" ";
	cout<<endl;
}
void Delete(HeaderList *h){//删除运算 
	Node *pre=h->head,*p=pre->next;
	while(p!=h->head){//遍历链表 
		if(pre->element==p->element)//查找到两个结点元素相同 
			pre->next=p->next;//删除第二个结点 
		pre=p;
		p=p->next;
	}
}
int main(int argc, char** argv) {
	HeaderList hl;
	Init(&hl);
	Input(&hl);
	//Output(&hl);
	Delete(&hl);
	Output(&hl);
	return 0;
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3、删除链表中的结点

https://leetcode-cn.com/problems/delete-node-in-a-linked-list/
题目描述:请编写一个函数,使其可以删除某个链表中给定的结点。

示例1:
input:head=[4,5,1,9] node=5
output:[4,1,9]
示例2:
input:head=[4,5,1,9] node=1
output:[4,5,9]
要求:
1、链表至少包含两个结点。
2、链表所有结点的值是唯一的 即不含重复元素。
3、给定待删元素必须有效。

分析:本题采用带表头结点链表完成,本题重要的函数就是删除链表中的给定元素,但题目中有一些要求:链表包含两个结点,那么用户输入一个或零个以内的值则需要再次输入;链表中的所有结点的值唯一,那么就需要遍历链表,若存在重复元素需要再次输入;若输入合法但需要删除的元素不存在,需要重复输入待删元素,直到待删元素存在于链表中。删除函数需要给定待删元素x,假定输入均合法,规定q指针从第一个元素开始遍历,规定pre指针从头结点开始遍历,那么pre指针所指结点为q指针所指结点的前驱,当q指针找到了待删元素,pre指针所指结点的指针域指向当前q结点所指结点的指针域。

#include <bits/stdc++.h>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
using namespace std;
typedef int ElemType;
typedef struct node{
	ElemType element;//数据域 
	struct node *next;//指针域 
}Node;
typedef struct headerList{
	int n;//有效长度 
	Node *head;//头指针 
}HeaderList;
void Init(HeaderList *h){//初始化运算 
	h->n=0;
	h->head=(Node*)malloc(sizeof(Node));
	h->head->element=-1;
	h->head->next=NULL;
}
void Input(HeaderList *h){//输入运算 
	Node *p=h->head;
	for(;;){
		Node *q=(Node*)malloc(sizeof(Node));
		cin>>q->element;
		if(q->element<0)//输入负数结束输入 
			break;
		q->next=p->next;
		p->next=q;
		p=p->next;
		h->n++;
	}	
}
void Output(HeaderList *h){//输出运算 
	Node *p=h->head->next;
	for(;p!=NULL;p=p->next)
		cout<<p->element<<" ";
	cout<<endl;
}
bool isrepeated(HeaderList *h){//判断链表中每个结点值是否重复 
	if(h->n<2)//表长小于2不合法 
		return true;
	else{
		Node *p=h->head->next,*q=p->next;
		while(p->next!=NULL){
			if(p->element==q->element)//出现相同元素不合法 
				return true;
			q=q->next;
			if(q==NULL){
				p=p->next;
				q=p->next;
			}
		}
		return false;
	}
}
void Destory(HeaderList *h){//撤销运算 
	Node *p=h->head,*q=h->head->next;
	while(q!=NULL){
		p->next=q->next;
		free(q);
		q=p->next;
	}
}
bool Delete(HeaderList *h,ElemType x){//删除运算 
	Node *pre=h->head,*q=pre->next;
	for(;q!=NULL;q=q->next){
		if(q->element==x)
			break;
		pre=pre->next;
	}
	if(q==NULL){//待删元素不存在则不合法 
		return true;
	}
	else{
		pre->next=q->next;
		free(q);
		return false;
	}
}
int main(int argc, char** argv) {
	HeaderList hl;
	Init(&hl);
	bool flag=true;
	while(flag){
		Destory(&hl);
		Input(&hl);//执行输入 若不合法重新输入 
		flag=isrepeated(&hl);
	}
	ElemType x;
	bool flag2=true;
	while(flag2){
		cin>>x;
		flag2=Delete(&hl,x);//执行删除 若待删结点不合法重新输入 
	}
	Output(&hl); 
	Destory(&hl); 
	return 0;
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4、移除链表元素

https://leetcode-cn.com/problems/remove-linked-list-elements/
题目描述:给定一个链表的头结点head和val,删除链表中所有满足Node.value==val的结点,并返回新的头结点。

示例1:
input:head=[1,2,6,3,4,5,6] val=6
output:[1,2,3,4,5]
示例2:
input:head=[] val=1
output:[]
示例3:
input:head=[] val=7
ouutput:[]

分析:本题需要删除链表中指定元素,若链表中指定元素存在,无论元素是否重复,均删除与指定元素相等的元素结点,返回删除后的链表;若链表中指定元素不存在,则返回原链表。本题使用带表头结点的单链表,算法核心是Delete函数,设置两个指针p、q遍历链表,p指针所指结点是q指针所指结点的前驱。若q指针当前所指结点的元素与指定元素相等,则删除当前q指针所指结点。
在这里插入图片描述

#include <bits/stdc++.h>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
using namespace std;
const int INF=32767;
typedef int ElemType;
typedef struct node{
	ElemType element;//数据域 
	struct node *next;//指针域 
}Node;
typedef struct headerList{
	int n;//有效长度 
	Node *head;//头指针 
}HeaderList;
void Init(HeaderList *h){//初始化运算 
	h->head=(Node*)malloc(sizeof(Node));
	h->n=0;
	h->head->next=NULL;
	h->head->element=-INF;
}
void Input(HeaderList *h){//输入运算 
	Node *p=h->head;
	for(;;){
		Node *q=(Node*)malloc(sizeof(Node));
		cin>>q->element;
		if(q->element==-INF)
			break;
		q->next=p->next;
		p->next=q;
		p=q;
		h->n++;
	}
}
void Output(HeaderList *h){//输出运算 
	Node *p=h->head->next;
	for(;p!=NULL;p=p->next)
		cout<<p->element<<" ";
	cout<<endl;
}
void Delete(HeaderList *h,ElemType x){//移除元素运算 
	Node *p=h->head;
	Node *q=h->head->next;
	for(;q!=NULL;q=q->next){
		if(q->element==x){ 
			p->next=q->next;
			continue;
		}
		p=p->next;
	}
}
void Destory(HeaderList *h){//撤销运算 
	Node *p=h->head;
	Node *q=p->next;
	while(p->next!=NULL){
		p->next=q->next;
		free(q);
		q=p->next; 
	}
}
int main(int argc, char** argv) {
	HeaderList hl;
	ElemType val;
	Init(&hl);
	Input(&hl);
	Output(&hl);
	cin>>val;
	Delete(&hl,val);
	Output(&hl);
	Destory(&hl);
	return 0;
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

5、链表的中间结点

https://leetcode-cn.com/problems/middle-of-the-linked-list/
题目描述:给定一头结点为head的非空单链表,返回链表中间结点。

示例1:
input:[1,2,3,4,5]
output:3
示例2:
input:[1,2,3,4,5,6]
output:4(中间结点有两个返回第2个)

分析:本题采用带表头结点的单链表,首先执行输入操作,每输入一个有效数,当前表长加1,输入操作结束后链表形成,使用Getvalue函数返回链表中间值,通过for循环将开始指向第一个结点的指针p指向至中间结点,获取element返回。

#include <bits/stdc++.h>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
using namespace std;
const int maxn=100;//最大长度
typedef int ElemType;
typedef struct node{
	ElemType element;//数据域 
	struct node *next;//指针域 
}Node;
typedef struct headerList{
	Node *head;//头指针 
	int n;//有效长度 
}HeaderList;
void Init(HeaderList *h){//初始化运算 
	h->head=(Node*)malloc(sizeof(Node));
	h->head->next=NULL;
	h->head->element=-1;
	h->n=0;
}
void Input(HeaderList *h){//输入操作 
	Node *p=h->head;
	for(;;){
		Node *q=(Node*)malloc(sizeof(Node));
		cin>>q->element;
		if(q->element<0||h->n>100)
			break;
		q->next=p->next;
		p->next=q;
		p=q;
		h->n++;
	}
}
void Output(HeaderList *h){//输出运算 
	Node *p=h->head->next;
	for(int i=0;i<h->n;i++){
		cout<<p->element<<" ";
		p=p->next;
	}
	cout<<endl;
}
ElemType Getvalue(HeaderList *h){//返回中间结点值 
	Node *p=h->head->next;
	for(int i=0;i<(h->n)/2;i++)
		p=p->next;
	return p->element; 
}
int main(int argc, char** argv) {
	HeaderList hl;
	Init(&hl);
	Input(&hl);
	Output(&hl);
	cout<<Getvalue(&hl)<<endl;
	return 0;
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

6、反转链表

https://leetcode-cn.com/problems/reverse-linked-list/
题目描述:给定单链表头结点head,将链表整体反转,返回反转后的链表。

示例1:
input:head=[1,2,3,4,5]
output:[5,4,3,2,1]
示例2:
input:head=[1,2]
output:[2,1]
示例3:
input:head=[]
output:[]

分析:本题使用带表头结点的单链表,为简化链表结构,可遍历链表每个结点的数据,然后倒序存入一维数组中,再次顺序遍历数组和链表,使用覆盖函数将原链表数据覆盖。

#include <bits/stdc++.h>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
using namespace std;
const int maxn=5e3;//最大长度 
typedef struct node{
	int val;//数据域 
	struct node *next;//指针域 
}Node;
typedef struct headerList{
	Node *head;//头指针 
	int n;//有效长度 
}HeaderList;
void Init(HeaderList *h){//初始化运算 
	h->head=(Node*)malloc(sizeof(Node));
	h->head->next=NULL;
	h->head->val=maxn+1;
	h->n=0;
}
void Input(HeaderList *h){//输入运算 
	Node *p=h->head;
	for(;;){
		Node *q=(Node*)malloc(sizeof(Node));
		cin>>q->val;
		if(q->val<-maxn||q->val>maxn||h->n>=maxn)
			break;
		q->next=p->next;
		p->next=q;
		p=q;
		h->n++; 
	}
}
void Flag(HeaderList *h,int *a){//将链表中数据倒序存储至一维数组中 
	Node *p=h->head->next;
	int cnt=h->n-1;
	for(;p!=NULL;p=p->next){
		a[cnt]=p->val;
		cnt--;	
	}
}
void CoverList(HeaderList *h,int *a){//从一维数组中顺序提取元素覆盖原链表 
	Node *p=h->head->next;
	int i=0;
	for(;p!=NULL;p=p->next){
		p->val=a[i];
		i++;
	}
}
void Output(HeaderList *h){//输出运算 
	Node *p=h->head->next;
	for(;p!=NULL;p=p->next)
		cout<<p->val<<" ";
	cout<<endl; 
}
int main(int argc, char** argv) {
	HeaderList hl;
	Init(&hl);
	Input(&hl);
	int *a=(int*)malloc(sizeof(int)*hl.n); 
	Flag(&hl,a);
	CoverList(&hl,a);
	Output(&hl);
	free(a); 
	return 0;
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

7、二进制链表转整数

https://leetcode-cn.com/problems/convert-binary-number-in-a-linked-list-to-integer/
题目描述:给定单链表引用head结点,链表中每个结点的值不是0就是1即二进制的表示形式。请编写函数返回链表所表示数字的十进制。

示例1:
input:head=[1,0,1]
output:5
示例2:
input:head=[0]
output:0
示例3:
head=[1]
output:1
示例4:
input:head=[0,0]
output:0
示例5:
input:head = [1,0,0,1,0,0,1,1,1,0,0,0,0,0,0]
output:18880
要求:
1、链表不为空
2、链表结点总数不超过30
3、每个结点值不是0就是1

分析:本题采用带表头结点的单链表,题目要求将链表中的二进制数转化为十进制数,显然,链表中的值只能为0或1,考虑到用户输入时可能输入错误,那么每输入一个数字,对其检查是否输入合法,若合法则添加至链表中,若不合法舍弃当前输入。其次题目要求输入的二进制位数不超过30,那么由等比数列求和公式得出返回十进制结果最大值为 2 0 2^0 20+ 2 1 2^1 21+…+ 2 29 2^{29} 229= 2 30 2^{30} 230-1=1073741823,远超过int类型(认为16位计算机,int范围为-32768~32767)的范围,我们可以选择long类型作为返回值,其类型最大值为 2 31 2^{31} 231-1。

#include <bits/stdc++.h>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
using namespace std;
typedef long l;
typedef struct node{
	int i;//数据域 
	struct node *next;//指针域 
}Node;
typedef struct headerList{
	Node *head;//头指针 
	int n;//有效长度 
}HeaderList;
void Init(HeaderList *h){//初始化操作 
	h->head=(Node*)malloc(sizeof(Node));
	h->head->next=NULL;
	h->head->i=-1;
	h->n=0;
}
bool judge(int i){//判断函数 判断输入数据是否合法 
	if(i<=0||i==1)//负数用于结束输入 
		return false;
	return true;
}
bool Input(HeaderList *h){//输入运算 
	if(h->n<0||h->n>30)
		return false;
	Node *p=h->head;
	for(;;){
		Node *q=(Node*)malloc(sizeof(Node));
		bool flag=true;
		while(flag){
			cin>>q->i;
			flag=judge(q->i);//若输入数据不合法此数无效 
		}
		if(q->i<0||h->n>=30)
			break;
		q->next=p->next;
		p->next=q;
		p=q;
		h->n++;
	}
	return true;
}
l Quickpow(int a,int b){//快速幂求每项权值 
	l res=1;
	while(b){
		if(b&1)
			res=res*a;
		b>>=1;
		a=a*a;
	}
	return res;
}
l Conversion(HeaderList *h){//转换函数 
	Node *p=h->head->next;
	l res=0;
	int len=h->n;
	for(;p!=NULL;p=p->next){
		res+=Quickpow(2,len-1)*p->i;//结果为每项权值和 
		len--;
	}
	return res;
}
void Output(HeaderList *h){//输出运算 
	Node *p=h->head->next;
	for(;p!=NULL;p=p->next)
		cout<<p->i;
	cout<<endl; 
}
int main(int argc, char** argv) {
	HeaderList hl;
	Init(&hl);
	Input(&hl);
	Output(&hl);
	cout<<Conversion(&hl)<<endl;
	return 0;
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

8、合并两个链表

https://leetcode-cn.com/problems/merge-in-between-linked-lists/
题目描述:给定两链表list1和list2,其原始个数分别n个m个。将list1中第a个结点到第b个结点删除,将list2接在被删除结点位置。

示例1:
input:list1=[0,1,2,3,4,5] list2=[1000000,1000001,1000002] a=3 b=4
output:[0,1,2,1000000,1000001,1000002,5]
示例2:
input:list1=[0,1,2,3,4,5,6] list2=[1000000,1000001,1000002,1000003,1000004] a=2 b=5
output:[0,1,1000000,1000001,1000002,1000003,1000004,6]

分析:本题采用带头结点的单链表,本题重点就是定位,找准切除点,使用p指针找到list1的头删除点,q指针找到list1的尾删除点,pre指针找到list2末尾结点实现对接操作,以上寻找结点操作均可通过for或while循环实现。
在这里插入图片描述

#include <bits/stdc++.h>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
using namespace std;
const int maxn=1e4;//最大长度
typedef long ElemType;
typedef struct node{
	ElemType element;//数据域 
	struct node *next;//指针域 
}Node;
typedef struct headerList{
	Node *head;//头指针 
	int n;//有效长度 
}HeaderList;
void Init(HeaderList *h){//初始化运算 
	h->head=(Node*)malloc(sizeof(Node));
	h->head->next=NULL;
	h->head->element=-1;
	h->n=0;
}
void Input(HeaderList *h){//输入运算 
	Node *p=h->head;
	for(;;){
		Node *q=(Node*)malloc(sizeof(Node));
		cin>>q->element;
		if(q->element<0||h->n>=maxn)
			break;
		q->next=p->next;
		p->next=q;
		p=q;
		h->n++;
	} 
}
void Output(HeaderList *h){//输出运算 
	Node *p=h->head->next;
	for(;p!=NULL;p=p->next)
		cout<<p->element<<" ";
	cout<<endl;
}
int Divide(HeaderList *h1,HeaderList *h2,int a,int b){//合并运算 
	if(a<=b&&a>=1&&b<h1->n-1){
		Node *p=h1->head->next;
		Node *q=h1->head->next;
		for(int i=0;i<a-1;i++)
			p=p->next;//p指针指向h1第a个结点前 
		for(int j=0;j<b;j++)
			q=q->next;//q指针指向h1第b个结点 
		p->next=h2->head->next;
		Node *pre=h2->head->next;
		for(int k=0;k<h2->n-1;k++)
			pre=pre->next;//pre指针指向h2末尾结点 
		pre->next=q->next;
		return 1;
	}
	else//非法输入 
		return 0;
}
int main(int argc, char** argv) {
	HeaderList hl1,hl2;
	Init(&hl1);Init(&hl2);
	Input(&hl1);Input(&hl2);
	Output(&hl1);Output(&hl2);
	int a,b;
	cin>>a>>b;
	Divide(&hl1,&hl2,a,b);
	Output(&hl1);
	return 0;
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

9、回文链表

https://leetcode-cn.com/problems/palindrome-linked-list-lcci/
题目描述:编写一个函数,检查输入的链表是否是回文的。

示例1:
input:1->2
output:false
示例2:
input:1->2->2->1
output:true

分析:回文即对称,本题要求输入一个链表,判断链表的元素是否回文。我们可以想到从链表两头向中间判断,若对称结点元素不等,则不回文。由于普通的链表只能实现向一个方向移动,为提高灵活性,本题采用带表头结点的双向链表

#include <bits/stdc++.h>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
using namespace std;
const int INF=32767;
typedef int ElemType;
typedef struct node{
	ElemType element;//数据域 
	struct node *leftlink;//左指针域 
	struct node *rightlink;//右指针域 
}Node;
typedef struct duList{
	Node *head;//头指针 
	int n;//有效长度 
}DuList;
void Init(DuList *d){//初始化运算 
	d->head=(Node*)malloc(sizeof(Node));
	d->head->element=-INF;
	d->n=0;
	d->head->rightlink=NULL;
}
void Input(DuList *d){//输入运算 
	Node *p=d->head;
	for(;;){
		Node *q=(Node*)malloc(sizeof(Node));
		cin>>q->element;
		if(q->element==-INF)
			break;
		q->leftlink=p;
		p->rightlink=q;
		p=q;
		d->n++;
	}	
}
void Output(DuList *d){//输出运算 
	Node *p=d->head->rightlink;
	for(int i=0;i<d->n;i++){
		cout<<p->element<<" ";
		p=p->rightlink;
	}
	cout<<endl;
}
bool Isreplies(DuList *d){//判断回文 
	Node *p=d->head->rightlink;
	Node *q=d->head->rightlink;
	for(int i=0;i<d->n-1;i++){
		q=q->rightlink;
	}
	//初始p指针指向第一个元素结点 q指针指向最后一个元素结点 
	int cnt=0;//指针移动步数 p和q指针每移动一次cnt就加1
	while(cnt<d->n/2){
		//cout<<p->element<<" "<<q->element<<endl;//将每轮比较的数输出 
		if(p->element!=q->element)//若存在对称结点元素不等 则不回文 
			return false;
		p=p->rightlink;q=q->leftlink;//p指针向右q指针向左逐个判断 
		cnt++;
	}
	return true;
}
int main(int argc, char** argv) {
	DuList du;
	Init(&du);
	Input(&du);
	Output(&du);
	cout<<Isreplies(&du)<<endl;
	return 0;
}

在这里插入图片描述
在这里插入图片描述

10、旋转链表

https://leetcode-cn.com/problems/rotate-list/
题目描述:给定链表头结点head,旋转链表,将链表每个结点向右移动k个位置。

示例1:
input:head=[1,2,3,4,5] k=2
output:[4,5,1,2,3]
示例2:
input:head=[0,1,2] k=4
output:[2,0,1]
说明:
k=0 0->1->2
k=1 2->0->1
k=2 1->2->0
k=3 0->1->2
k=4 2->0->1

分析:本题要求将链表旋转,末尾结点移动至头部k个,首先链表选择循环链表,其次指针需要左右移动,选择双向链表,那么本题使用带表头结点的双循环链表。首先初始化链表后,将指针p移至倒数第二个结点,指针q移至末尾结点(q指针所指结点为p指针所指结点后继)(操作Ⅰ);其次由于此链表带表头结点,末尾结点的右指针所指表头结点,此时需要将末尾结点的右指针指向表头结点的下一个结点(第一个元素结点)(操作Ⅱ);然后将p指针和q指针指向需要截断的位置,将其截断(操作Ⅲ);最后通过当前指针q遍历链表将链表输出。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

#include <bits/stdc++.h>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
using namespace std;
const long maxk=2e9;
typedef int ElemType;
typedef long l;
typedef struct node{
	ElemType element;//数据域 
	struct node *rightnext;//右指针域 
	struct node *leftnext;//左指针域 
}Node;
typedef struct headerList{
	int n;//有效长度 
	Node *head;//头指针 
}HeaderList;
void Init(HeaderList *h){//初始化运算 
	h->head=(Node*)malloc(sizeof(Node));
	h->head->rightnext=NULL;
	h->head->element=101;
	h->n=0;
}
bool Input(HeaderList *h,int N){//输入运算 
	if(N>500)
		return false;
	Node *p=h->head;
	Node *q;
	for(int i=0;i<N;i++){
		q=(Node*)malloc(sizeof(Node));
		cin>>q->element;
		q->leftnext=p;
		q->rightnext=p->rightnext;
		p->rightnext=q;
		p=q;
		h->n++;
	}
	q->rightnext=h->head->rightnext;
	return true;
}
bool Rotate(HeaderList *h,l k){//旋转运算 
	if(k>maxk)
		return false;
	Node *p=h->head,*q;
	for(int i=0;i<h->n-1;i++)
		p=p->rightnext;
	q=p->rightnext;//Ⅰ
	h->head->rightnext->leftnext=q; 
	q->rightnext=h->head->rightnext;//Ⅱ
	for(l i=0;i<k-1;i++){
		q=q->leftnext;
		p=p->leftnext;
	}
	p->rightnext=NULL;q->leftnext=NULL;//Ⅲ
	for(int i=0;i<h->n;i++){
		cout<<q->element<<" ";
		q=q->rightnext;
	}
	cout<<endl;	
	return true;
}
void Destory(HeaderList *h){//撤销运算 
	Node *p=h->head;
	Node *q=p->rightnext;
	while(p->rightnext!=NULL){
		p->rightnext=q->rightnext;
		free(q);
		q=p->rightnext;
	}
	free(h->head);
} 
int main(int argc, char** argv) {
	HeaderList hl;
	l K;
	int N;
	Init(&hl);
	cin>>N;
	Input(&hl,N);
	cin>>K;
	Rotate(&hl,K);
	Destory(&hl);
	return 0;
}

在这里插入图片描述
在这里插入图片描述

11、交换链表中的结点

https://leetcode-cn.com/problems/swapping-nodes-in-a-linked-list/
题目描述:给定链表头结点head和整数k,链表长度为n,交换链表中正数第k个结点和倒数第k个结点值后,返回链表。(0<k≤n)

示例1:
input:head=[1,2,3,4,5] k=2
output:[1,4,3,2,5]
示例2:
input:head=[7,9,6,6,7,8,3,0,9,5] k=5
output:[7,9,6,6,8,7,3,0,9,5]
示例3:
input:head=[1] k=1
output:[1]
示例4:
input:head=[1,2] k=1
output:[2,1]
示例5:
input:head=[1,2,3] k=2
output:[1,2,3]
要求:
1、1<=k<=n<=1e5
2、0<=Node.value<=100

分析:本题采用带表头结点的单链表,本体需要交换第k个和倒数第k个结点的值。我们知道如何编写一个程序交换两数的值,即借助第三变量实现交换。此题同理,再申请一个结点空间相当于第三变量,将其中一个值放入其中,另一个值赋值给此值的位置,再将第三变量中的值放入另一值原位置,最后释放第三变量结点空间即可。

#include <bits/stdc++.h>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
using namespace std;
const long maxn=1e5;//最大长度 
typedef int ElemType;
typedef long l;
typedef struct node{
	ElemType element;//数据域 
	struct node *next;//指针域 
}Node;
typedef struct headerList{
	Node *head;//头指针 
	l n;//有效长度 
}HeaderList;
void Init(HeaderList *h){//初始化运算 
	h->head=(Node*)malloc(sizeof(Node));
	h->head->element=101;
	h->head->next=NULL;
	h->n=0;
} 
void Input(HeaderList *h){//输入运算 
	Node *p=h->head;
	for(;;){
		Node *q=(Node*)malloc(sizeof(Node));
		cin>>q->element;
		if(q->element<0||q->element>100||h->n>=maxn)
			break;
		q->next=p->next; 
		p->next=q;
		p=q;
		h->n++;
	}
}
void Output(HeaderList *h){//输出运算 
	Node *p=h->head->next;
	for(;p!=NULL;p=p->next)
		cout<<p->element<<" ";
	cout<<endl;
}
bool SwapNode(HeaderList *h,l k){//交换运算 
	if(k>h->n||k<=0)
		return false;
	Node *p=h->head,*q=p;
	for(int i=0;i<k;i++)
		p=p->next;
	for(int j=0;j<h->n-k+1;j++)
		q=q->next;
	Node *tmp=(Node*)malloc(sizeof(Node));//第三变量存储结点值 
	tmp->element=p->element;
	p->element=q->element;
	q->element=tmp->element;
	free(tmp);
	return true;
}
int main(int argc, char** argv) {
	HeaderList hl;
	l k;
	Init(&hl);
	Input(&hl);
	Output(&hl);
	cin>>k;
	SwapNode(&hl,k);
	Output(&hl);
	return 0;
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

12、链表中的下一个更大结点

题目描述:给定头结点head链表,其结点值分别为:node_1~node_n。每个结点node_i的后继所有结点中可能存在比当前结点node_i值更大的结点,若不存在认为0。将其答案存放至一维数组(answer[i]=next_larger(node_{i+1}))中并返回。

示例1:
input:[2,1,5]
output:[5,5,0]
说明:输出中第一位5表示2的后继中有比2大的值为5;第二位5同理;第三位0表示5后没有比5更大的后继
示例2:
input:[2,7,4,3,5]
output:[7,0,5,5,0]
示例3:
input:[1,7,5,1,9,2,5,1]
output:[7,9,9,9,0,5,0,0]

分析:本题采用带表头结点的单链表。很容易想到遍历链表比较,定义两个指针p、q,指针p所指结点为指针q所指结点的前驱,q指针逐个向后比较,为避免越界表示此轮查找结束未查找到目标值,另再开辟一个tmp结点,其元素值为-INF。若查找到目标值,将其放置数组中;若未查找到目标值,指针q指向tmp结点,当前数组值为0。

#include <bits/stdc++.h>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
using namespace std;
const int maxn=1e4;//最大长度 
const long INF=1e9;
typedef long ElemType;
typedef struct node{
	ElemType element;//数据域 
	struct node *next;//指针域 
}Node;
typedef struct headerList{
	Node *head;//头指针 
	int n;//有效长度 
}HeaderList;
void Init(HeaderList *h){//初始化运算 
	h->head=(Node*)malloc(sizeof(Node));
	h->head->next=NULL;
	h->head->element=INF+1;
	h->n=0;
}
void Input(HeaderList *h){//输入运算 
	Node *p=h->head;
	Node *q;
	for(;;){
		q=(Node*)malloc(sizeof(Node));
		cin>>q->element;
		if(q->element<1||q->element>INF||h->n>=maxn)
			break;
		q->next=p->next;
		p->next=q;
		p=q;
		h->n++;
	}
	Node *tmp=(Node*)malloc(sizeof(Node));//防止越界 
	tmp->element=-INF+1;p->next=tmp;tmp->next=NULL;
}
void Output(HeaderList *h){//输出运算 
	Node *p=h->head->next;
	for(;p!=NULL;p=p->next)
		cout<<p->element<<" ";
	cout<<endl;
}
ElemType* Solve(HeaderList *h){
	Node *p=h->head->next,*q;
	ElemType *ans=(ElemType*)malloc(sizeof(Node)*h->n);//一维数组存放答案 
	int i=0;//当前数组下标 
	while(p->next!=NULL){
		q=p->next;//q指针所指结点为p指针所指结点后继 
		for(;;q=q->next){//q指针开始寻找目标 
			if(q->element>p->element){//寻找到目标 
				ans[i]=q->element;
				i++;
				break;
			}
			if(q->element==-INF+1){//寻找至链表尾部未寻找到目标 
				ans[i]=0;
				i++;
				break;
			}
		}
		p=p->next;//p指针向后移动一个结点 
	}
	return ans;
}
int main(int argc, char** argv) {
	HeaderList hl;
	ElemType *answer;
	Init(&hl);
	Input(&hl);
	Output(&hl);
	answer=Solve(&hl);
	for(int i=0;i<hl.n;i++)
		cout<<answer[i]<<" ";
	cout<<endl;
	return 0;
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

13、奇偶链表

https://leetcode-cn.com/problems/odd-even-linked-list/
题目描述:给定链表,将所有第奇数个结点和第偶数个结点排在一起。

示例1:
input:1->2->3->4->5->NULL
output:1->3->5->2->4->NULL
示例2:
input:2->1->3->5->6->4->7->NULL
output:2->3->6->7->1->5->4->NULL
说明:
示例2中输出的2->3->6->7为原链表第奇数个结点(第1、3、5、7个结点);1->5->4为原链表第偶数个结点(第2、4、6个结点)

分析:本题采用带表头结点的单链表。容易想到定义两个指针,均以步长为2遍历链表,分别得到奇数结点和偶数结点的值,再分别将值插入新链表中。为避免越界,在原链表末尾新增一结点且其指针指向自己本身。将每次访问的结点值依次存入一维数组中,在定义一个新链表,顺序将一维数组中元素插入至新链表中。
在这里插入图片描述

#include <bits/stdc++.h>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
using namespace std;
const int INF=32767;
typedef int ElemType;
typedef struct node{
	ElemType element;//数据域 
	struct node *next;//指针域 
}Node;
typedef struct headerList{
	Node *head;//头指针 
	int n;//有效长度 
}HeaderList;
void Init(HeaderList *h){//初始化运算 
	h->head=(Node*)malloc(sizeof(Node));
	h->head->next=NULL;
	h->head->element=INF;
	h->n=0;
}
void Input(HeaderList *h){//输入运算 
	Node *p=h->head,*q;
	for(;;){
		q=(Node*)malloc(sizeof(Node));
		cin>>q->element;
		if(q->element<=-INF||q->element>=INF)
			break;
		q->next=p->next;
		p->next=q;
		p=q;
		h->n++;
	}
	Node *tmp=(Node*)malloc(sizeof(Node));//防止越界 
	tmp->element=-INF;tmp->next=tmp;p->next=tmp;
}
void Output1(HeaderList *h){//输出原链表运算 
	Node *p=h->head->next;
	for(;p->element!=-INF;p=p->next)
		cout<<p->element<<" ";
	cout<<endl;
}
void Output2(HeaderList *h){//输出新链表运算 
	Node *p=h->head->next;
	for(int i=0;i<h->n;i++){
		cout<<p->element<<" ";
		p=p->next;
	}
	cout<<endl;
}
void Insert(HeaderList *h,int i,ElemType elm){//插入运算 
	Node *p=h->head;
	for(int j=0;j<i;j++)
		p=p->next;
	Node *q=(Node*)malloc(sizeof(Node));
	q->element=elm;
	p->next=q;
	h->n++;
} 
ElemType* Getvalue(HeaderList *h){//获取奇偶结点 
	Node *p=h->head,*q=p->next;
	ElemType* ans=(ElemType*)malloc(sizeof(ElemType)*h->n);//一维数组顺序存放结果 
	int cnt=0; 
	for(;q->element!=-INF;q=q->next->next){//奇数结点 
		ans[cnt]=q->element;
		cnt++;	
	}
	for(;p->element!=-INF;p=p->next->next){//偶数结点 
		if(p->element==INF)
			continue;
		ans[cnt]=p->element;
		cnt++;
	}
	return ans;
}
int main(int argc, char** argv) {
	HeaderList hl,res;
	ElemType *ans;
	Init(&hl);Init(&res);
	Input(&hl);
	Output1(&hl);
	ans=Getvalue(&hl);
	for(int i=0;i<hl.n;i++)
		Insert(&res,i,ans[i]);//将一维数组中元素顺序插入至新链表中	
	Output2(&res);
	return 0;
}

在这里插入图片描述
在这里插入图片描述

14、分割链表

https://leetcode-cn.com/problems/partition-list-lcci/
题目描述:给定头结点head和特定值x,请你对链表进行分割,使所有小于x的结点都出现在大于等于x结点前。

示例1:
input:head=[1,4,3,2,5,2] x=3
output:[1,2,2,4,3,5]
示例2:
input:head=[2,1] x=2
output:[1,2]
说明:示例1中特定值为3,那么链表中顺序小于3的结点为1,2,2;剩余结点4,3,5顺序接在1,2,2后
要求:
1、链表中结点数目范围[0,200]
2、-100<=Node.value<=100
3、-200<=x<=200

分析:本题要求输入一个链表和一个特定值x,将小于特定值x的所有结点顺序放至链表前,将剩余结点顺序放置接着放至链表后。本题采用带表头结点的单链表,首先遍历整个链表,顺序查找出小于特定值的元素,将其存储至一维数组中;然后再将剩余结点元素顺序存储至一维数组中;最后在定义一个新链表,通过尾部插入运算将一维数组中元素存储至新链表中。

#include <bits/stdc++.h>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
using namespace std;
const int INF=100;
const int maxn=200;//最大长度 
int a[maxn];//辅助存储数组 
typedef struct node{
	int element;//数据域 
	struct node *next;//指针域 
}Node;
typedef struct headerList{
	Node *head;//头结点 
	int n;//有效长度 
}HeaderList;
void Init(HeaderList *h){//初始化运算 
	h->head=(Node*)malloc(sizeof(Node));
	h->head->element=-INF-1;
	h->head->next=NULL;
	h->n=0;
}
void Input(HeaderList *h){//输入运算 
	Node *p=h->head;
	for(;;){
		Node *q=(Node*)malloc(sizeof(Node));
		cin>>q->element;
		if(q->element<-INF||q->element>INF||h->n>=maxn)
			break;
		q->next=p->next;
		p->next=q;
		p=q;
		h->n++;
	}
}
void Output(HeaderList *h){//输出运算 
	Node *p=h->head->next;
	for(;p!=NULL;p=p->next)	
		cout<<p->element<<" ";
	cout<<endl; 
}
void Insert(HeaderList *h,int x){//尾部插入运算 
	Node *p=h->head;
	for(int i=0;i<h->n;i++)
		p=p->next;//p指针指向尾部节点 
	Node *q=(Node*)malloc(sizeof(Node));
	q->element=x;
	p->next=q;q->next=NULL; 
	h->n++; 
}
bool Findsmaller(HeaderList *h,HeaderList *h1,int x){//查找小于特定值的结点 
	if(x<-200||x>200)
		return false;
	Node *p=h->head->next;
	int i=0;
	for(;p!=NULL;p=p->next){
		if(x>p->element){
			a[i]=p->element;//将小于特定值的结点元素顺序存入辅助数组中 
			i++;
		}
	}
	for(int j=0;j<i;j++)
		Insert(h1,a[j]);//将小于特定值的结点元素再顺序插入新链表尾部 
	return true;
}
void Solve(HeaderList *h,HeaderList *h1,int x){//剩余结点顺序插入运算 
	Node *p=h->head->next;
	for(;p!=NULL;p=p->next){
		if(x<=p->element)
			Insert(h1,p->element);//再将大于等于特定值的结点元素顺序插入新链表尾部 
	}
} 
int main(int argc, char** argv) {
	HeaderList hl,hl1;
	Init(&hl);Init(&hl1);
	Input(&hl);
	Output(&hl);
	int x;//特定值 
	cin>>x;
	Findsmaller(&hl,&hl1,x);
	Solve(&hl,&hl1,x);
	Output(&hl1); 
	return 0;
}

在这里插入图片描述
在这里插入图片描述

15、K个一组翻转链表

https://leetcode-cn.com/problems/reverse-nodes-in-k-group/
题目描述:给定一个链表,每k个结点进行翻转,返回翻转后链表。若结点总数不是k的整数倍,剩余结点不翻转。

示例1:
input:head=[1,2,3,4,5] k=2
output:[2,1,4,3,5]
说明:将输入的链表[1,2,3,4,5]每2个翻转,那么1和2翻转;3和4翻转;剩余1个结点不翻转
示例2:
input:head=[1,2,3,4,5] k=3
output:[3,2,1,4,5]
示例3:
input:head=[1,2,3,4,5] k=1
output:[1,2,3,4,5]
示例4:
input:head=[1] k=1
output:[1]

分析:本题需要在链表中直接进行修改,仍然选择带表头结点的单链表。本题需要输入一个小于链表长度的正整数k,每k个翻转结点中的元素,我们知道若其所有数据放入一维数组中,实现该功能并不复杂。那就可以先遍历链表将数据顺序放入一个一维数组中,然后在数组中实现每k个一组翻转,最后在顺序遍历数组和链表,逐个更改原链表的每个结点的值即可。
在这里插入图片描述

#include <bits/stdc++.h>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
using namespace std;
const int maxn=5e3;//最大长度 
const int INF=1e3;
typedef struct node{
	int element;//数据域 
	struct node *next;//指针域 
}Node;
typedef struct headerList{
	Node *head;//头指针 
	int n;//有效长度 
}HeaderList;
void Init(HeaderList *h){//初始化运算 
	h->head=(Node*)malloc(sizeof(Node));
	h->head->element=-1;
	h->n=0;
	h->head->next=NULL;
}
void Input(HeaderList *h){//输入运算 
	Node *p=h->head;
	for(;;){
		Node *q=(Node*)malloc(sizeof(Node));
		cin>>q->element;
		if(q->element<0||q->element>INF||h->n>=maxn)
			break;
		q->next=p->next;p->next=q;p=q;
		h->n++; 
	}
}
void Output(HeaderList *h){//输出运算 
	Node *p=h->head->next;
	for(;p!=NULL;p=p->next)
		cout<<p->element<<" ";
	cout<<endl;
}
void Swap(int *a,int *b){//交换运算 
	int tmp=*a;*a=*b;*b=tmp;
}
bool Reverse(HeaderList *h,int *a,int k){//翻转运算 
	if(k<1||k>h->n)//非法情况 
		return false;
	Node *p=h->head->next;
	int i=0;
	for(;p!=NULL;p=p->next)
		a[i++]=p->element;//链表每个结点数据顺序放入一维数组 
	int left,right;
	for(int i=0;i+(k-1)<h->n;i+=k){//分组 
		left=i;right=left+(k-1);
		while(left<right){
			Swap(&a[left],&a[right]);//一组中翻转 
			left++;right--;
		}
	}
	return true;
}
void Change(HeaderList *h,int *a){//直接将一维数组中的值顺序放入链表中 
	Node *p=h->head->next;
	int i=0;
	for(;p!=NULL;p=p->next)
		p->element=a[i++];
}
int main(int argc, char** argv) {
	int k;
	HeaderList hl;
	Init(&hl);
	Input(&hl);
	int *a=(int*)malloc(hl.n*sizeof(int));
	Output(&hl);
	cin>>k;
	if(!Reverse(&hl,a,k))
		exit(0);
	Change(&hl,a);
	Output(&hl);
	free(a);
	return 0;
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

16、反转链表Ⅱ

题目描述:给定一个链表和两个整数left和right(left≤right),将链表从位置left到位置right结点进行反转。返回反转后的链表。

示例1:
input:head=[1,2,3,4,5] left=2 right=4
output:[1,4,3,2,5]
示例2:
input:head=[5] left=1 right=1
output:[5]

分析:本题采用带表头结点的单链表,通过之前的题目,发现当题目要求链表需要进行较复杂的操作时,可以采用一维数组进行存储进行操作,然后将一维数组数值覆盖原链表即可。本题可以将需要反转的部分存储至一维数组中,通过交换函数实现反转,然后覆盖原链表被更改的部分,返回原链表即可。
在这里插入图片描述

#include <bits/stdc++.h>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
using namespace std;
const int maxn=500;//最大长度 
typedef struct node{
	int element;//数据域 
	struct node *next;//指针域 
}Node;
typedef struct headerList{
	int n;//有效长度 
	Node *head;//头指针 
}HeaderList;
void Init(HeaderList *h){//初始化运算 
	h->n=0;
	h->head=(Node*)malloc(sizeof(Node));
	h->head->element=maxn+1;
	h->head->next=NULL;
}
void Input(HeaderList *h){//输入运算 
	Node *p=h->head;
	for(;;){
		Node *q=(Node*)malloc(sizeof(Node));
		cin>>q->element;
		if(h->n>=maxn||q->element<-maxn||q->element>maxn)
			break;
		q->next=p->next;
		p->next=q;
		p=q;
		h->n++;
	}
}
void Output(HeaderList *h){//输出运算 
	Node *p=h->head->next;
	for(;p!=NULL;p=p->next)
		cout<<p->element<<" ";
	cout<<endl;
}
void Swap(int *a,int *b){//交换运算 
	int tmp;
	tmp=*a;
	*a=*b;
	*b=tmp;
}
void Solve(HeaderList *h,int *a,int left,int right){
	Node *p=h->head->next;
	for(int i=0;i<left-1;i++)
		p=p->next;
	Node *q=p;//Ⅰ 
	int cnt=0;
	while(cnt<(right-left)+1){
		a[cnt]=p->element;
		cnt++;
		p=p->next;
	}//Ⅱ 
	int lft=0,rig=right-left;
	while(lft<=rig){ 
		Swap(&a[lft],&a[rig]);
		lft++;rig--;
	}//Ⅲ 
	for(int i=0;i<(right-left)+1;i++){
		q->element=a[i];
		q=q->next;
	}//Ⅳ 
}
int main(int argc, char** argv) {
	HeaderList hl;
	Init(&hl);
	Input(&hl);
	int left,right;
	cin>>left>>right;
	if(left>right)
		exit(0);
	int *a=(int*)malloc(sizeof(int)*(right-left)+1);
	Solve(&hl,a,left,right);
	Output(&hl);
	free(a); 
	return 0;
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

17、两数相加

https://leetcode-cn.com/problems/add-two-numbers/
题目描述:给定两个非空链表,表示两个非负整数。它们每位数字都是按照逆序方式存储,每个结点存放一位数字。将两个链表对应的数相加。

示例1:
input:l1=[2,4,3] l2=[5,6,4]
output:[7,0,8]
说明:342+465=807
示例2:
input:l1=[0] l2=[0]
output:[0]
示例3:
input:l1=[9,9,9,9,9,9,9] l2=[9,9,9,9]
output:[8,9,9,9,0,0,0,1]

分析:本题采用带表头结点的单链表,本题需要对两个链表表示的逆序数进行相加运算,两数相加有进位情况,部分情况下加出来的数相较于原结点数会多。考虑极限情况:①两个链表结点数相同,如999+999=1998,极限情况为较于链表长度多一位。②两个链表结点数不同,如99+999=1098,999+99999=100998,极限情况为较于两链表更长的长度还多一位。为便于相加,先读取待加两链表长度,根据两种极限情况,补充足够的0(如下图)。定义两个指针p,q分别指向链表1,链表2的最低位,每一次求和结束,两指针均向后移动,直至遇空。另外为节约空间,无需再声明第三个链表,直接将每一位相加结果覆盖第二个链表中的结点。在相加时,需要判断当前和是否需要进位,IfC函数返回是否需要进位的布尔值。
在这里插入图片描述

#include <bits/stdc++.h>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
using namespace std;
const int maxn=100;
typedef struct node{
	int val;//数据域 
	struct node *next;//指针域 
}Node;
typedef struct headerList{
	int n;//有效长度 
	Node *head;//头指针 
}HeaderList;
void Init(HeaderList *h){//初始化运算 
	h->head=(Node*)malloc(sizeof(Node));
	h->n=0;
	h->head->val=0;
	h->head->next=NULL;
}
bool Input(HeaderList *h,int n){//输入运算 
	if(h->n>maxn)
		return false;
	Node *p=h->head;
	h->n=n;
	for(int i=0;i<n;i++){
		Node *q=(Node*)malloc(sizeof(Node));
		cin>>q->val;
		if(q->val<0||q->val>9)
			return false;
		q->next=p->next;
		p->next=q;
		p=q;
	}
	return true;
}
void AddZero(HeaderList *h1,HeaderList *h2){//加零操作 
	if(h1->n>h2->n){//h1长度大于h2长度 
		int num=abs(h1->n-h2->n);
		Node *p=h2->head->next;
		for(int i=0;i<h2->n-1;i++)
			p=p->next;
		for(int j=0;j<num;j++){
			Node *x=(Node*)malloc(sizeof(Node));
			x->val=0;
			p->next=x;x->next=NULL;
			p=x;
			h2->n++;
		}
	}
	else if(h1->n<h2->n){//h1长度小于h2长度
		int num=abs(h1->n-h2->n);
		Node *p=h1->head->next;
		for(int i=0;i<h1->n-1;i++)
			p=p->next;
		for(int j=0;j<num;j++){
			Node *x=(Node*)malloc(sizeof(Node));
			x->val=0;
			p->next=x;x->next=NULL;
			p=x;
			h1->n++;
		}
	}
	else{//h1长度等于h2长度
		Node *p=h1->head->next,*q=h2->head->next;
		for(int i=0;i<h1->n-1;i++){
			p=p->next;
			q=q->next;
		}
		Node *x=(Node*)malloc(sizeof(Node));
		Node *y=(Node*)malloc(sizeof(Node));
		x->val=0;x->next=NULL;
		y->val=0;y->next=NULL;
		p->next=x;q->next=y;
		h1->n++;h2->n++;
	}
}
void Output(HeaderList *h){//输出运算 
	Node *p=h->head->next;
	for(;p!=NULL;p=p->next)
		cout<<p->val<<" ";
	cout<<endl;
}
bool IfC(int a,int b){//判断当前位数和是否需要进位 
	if(a+b>=10)
		return true;
	return false;
}
void Add(HeaderList *h1,HeaderList *h2){//结点求和操作 
	Node *p=h1->head->next,*q=h2->head->next;
	while(p!=NULL){
		if(IfC(p->val,q->val)){//需要进位 
			q->val=(p->val+q->val)%10;//取个位值 
			q->next->val+=1;//进位 
			p=p->next;q=q->next;
		}
		else{//无需进位 
			q->val=p->val+q->val;//直接相加 
			p=p->next;q=q->next;
		}
	}
}
int main(int argc, char** argv) {
	int n1,n2;
	cin>>n1>>n2;
	HeaderList hl,hl1;
	Init(&hl);Init(&hl1);
	Input(&hl,n1);Input(&hl1,n2);
	AddZero(&hl,&hl1);
	AddZero(&hl,&hl1);
	//Output(&hl);Output(&hl1);
	Add(&hl,&hl1);
	Output(&hl1);
	return 0;
}

在这里插入图片描述
在这里插入图片描述

;