链表练习索引
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;
}