1.创建有序单链表
【问题描述】为从键盘终端输入的m个整数创建带头结点的有序单链表存储结构,使输入的数据元素在单链表中按照元素值递增有序。
【输入形式】
第一行:单链表中元素个数m
第二行:单链表中的m个整数
【输出形式】
按递增有序形式输出m个整数
【样例输入】
5
1 3 2 4 5
【样例输出】
1 2 3 4 5
【样例说明】
【评分标准】
#include <iostream>
using namespace std;
struct Node {
int data;
Node *next;
};
typedef Node *LinkList;
void createOList(LinkList &L,int m)
{
int num,i=0,s[m];
while(cin>>num)
{
s[i++]=num;
}
for(int i=0;i<m-1;i++)
{
for(int j=i+1;j<m;j++)
{
if(s[i]>s[j])
{
int t=0;
t=s[i];
s[i]=s[j];
s[j]=t;
}
}
}
Node *p,*r;
L=new Node;
L->next=NULL;
r=L;
i=0;
while(m)
{
p=new Node;
p->data=s[i++];
r->next=p;
r=p;
m--;
}
r->next=NULL;
}
void printList(LinkList L) {
Node *p;
p=L->next;
while(p) {
cout<<p->data<<" ";
p=p->next;
}
cout<<endl;
}
int main() {
LinkList L;
int m;
cin>>m;//单链表中元素个数
createOList(L,m);//创建带头节点的有序单链表
printList(L);
return 0;
}
2.输出单链表中的数据并统计单链表中的元素个数
【问题描述】下面程序中createList函数的功能是创建若干个整数的带头结点的单链表存储结构。getLength函数的功能是求解单链表中元素的个数,printLst函数的功能是将单链表中各个整数以空格间隔顺序输出。根据上下文,将程序补充完整。
【输入形式】若干整数以空格间隔
【输出形式】两行。第一行:单链表中的整数以空格间隔输出;第二行:单链表中元素的个数
【样例输入】1 2 3 4 5
【样例输出】
1 2 3 4 5
5
【样例说明】
【评分标准】
#include <iostream>
#include <cstdlib>
using namespace std;
struct LNode
{
int data;
LNode *next;
};
void createList(LNode *&h)
{
int num;
LNode *p,*r;
h=new LNode;
h->next=NULL;
r=h;
while(cin>>num)
{
p=new LNode;
p->data=num;
r->next=p;
r=p;
}
r->next=NULL;
}
int getLength(LNode *&L)
{
LNode *p;
int length=0;
p=L->next;
while(p) {
p=p->next;
length++;
}
return length;
}
void printList(LNode *&L)
{
LNode *p;
p=L->next;
while(p) {
cout<<p->data<<" ";
p=p->next;
}
cout<<endl;
}
int main()
{
LNode *L;
createList(L);
printList(L);
cout<<getLength(L);
return 0;
}
3.删除单链表中相同元素
【问题描述】单链表中存放了若干整数,请删除相同整数。
【输入形式】单链表
【输出形式】删除相同整数后的单链表
【样例输入】1 1 1 2 3
【样例输出】1 2 3
【样例说明】以递增的形式输入数据,允许相同元素
【评分标准】
#include <stdlib.h>
#include <iostream>
using namespace std;
//类型定义
#include <stdlib.h>
struct LNode
{
int data;
LNode *next;
};
typedef LNode *LinkList;
//尾插入法创建单链表
void createList(LinkList &h, int n)
{
h = new LNode;
h->next = NULL;
LNode *p, *r;
r = h;
for (int i = 1; i <= n; i++)
{
p = new LNode;
cin>>p->data;
r->next = p;
r = p;
}
r->next = NULL;
}
void printList(LinkList h)
{
LNode *p=h->next;
while(p)
{
cout<<p->data<<" ";
p=p->next;
}
cout<<endl;
}
void listDeleteRepeat(LinkList h)
{
LNode *p=h->next;
while(p)
{
LNode *q=p;
while(q->next)
{
if(q->next->data==p->data)
{
LNode *tmp=q->next;
q->next=q->next->next;
delete tmp;
}
else{
q=q->next;
}
}
p=p->next;
}
}
int main()
{
LinkList h;
createList(h, 5);
listDeleteRepeat(h);
printList(h);
return 0;
}
4.删除单链表中某区间的数
【问题描述】已知某带头结点的单链表中存放着若干整数,请删除该单链表中元素在[x, y]之间的所有结点,要求算法的时间复杂度为O(n),空间复杂度为O(1)。
【输入形式】第一行:单链表中元素个数m
第二行:单链表中的m个整数
第三行:要删除的元素值所在区间[x,y]对应的x和y
【输出形式】
删除元素后的单链表中剩下的元素值
【样例输入】
5
13 24 50 33 56
30 50
【样例输出】
13 24 56
【样例说明】
【评分标准】
#include <iostream>
using namespace std;
struct Node {
int data;
Node *next;
};
typedef Node *LinkList;
void createList(LinkList &L,int n) {
Node *p,*r;
L=new Node;
L->next=NULL;
r=L;
for(int i=1; i<=n; i++) {
p=new Node;
cin>>p->data;
r->next=p;
r=p;
}
r->next=NULL;
}
void printList(LinkList L) {
Node *p;
p=L->next;
while(p) {
cout<<p->data<<" ";
p=p->next;
}
cout<<endl;
}
void delElem(LinkList h,int a,int b)
{
Node *p,*c;
p=h,c=h->next;//c为p的下一个结点
while(c)
{
if(c->data>=a&&c->data<=b)
{
p->next=c->next;
delete c;
c=p->next;
}
else
{
p=p->next;
c=c->next;
}
}
}
int main() {
LinkList L;
int m;
int x,y;
cin>>m;//单链表中元素个数
createList(L,m);//尾插入法创建带头节点的单链表
cin>>x>>y;//要删除的元素值所在区间[x,y],包含x和y
delElem(L,x,y);//删除单链表中x-y之间的数
printList(L);//输出结果单链表中的所有数据
return 0;
}
5.倒数第k个元素
【问题描述】已知带头结点的非空单链表中存放着若干整数,请找出该链表中倒数第k个元素。
【输入形式】第一行:单链表中元素个数m
第二行:单链表中的m个整数
第三行:k值
【输出形式】倒数第k个元素的值(不存在倒数第k个元素输出"no")
【样例输入】
5
13 24 50 33 56
2
【样例输出】
33
【样例说明】
输入:
5
13 24 50 33 56
6
输出:no
【评分标准】
#include <iostream>
using namespace std;
struct Node {
int data;
Node *next;
};
typedef Node *LinkList;
void createList(LinkList &L,int n) {
Node *p,*r;
L=new Node;
L->next=NULL;
r=L;
for(int i=1; i<=n; i++) {
p=new Node;
cin>>p->data;
r->next=p;
r=p;
}
r->next=NULL;
}
void printList(LinkList L) {
Node *p;
p=L->next;
while(p) {
cout<<p->data<<" ";
p=p->next;
}
cout<<endl;
}
Node *getElem(LinkList L,int k)
{
int count=0;
Node *p,*a;
p=L->next;//p指向第二个结点
a=L->next;
while(p)
{
if(count<k)
count++;
else
a=a->next;
p=p->next;
}
if(count==k)
return a;
else
return 0;
}
int main() {
LinkList L;
int m,k;
cin>>m;//单链表中元素个数
createList(L,m);//尾插入法创建带头节点的单链表
cin>>k;
Node *p=getElem(L,k);//找单链表中倒数第k个元素
if(p)
cout<<p->data;
else
cout<<"no";
return 0;
}
6.查找两个单链表的公共结点
【问题描述】给定两个单链表,编写算法找出两个链表的公共结点
【输入形式】用于构造两个公共链表的结点数和数据元素的值
【输出形式】两个单链表所有公共结点的元素值以空格间隔输出
【样例输入】若构建的两个链表结构如下图所示:则公共结点为数据值为11和15的结点。
【样例输出】11 15
【样例说明】
【评分标准】
#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;
struct LNode
{
int data;
LNode *next;
};
typedef LNode *Linklist;
void create(Linklist &h,int n)
{
LNode *r,*p;
h=new LNode;
h->next=NULL;
r=h;
for(int i=1; i<=n; i++)
{
p=new LNode;
cin>>p->data;
r->next=p;
r=p;
}
r->next=NULL;
}
void create(Linklist &h)
{
LNode *r,*p;
srand(time(NULL));
int i,m;
m=rand()%10;
h=new LNode;
h->next=NULL;
r=h;
for(int i=1; i<=m; i++)
{
p=new LNode;
p->data=rand()%90+10;
r->next=p;
r=p;
}
r->next=NULL;
}
LNode *getTail(Linklist h)
{
LNode *tail;
tail=h;
while(tail->next)
{
tail=tail->next;
}
return tail;
}
void connect(Linklist ha,Linklist hb)
{
LNode *r;
r=getTail(ha);
r->next=hb->next;
}
void printList(Linklist h)
{
LNode *p=h->next;
while(p)
{
cout<<p->data<<" ";
p=p->next;
}
cout<<endl;
}
void printPublicNode(Linklist ha, Linklist hb)
{
LNode *pa = ha->next;
while (pa)
{
LNode *pb = hb->next;
while (pb)
{
if (pa == pb)
{
cout << pa->data << " ";
break;
}
pb = pb->next;
}
pa = pa->next;
}
}
int main()
{
Linklist ha,hb,hc;
int n;
cin>>n;
create(ha);
create(hb);
create(hc,n);
connect(ha,hc);
connect(hb,hc);
printPublicNode(ha,hb);
return 0;
}
7.有序集合的并集-无重复数据-单链表
【问题描述】将两个递增的有序链表合并为一个递增的有序链表。要求结果链表仍使用原来的两个链表的存储空间,不另外占用其他的存储空间。表中允许有重复的数据。
【输入形式】三行,第一行:两个有序链表中元素的个数,第二行:第一个链表中的元素以空格间隔,第三行:第二个链表中的元素以空格间隔
【输出形式】合并后的没有重复元素的有序链表中的数据以空格间隔
【样例输入】
3 4
1 5 7
2 4 7 9
【样例输出】1 2 4 5 7 9
【样例说明】
【评分标准】
#include <bits/stdc++.h>
using namespace std;
struct OLNode
{
int data;
OLNode *next;
};
typedef OLNode *OLinkList;
OLNode *getPre(OLinkList h,int e)
{
OLNode *pre=h;
while(pre->next&&pre->next->data<e)
pre=pre->next;
return pre;
}
void createOLinkList(OLinkList &h,int n)
{
h=new OLNode;
h->next=NULL;
OLNode *pre,*p;
int e;
for(int i=1; i<=n; i++)
{
cin>>e;
p=new OLNode;
p->data=e;
pre=getPre(h,e);
p->next=pre->next;
pre->next=p;
}
}
void printOLinkList(OLinkList h)
{
OLNode *p;
p=h->next;
while(p)
{
cout<<p->data<<" ";
p=p->next;
}
cout<<endl;
}
void olistUnion(OLinkList ha, OLinkList hb)
{
OLinkList h = ha;
OLinkList p = ha->next;
OLinkList q = hb->next;
while (p && q) {
if (p->data < q->data) {
h->next = p;
h = p;
p = p->next;
}
else if (p->data > q->data) {
h->next = q;
h = q;
q = q->next;
}
else {
// 两个节点的数据相等,保留一个节点并删除另一个节点
h->next = p;
h = p;
p = p->next;
OLinkList tmp = q->next;
delete q;
q = tmp;
}
}
h->next = p ? p : q; // 将剩余部分接入新链表
delete hb; // 释放链表hb的头结点
}
int main()
{
int m,n;
OLinkList ha,hb;
cin>>m>>n;
createOLinkList(ha,m);
createOLinkList(hb,n);
olistUnion(ha,hb);
printOLinkList(ha);
return 0;
}
8.有序集合的并集-单链表
【问题描述】将两个递增的有序链表合并为一个递增的有序链表。要求结果链表仍使用原来的两个链表的存储空间,不另外占用其他的存储空间。表中允许有重复的数据。
【输入形式】三行,第一行:两个有序链表中元素的个数,第二行:第一个链表中的元素以空格间隔,第三行:第二个链表中的元素以空格间隔
【输出形式】合并后的没有重复元素的有序链表中的数据以空格间隔
【样例输入】
3 4
1 5 7
2 4 7 9
【样例输出】1 2 4 5 7 7 9
【样例说明】
【评分标准】
#include <bits/stdc++.h>
using namespace std;
struct OLNode
{
int data;
OLNode *next;
};
typedef OLNode *OLinkList;
OLNode *getPre(OLinkList h,int e)
{
OLNode *pre=h;
while(pre->next&&pre->next->data<e)
pre=pre->next;
return pre;
}
void createOLinkList(OLinkList &h,int n)
{
h=new OLNode;
h->next=NULL;
OLNode *pre,*p;
int e;
for(int i=1; i<=n; i++)
{
cin>>e;
p=new OLNode;
p->data=e;
pre=getPre(h,e);
p->next=pre->next;
pre->next=p;
}
}
void printOLinkList(OLinkList h)
{
OLNode *p;
p=h->next;
while(p)
{
cout<<p->data<<" ";
p=p->next;
}
cout<<endl;
}
void olistUnion(OLinkList ha, OLinkList hb)
{
OLinkList h = ha;
OLinkList p = ha->next;
OLinkList q = hb->next;
while (p && q) {
if (p->data <= q->data) {
h->next = p;
h = p;
p = p->next;
}
else if (p->data > q->data) {
h->next = q;
h = q;
q = q->next;
}
}
h->next = p ? p : q; // 将剩余部分接入新链表
delete hb; // 释放链表hb的头结点
}
int main()
{
int m,n;
OLinkList ha,hb;
cin>>m>>n;
createOLinkList(ha,m);
createOLinkList(hb,n);
olistUnion(ha,hb);
printOLinkList(ha);
return 0;
}