7-5 链表合并 (25分)

题目

在这里插入图片描述
输入样例:
00100 01000 7
02233 2 34891
00100 6 00001
34891 3 10086
01000 1 02233
00033 5 -1
10086 4 00033
00001 7 -1

输出样例:
01000 1 02233
02233 2 00001
00001 7 34891
34891 3 10086
10086 4 00100
00100 6 00033
00033 5 -1

解题思路

1.如何链在一起:把顺序结构当作链式结构的方法

把数组的下标作为5位数字的地址

link linkall[100005];//下标是为输入的地址

链表的结构体为{地址(编号,即数组的下标);数据;下一跳地址}

//记录自己的编号,数据,下一跳
//实际上自己的编号也是数组的下标,使得顺序结构可被当作链式结构使用
typedef struct link{
	int id, data, next;
}link;

这样顺序结构就可以通过下标被当作链式结构使用

2.如何合并在一起:只要根据长短表的顺序,隔两个一输出短表地址即可

  1. 第一个元素的每个id及其data先输出
  2. 接着 next,next的id和data输出
  3. 当有一表输出完后,再把未输出完的那个表输出完
  4. 最后留着-1单独输出

子函数

1.输入

for (int i = 0; i < N; i++){
		scanf("%d%d%d", &id, &data, &next);
		//实际上自己的编号也是数组的下标,使得顺序结构可被当作链式结构使用
		linkall[id].id = id;
		linkall[id].data = data;
		linkall[id].next=next;
	}

2.把一子表链起来

按子表的顺序存放(0空着,1~n),最后返回子表长度

int Linking(int start,link L[]){//链接表1表2
	int id = start;//根据头元素地址(下标)找到链的头元素
	int len = 0;//从1开始,这样长度正确,合并时不需要-1
	while (id != -1){
		L[++len] = linkall[id];
		id = L[len].next;//跳到下一跳
	}
	return len;
}

2.两表合并

i代表长表的当前编号,j代表短表的当前序号

  1. 当两表都未输出完时,即i<=Llen&&j>=1

    按序输出长表,当长表序号i%2==0时,插入一个短表的

  2. 当有一表输出完后,再把未输出完的那个表输出完

  3. 最后留着-1单独输出

void unionlink(link Short[],int Slen,link Long[],int Llen){//合并两表
	//第一个元素的每个id及其data先输出
	//接着 next,next的id和data输出
	//最后留着-1单独输出
	int j = Slen,i=1;//短表j,长表i的下标
	printf("%05d %d ", Long[i].id, Long[i].data);
	while (++i<=Llen&&j>=1){
		printf("%05d\n%05d %d ", Long[i].id, Long[i].id, Long[i].data);
		if (i%2==0){
			printf("%05d\n%05d %d ", Short[j].id, Short[j].id,Short[j].data);
			j--;
		}
	}
	//写while(i++<=Llen)的话在判断完i<=Llen之后就i++了,不可以)
	while (i <= Llen){//若i表未输出完
		printf("%05d\n%05d %d ", Long[i].id, Long[i].id, Long[i].data);
		i++;
	}
	while (j >= 1){//若j表未输出完
		printf("%05d\n%05d %d ", Short[j].id, Short[j].id, Short[j].data);
		j--;
	}
	printf("-1\n");
	return;
}

AC代码

#include<stdio.h>
#include<stdlib.h>
#include<string>
using namespace std;
//记录自己的编号,数据,下一跳
//实际上自己的编号也是数组的下标,使得顺序结构可被当作链式结构使用
typedef struct link{
	int id, data, next;
}link;
link linkall[100005];//下标是为输入的地址
link link1[100005], link2[100005];//下标是在该链的位置,方便合并
int l1,l1len,l2,l2len,start,N;
int Linking(int start,link L[]){//链接表1表2
	int id = start;//根据头元素地址(下标)找到链的头元素
	int len = 0;//从1开始,这样长度正确,合并时不需要-1
	while (id != -1){
		L[++len] = linkall[id];
		id = L[len].next;//跳到下一跳
	}
	return len;
}
void unionlink(link Short[],int Slen,link Long[],int Llen){//合并两表
	//第一个元素的每个id及其data先输出
	//接着 next,next的id和data输出
	//最后留着-1单独输出
	int j = Slen,i=1;//短表j,长表i的下标
	printf("%05d %d ", Long[i].id, Long[i].data);
	while (++i<=Llen&&j>=1){
		printf("%05d\n%05d %d ", Long[i].id, Long[i].id, Long[i].data);
		if (i%2==0){
			printf("%05d\n%05d %d ", Short[j].id, Short[j].id,Short[j].data);
			j--;
		}
	}
	//写while(i++<=Llen)的话在判断完i<=Llen之后就i++了,不可以)
	while (i <= Llen){//若i表未输出完
		printf("%05d\n%05d %d ", Long[i].id, Long[i].id, Long[i].data);
		i++;
	}
	while (j >= 1){//若j表未输出完
		printf("%05d\n%05d %d ", Short[j].id, Short[j].id, Short[j].data);
		j--;
	}
	printf("-1\n");
	return;
}
int main(){
	scanf("%d%d%d", &l1, &l2, &N);
	int id, data, next;
	for (int i = 0; i < N; i++){
		scanf("%d%d%d", &id, &data, &next);
		//实际上自己的编号也是数组的下标,使得顺序结构可被当作链式结构使用
		linkall[id].id = id;
		linkall[id].data = data;
		linkall[id].next=next;
	}
	l1len = Linking(l1, link1);
	l2len = Linking(l2, link2);
	if (l1len>l2len)
		unionlink(link2, l2len, link1, l1len);
	else
		unionlink(link1, l1len, link2, l2len);
	system("PAUSE");
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Deosiree

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值