PTA表练习

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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值