7-1 重排链表
给定一个单链表 L1→L2→⋯→Ln−1→Ln,请编写程序将链表重新排列为 Ln→L1→Ln−1→L2→⋯。例如:给定L为1→2→3→4→5→6,则输出应该为6→1→5→2→4→3。
输入格式:
每个输入包含1个测试用例。每个测试用例第1行给出第1个结点的地址和结点总个数,即正整数N (≤105)。结点的地址是5位非负整数,NULL地址用−1表示。
接下来有N行,每行格式为:
Address Data Next
其中Address
是结点地址;Data
是该结点保存的数据,为不超过105的正整数;Next
是下一结点的地址。题目保证给出的链表上至少有两个结点。
输出格式:
对每个测试用例,顺序输出重排后的结果链表,其上每个结点占一行,格式与输入相同。
输入样例:
00100 6
00000 4 99999
00100 1 12309
68237 6 -1
33218 3 00000
99999 5 68237
12309 2 33218
输出样例:
68237 6 00100
00100 1 99999
99999 5 12309
12309 2 00000
00000 4 33218
33218 3 -1
代码如下:
#include<bits/stdc++.h>
using namespace std;
struct Node
{
int address;
int data;
int next;
};
int main()
{
int first,n;
cin>>first>>n;
int b1[n],b2[n];
Node a[100000];
for(int i=0;i<n;i++)
{
int address,data,next;
cin>>address>>data>>next;
a[address].address=address;
a[address].data=data;
a[address].next=next;
}
int i=first,t1=0,t2=0;
while(a[i].next!=-1)
{
b1[t1++]=a[i].address;
b2[t2++]=a[i].data;
i=a[i].next;
}
b1[t1++]=a[i].address;
b2[t2++]=a[i].data;
int j=0,min=0,max=t1-1;
while(t1--)
{
j++;
if(j%2==1)
if(t1==0) printf("%05d %d -1\n",b1[max],b2[max]);
else
{
printf("%05d %d %05d\n",b1[max],b2[max],b1[min]);
max--;
}
else
if(t1==0) printf("%05d %d -1\n",b1[min],b2[min]);
else
{
printf("%05d %d %05d\n",b1[min],b2[min],b1[max]);
min++;
}
}
return 0;
}
7-2 链表去重
给定一个带整数键值的链表 L,你需要把其中绝对值重复的键值结点删掉。即对每个键值 K,只有第一个绝对值等于 K 的结点被保留。同时,所有被删除的结点须被保存在另一个链表上。例如给定 L 为 21→-15→-15→-7→15,你需要输出去重后的链表 21→-15→-7,还有被删除的链表 -15→15。
输入格式:
输入在第一行给出 L 的第一个结点的地址和一个正整数 N(≤105,为结点总数)。一个结点的地址是非负的 5 位整数,空地址 NULL 用 -1 来表示。
随后 N 行,每行按以下格式描述一个结点:
地址 键值 下一个结点
其中地址
是该结点的地址,键值
是绝对值不超过104的整数,下一个结点
是下个结点的地址。
输出格式:
首先输出去重后的链表,然后输出被删除的链表。每个结点占一行,按输入的格式输出。
输入样例:
00100 5
99999 -7 87654
23854 -15 00000
87654 15 -1
00000 -15 99999
00100 21 23854
输出样例:
00100 21 23854
23854 -15 99999
99999 -7 -1
00000 -15 87654
87654 15 -1
代码如下:
#include<stdio.h>
#include<stdio.h>
#include<math.h>
#define N 100001
int visit[N] = {0};
typedef struct LNode
{
int data;
int next;
}LNode,*List;
typedef struct L
{
int address,data;
}L;
LNode node[N];
L a[N];int k1 = 0;
L b[N];int k2 = 0;
int main()
{
int first_address,K;
scanf("%d %d",&first_address,&K);
int m;
while(K--)
{
scanf("%d",&m);
scanf("%d %d",&node[m].data,&node[m].next);
}
int n = first_address;
while(n != -1)
{
if(visit[abs(node[n].data)] == 0)
{
a[k1].address = n;
a[k1].data = node[n].data;
k1++;
visit[abs(node[n].data)] = 1;
}
else
{
b[k2].address = n;
b[k2].data = node[n].data;
k2++;
}
n = node[n].next;
}
if(k1>=1)
a[k1].address = -1;
if(k2>=1)
b[k2].address = -1;
int i = 0;
while(1)
{
if(a[i+1].address == -1)
{
printf("%05d %d %d\n",a[i].address,a[i].data,a[i+1].address);
break;
}
else
printf("%05d %d %05d\n",a[i].address,a[i].data,a[i+1].address);
i++;
}
int j = 0;
while(k2!=0)
{
if(b[j+1].address == -1)
{
printf("%05d %d %d\n",b[j].address,b[j].data,b[j+1].address);
break;
}
else
printf("%05d %d %05d\n",b[j].address,b[j].data,b[j+1].address);
j++;
}
return 0;
}
7-3 两个有序链表序列的合并
已知两个非降序链表序列S1与S2,设计函数构造出S1与S2合并后的新的非降序链表S3。
输入格式:
输入分两行,分别在每行给出由若干个正整数构成的非降序序列,用−1表示序列的结尾(−1不属于这个序列)。数字用空格间隔。
输出格式:
在一行中输出合并后新的非降序链表,数字间用空格分开,结尾不能有多余空格;若新链表为空,输出NULL
。
输入样例:
1 3 5 -1
2 4 6 8 10 -1
输出样例:
1 2 3 4 5 6 8 10
代码如下:
#include <iostream>
#include <stdlib.h>
using namespace std;
typedef struct LNode
{
int data;
struct LNode* next;
}LNode, * LinkList;
void List_creat(LinkList &L)
{
int x;
LinkList s, r;
L = (LinkList)malloc(sizeof(LNode));
L->next = NULL;
r = L;
cin >> x;
while (x != -1)
{
s = (LinkList)malloc(sizeof(LNode));
s->data = x;
r->next = s;
r = r->next;
cin >> x;
}
r->next = NULL;
}
void List_print(LinkList &L)
{
if(L->next==NULL)
{
cout<<"NULL";
return;
}
LinkList r;
r = L->next;
cout<<r->data;
r=r->next;
while (r)
{
cout << " "<< r->data;
r = r->next;
}
}
LinkList Merge(LinkList &L1, LinkList &L2)
{
LinkList L, p, q, r;
L = (LinkList)malloc(sizeof(LNode));
L->next = NULL;
r = L;
p = L1->next;
q = L2->next;
while (p && q)
if (p->data <= q->data)
{
r->next = p;
r = r->next;
p = p->next;
}
else
{
r->next = q;
r = r->next;
q = q->next;
}
if (p) r->next = p;
if (q) r->next = q;
return L;
}
int main()
{
LinkList L1 = NULL, L2 = NULL, L = NULL;
List_creat(L1);
List_creat(L2);
L = Merge(L1, L2);
List_print(L);
return 0;
}
7-4 两个有序链表序列的交集
已知两个非降序链表序列S1与S2,设计函数构造出S1与S2的交集新链表S3。
输入格式:
输入分两行,分别在每行给出由若干个正整数构成的非降序序列,用−1表示序列的结尾(−1不属于这个序列)。数字用空格间隔。
输出格式:
在一行中输出两个输入序列的交集序列,数字间用空格分开,结尾不能有多余空格;若新链表为空,输出NULL
。
输入样例:
1 2 5 -1
2 4 5 8 10 -1
输出样例:
2 5
代码如下:
#include<iostream>
using namespace std;
typedef struct node
{
int data;
struct node *next;
}Node;
Node* in()
{
Node* head;
head=new Node;
head->next=NULL;
Node* p,*q=head;
while(1)
{
p=new Node;
cin>>p->data;
if(p->data==-1)
break;
p->next=NULL;
q->next=p;
q=p;
}
return head;
}
void combinate(Node* a,Node* b)
{
int flag=0;
Node *p=a->next,*q=b->next;
while(p!=NULL&&q!=NULL)
{
if(p->data>q->data)
q=q->next;
else if(p->data<q->data)
p=p->next;
else if(p->data==q->data)
{
if(flag==0)
{
cout<<p->data;
flag=1;
}
else
cout<<" "<<p->data;
p=p->next;
q=q->next;
}
}
if(flag==0)
cout<<"NULL";
}
int main()
{
Node *head1=NULL,*head2=NULL;
head1=in();
head2=in();
combinate(head1,head2);
return 0;
}