目录
10.将一个带头节点的单链表A分解为两个带头节点的单链表A和B,使得A表中含有原表中序号为奇数的元素,而B表中含有原表中序号为偶数的元素,且保持其相对顺序不变。
13假设有两个按元素值递增次序排列的线性表,均以单链表形式存储,请编写算法将这两个单链表归并为一个按元素值递减次序排列的单链表,并要求利用原来的两个单链表的节点存放归并后的单链表。
14.设A和B是两个单链表(带头节点),其中元素递增有序。设计一个算法从A和B中的公共元素产生单链表C,要求不破坏A,B的节点。
15.已知两个链表A和B分别表示两个集合,其元素递增排列。编制函数,求A与B的交集,并存放于A链表中。
16.两个整数序列A=a1,a2,...,am,B=b1,b2,...,bn。已经存入两个单链表中,设计一个算法,判断序列B是否是序列A的连续子序列。
18.有两个循环单链表,链表头指针分别为h1和h2,编写一个函数将链表h2链接到链表h1之后,要求链接后的链表仍保持循环链表形式。
其他-王道数据结构算法题-链表题,如下
扫描二维码关注公众号,回复:
14318397 查看本文章
10.将一个带头节点的单链表A分解为两个带头节点的单链表A和B,使得A表中含有原表中序号为奇数的元素,而B表中含有原表中序号为偶数的元素,且保持其相对顺序不变。
代码实现:
//分链表
#include<iostream>
using namespace std;
typedef struct lnode{
int data;
struct lnode *next;
}lnode,*linklist;
int a[5]={2,7,4,1,9};
int n=5;
void buildlist(linklist &L)
{
L=(linklist)malloc(sizeof(lnode));
lnode *r=L,*s;
for(int i=0;i<n;i++)
{
s=(lnode *)malloc(sizeof(lnode));
s->data=a[i];
r->next=s;
r=r->next;
}
r->next=NULL;
}
void disp(linklist L)
{
lnode *s=L->next;
while(s)
{
cout<<s->data<<" ";
s=s->next;
}
cout<<endl;
}
linklist L2;
void cut(linklist &L1)
{
L2=(linklist)malloc(sizeof(lnode));
L2->next=NULL;
lnode *r1=L1,*r2=L2,*p=L1->next;
int i=0;
L1->next=NULL;
while(p)
{
i++;
if(i%2==0)
{
r2->next=p;
r2=p;
}
else
{
r1->next=p;
r1=p;
}
p=p->next;
}
r1->next=NULL;
r2->next=NULL;
}
int main()
{
linklist L1;
buildlist(L1);
cout<<"之前"<<endl;
disp(L1);
cut(L1);
cout<<"L1: "<<endl;
disp(L1);
cout<<"L2"<<endl;
disp(L2);
return 0;
}
11.设C={a1,b1,a2,b2,...,an,bn}为线性表,采用带头节点的hc单链表存放,设计一个就地算法,将其拆分为两个线性表,使得A={a1,a2,...,an},B={bn,...,b2,b1}。
代码实现:
//链表拆分 头插法
#include<iostream>
using namespace std;
typedef struct lnode{
int data;
struct lnode *next;
}lnode,*linklist;
int a[10]={1,2,3,4,5,6,7,8,9,10};
int n=10;
void buildlist(linklist &L)
{
L=(linklist)malloc(sizeof(lnode));
lnode *s,*r=L;
for(int i=0;i<n;i++)
{
s=(lnode *)malloc(sizeof(lnode));
s->data=a[i];
r->next=s;
r=r->next;
}
r->next=NULL;
}
void disp(linklist L)
{
lnode *s=L->next;
while(s)
{
cout<<s->data<<" ";
s=s->next;
}
cout<<endl;
}
linklist L2;
void cutlist(linklist &L1)
{
L2=(linklist)malloc(sizeof(lnode));
L2->next=NULL;
lnode *p=L1->next,*q,*r=L1;
while(p)
{
r->next=p;
r=p;
p=p->next;
if(p!=NULL) q=p->next;
p->next=L2->next;
L2->next=p;
p=q;
}
r->next=NULL;
}
int main()
{
linklist L1;
buildlist(L1);
cout<<"一开始L1"<<endl;
disp(L1);
cutlist(L1);
cout<<"之后L1"<<endl;
disp(L1);
cout<<"之后L2"<<endl;
disp(L2);
return 0;
}
12.在一个递增有序的线性表中,有数值相同的元素存在。若存储方式为单链表,设计算法去掉数值相同的元素,使得表中不再有重复的元素,例如{7,10,10,21,30,42,42,42,51,70}将其变为{7,10,21,30,42,51,70}。
代码实现:
//链表的重复元素删除
#include<iostream>
using namespace std;
typedef struct lnode{
int data;
struct lnode *next;
}lnode,*linklist;
int a[10]={7,10,10,21,30,42,42,42,51,70};
int n=10;
void buildlist(linklist &L)
{
L=(linklist)malloc(sizeof(lnode));
lnode *s,*r=L;
for(int i=0;i<n;i++)
{
s=(lnode *)malloc(sizeof(lnode));
s->data=a[i];
r->next=s;
r=r->next;
}
r->next=NULL;
}
void disp(linklist L)
{
lnode *s=L->next;
while(s)
{
cout<<s->data<<" ";
s=s->next;
}
cout<<endl;
}
void deletelist(linklist &L)
{
if(L->next==NULL) return;
lnode *p=L->next,*q;
while(p->next!=NULL)
{
q=p->next;
if(p->data==q->data)
{
p->next=q->next;
free(q);
}
else p=p->next;
}
}
int main()
{
linklist L;
buildlist(L);
cout<<"删除之前"<<endl;
disp(L);
deletelist(L);
cout<<"删除之后"<<endl;
disp(L);
return 0;
}
13假设有两个按元素值递增次序排列的线性表,均以单链表形式存储,请编写算法将这两个单链表归并为一个按元素值递减次序排列的单链表,并要求利用原来的两个单链表的节点存放归并后的单链表。
代码实现:
//合并链表 递减
#include<iostream>
using namespace std;
typedef struct lnode{
int data;
struct lnode *next;
}lnode,*linklist;
int a[4]={1,2,3,4};
int b[5]={3,4,5,6,7};
int n1=4,n2=5;
void buildlist(linklist &L,int aa[],int n)
{
L=(linklist)malloc(sizeof(lnode));
lnode *r=L,*s;
for(int i=0;i<n;i++)
{
s=(lnode *)malloc(sizeof(lnode));
s->data=aa[i];
r->next=s;
r=r->next;
}
r->next=NULL;
}
void disp(linklist L)
{
lnode *s=L->next;
while(s)
{
cout<<s->data<<" ";
s=s->next;
}
cout<<endl;
}
void merge(linklist &L1,linklist &L2)
{
lnode *p1=L1->next,*p2=L2->next,*r;
L1->next=NULL;
while(p1&&p2)
{
if(p1->data<=p2->data)
{
r=p1->next;
p1->next=L1->next;
L1->next=p1;
p1=r;
}
else
{
r=p2->next;
p2->next=L1->next;
L1->next=p2;
p2=r;
}
}
if(p1) p2=p1;
while(p2)
{
r=p2->next;
p2->next=L1->next;
L1->next=p2;
p2=r;
}
free(L2);
}
int main()
{
linklist L1,L2;
buildlist(L1,a,n1);
buildlist(L2,b,n2);
cout<<"L1:"<<endl;
disp(L1);
cout<<"L2:"<<endl;
disp(L2);
merge(L1,L2);
cout<<"合并之后"<<endl;
disp(L1);
return 0;
}
14.设A和B是两个单链表(带头节点),其中元素递增有序。设计一个算法从A和B中的公共元素产生单链表C,要求不破坏A,B的节点。
代码实现:
//找共同元素 建立新链表
#include<iostream>
using namespace std;
typedef struct lnode{
int data;
struct lnode *next;
}lnode,*linklist;
int a[4]={2,3,4,9};
int n1=4;
int b[5]={4,7,9,10,11};
int n2=5;
void buildlist(linklist &L,int aa[],int n)
{
L=(linklist)malloc(sizeof(lnode));
lnode *s,*r=L;
for(int i=0;i<n;i++)
{
s=(lnode *)malloc(sizeof(lnode));
s->data=aa[i];
r->next=s;
r=r->next;
}
r->next=NULL;
}
void disp(linklist L)
{
lnode *s=L->next;
while(s)
{
cout<<s->data<<" ";
s=s->next;
}
cout<<endl;
}
linklist L3;
void buildnew(linklist L1,linklist L2)
{
L3=(linklist)malloc(sizeof(lnode));
lnode *p1=L1->next,*p2=L2->next,*s,*r;
r=L3;
while(p1&&p2)
{
if(p1->data<p2->data) p1=p1->next;
else if(p1->data>p2->data) p2=p2->next;
else
{
s=(lnode *)malloc(sizeof(lnode));
s->data=p1->data;
r->next=s;
r=s;
p1=p1->next;
p2=p2->next;
}
}
r->next=NULL;
}
int main()
{
linklist L1,L2;
buildlist(L1,a,n1);
buildlist(L2,b,n2);
cout<<"L1:"<<endl;
disp(L1);
cout<<"L2:"<<endl;
disp(L2);
buildnew(L1,L2);
cout<<"L3:"<<endl;
disp(L3);
return 0;
}
15.已知两个链表A和B分别表示两个集合,其元素递增排列。编制函数,求A与B的交集,并存放于A链表中。
代码实现:
//保留公共节点 其余删除
#include<iostream>
using namespace std;
typedef struct lnode{
int data;
struct lnode *next;
}lnode,*linklist;
int a[4]={1,2,3,4};
int b[6]={2,4,5,6,7,8};
int n1=4,n2=6;
void buildlist(linklist &L,int aa[],int n)
{
L=(linklist)malloc(sizeof(lnode));
lnode *s,*r=L;
for(int i=0;i<n;i++)
{
s=(lnode *)malloc(sizeof(lnode));
s->data=aa[i];
r->next=s;
r=r->next;
}
r->next=NULL;
}
void disp(linklist L)
{
lnode *s=L->next;
while(s)
{
cout<<s->data<<" ";
s=s->next;
}
cout<<endl;
}
void deletelist(linklist &L1,linklist &L2)
{
lnode *p1=L1->next,*p2=L2->next,*r=L1,*q;
while(p1&&p2)
{
if(p1->data<p2->data)
{
q=p1;
p1=p1->next;
free(q);
}
else if(p1->data>p2->data)
{
q=p2;
p2=p2->next;
free(q);
}
else
{
r->next=p1;
r=p1;
p1=p1->next;
q=p2;
p2=p2->next;
free(q);
}
}
while(p1)
{
q=p1;
p1=p1->next;
free(q);
}
while(p2)
{
q=p2;
p2=p2->next;
free(q);
}
r->next=NULL;
}
int main()
{
linklist L1,L2;
buildlist(L1,a,n1);
buildlist(L2,b,n2);
cout<<"L1"<<endl;
disp(L1);
cout<<"L2"<<endl;
disp(L2);
deletelist(L1,L2);
cout<<"L1"<<endl;
disp(L1);
return 0;
}
16.两个整数序列A=a1,a2,...,am,B=b1,b2,...,bn。已经存入两个单链表中,设计一个算法,判断序列B是否是序列A的连续子序列。
代码实现:
//判断是否是连续子序列
#include<iostream>
using namespace std;
typedef struct lnode{
int data;
struct lnode *next;
}lnode,*linklist;
int a[6]={1,2,3,4,5,6};
int b[3]={3,4,5};
int n1=6,n2=3;
void buildlist(linklist &L,int aa[],int n)
{
L=(linklist)malloc(sizeof(lnode));
lnode *s,*r=L;
for(int i=0;i<n;i++)
{
s=(lnode *)malloc(sizeof(lnode));
s->data=aa[i];
r->next=s;
r=r->next;
}
r->next=NULL;
}
bool isok(linklist L1,linklist L2)
{
lnode *p1=L1->next,*p2=L2->next,*r=L1->next;
while(p1&&p2)
{
if(p1->data!=p2->data)
{
r=r->next;
p1=r;
p2=L2->next;
}
else
{
p1=p1->next;
p2=p2->next;
}
}
if(p2) return false;
else return true;
}
int main()
{
linklist L1,L2;
buildlist(L1,a,n1);
buildlist(L2,b,n2);
if(isok(L1,L2)) cout<<"yes"<<endl;
else cout<<"no"<<endl;
return 0;
}
若 3 , 4 ,7则不是
17.设计一个算法用于判断带头节点的循环双链表是否对称。
代码实现:
//判断循环双链表是否是对称的
#include<iostream>
using namespace std;
typedef struct lnode{
int data;
struct lnode *next,*prior;
}lnode,*linklist;
int a[6]={1,2,3,3,2,1};
int n=6;
void buildlist(linklist &L)
{
L=(linklist)malloc(sizeof(lnode));
lnode *s,*r=L;
L->prior=L;
L->next=L;
for(int i=0;i<n;i++)
{
s=(lnode *)malloc(sizeof(lnode));
s->data=a[i];
s->next=r->next;
r->next->prior=s;
s->prior=r;
r->next=s;
r=s;
L->prior=s;
}
}
void disp(linklist L)
{
lnode *s=L->next;
while(s!=L)
{
cout<<s->data<<" ";
s=s->next;
}
cout<<endl;
}
bool isok(linklist L)
{
lnode *p=L->next,*q=L->prior;
while(p!=q&&q->next!=p)
{
if(p->data==q->data)
{
p=p->next;
q=q->prior;
}
else return false;
}
return true;
}
int main()
{
linklist L;
buildlist(L);
disp(L);
if(isok(L))cout<<"yes"<<endl;
else cout<<"no"<<endl;
return 0;
}
1,2,3,4,2,1很明显不对称
18.有两个循环单链表,链表头指针分别为h1和h2,编写一个函数将链表h2链接到链表h1之后,要求链接后的链表仍保持循环链表形式。
代码实现:
//循环单链表的拼接
#include<iostream>
using namespace std;
typedef struct lnode{
int data;
struct lnode *next;
}lnode,*linklist;
int a[4]={1,2,3,4};
int b[5]={5,6,7,8,9};
int n1=4,n2=4;
void buildlist(linklist &L,int aa[],int n)
{
L=(linklist)malloc(sizeof(lnode));
lnode *s,*r=L;
for(int i=0;i<n;i++)
{
s=(lnode *)malloc(sizeof(lnode));
s->data=aa[i];
r->next=s;
r=r->next;
}
r->next=L;
}
void disp(linklist L)
{
lnode *s=L->next;
while(s!=L)
{
cout<<s->data<<" ";
s=s->next;
}
cout<<endl;
}
void add(linklist &L1,linklist &L2)
{
lnode *p=L1->next,*q=L2->next;
while(p->next!=L1)
{
p=p->next;
}
while(q->next!=L2){
q=q->next;
}
p->next=L2->next;
q->next=L1;
}
int main()
{
linklist L1,L2;
buildlist(L1,a,n1);
buildlist(L2,b,n2);
cout<<"L1"<<endl;
disp(L1);
cout<<"L2"<<endl;
disp(L2);
add(L1,L2);
cout<<"L1"<<endl;
disp(L1);
return 0;
}