当前位置: 首页 > news >正文

实验二:链表

7-1 两个有序链表序列的合并

分数 20

作者 DS课程组

单位 浙江大学

已知两个非降序链表序列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<stdio.h>
#include<stdlib.h>
struct node
{int d;struct node *next;
};
int main()
{struct node *h1,*h2,*t1,*t2,*p1,*p2;h1=(struct node*)malloc(sizeof(struct node));h1->next=NULL;t1=h1;while(1){p1=(struct node*)malloc(sizeof(struct node));scanf("%d",&p1->d);if(p1->d==-1){free(p1);break;}p1->next=NULL;t1->next=p1;t1=p1;}h2=(struct node*)malloc(sizeof(struct node));h2->next=NULL;t2=h2;while(1){p2=(struct node*)malloc(sizeof(struct node));scanf("%d",&p2->d);if(p2->d==-1){free(p2);break;}p2->next=NULL;t2->next=p2;t2=p2;}struct node *h,*t,*p;h=h1;p1=h1->next;p2=h2->next;t=h1;while(p1!=NULL&&p2!=NULL){if(p1->d<p2->d){t->next=p1;t=p1;p1=p1->next;}else{t->next=p2;t=p2;p2=p2->next;}if(p1!=NULL)t->next=p1;elset->next=p2;}p=h->next;if(p==NULL)printf("NULL");else{while(p!=NULL){if(p->next==NULL)printf("%d\n",p->d);elseprintf("%d ",p->d);p=p->next;}}return 0;
}

7-2 两个有序链表序列的交集

分数 20

作者 DS课程组

单位 浙江大学

已知两个非降序链表序列S1与S2,设计函数构造出S1与S2的交集新链表S3。

输入格式:

输入分两行,分别在每行给出由若干个正整数构成的非降序序列,用−1表示序列的结尾(−1不属于这个序列)。数字用空格间隔。

输出格式:

在一行中输出两个输入序列的交集序列,数字间用空格分开,结尾不能有多余空格;若新链表为空,输出NULL

输入样例:

1 2 5 -1
2 4 5 8 10 -1

输出样例:

2 5
#include<stdio.h>
#include<stdlib.h>
struct node
{int d;struct node *next;
};
int main()
{struct node *h1,*h2,*t1,*t2,*p1,*p2;h1=(struct node*)malloc(sizeof(struct node));h1->next=NULL;t1=h1;while(1){p1=(struct node*)malloc(sizeof(struct node));scanf("%d",&p1->d);if(p1->d==-1){free(p1);break;}p1->next=NULL;t1->next=p1;t1=p1;}h2=(struct node*)malloc(sizeof(struct node));h2->next=NULL;t2=h2;while(1){p2=(struct node*)malloc(sizeof(struct node));scanf("%d",&p2->d);if(p2->d==-1){free(p2);break;}p2->next=NULL;t2->next=p2;t2=p2;}struct node *h,*t,*p;h=(struct node*)malloc(sizeof(struct node));h->next=NULL;t=h;p1=h1->next;p2=h2->next;while(p1!=NULL&&p2!=NULL){if(p1->d==p2->d){p=(struct node*)malloc(sizeof(struct node));p->d=p1->d;p->next=NULL;t->next=p;t=p;p1=p1->next;p2=p2->next;}else if(p1->d<p2->d)p1=p1->next;elsep2=p2->next;}p=h->next;if(p==NULL)printf("NULL");else{int is_first = 1;while(p!=NULL){if(is_first){printf("%d",p->d);is_first = 0;}elseprintf(" %d",p->d);p=p->next;}}return 0;
}

7-3 重排链表

分数 20

作者 陈越

单位 浙江大学

给定一个单链表 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 <stdio.h>
#include <stdlib.h>
// 定义节点结构:存储数据和下一个节点的地址
struct Node {int data;int next;
};
int main() {// 节点地址是5位非负整数,最大为99999,因此数组大小设为100000struct Node nodes[100000];// 初始化所有节点的next为-1(表示空地址)for (int i = 0; i < 100000; ++i) {nodes[i].next = -1;}int head, N;// 读取头节点地址和节点总数scanf("%d %d", &head, &N);// 读取N个节点,存入数组(下标=节点地址)for (int i = 0; i < N; ++i) {int addr, data, next;scanf("%d %d %d", &addr, &data, &next);nodes[addr].data = data;nodes[addr].next = next;}// 第一步:提取原链表的节点地址序列(按原顺序)int orig[N];  // 存储原链表的节点地址int len = 0;  // 原链表长度(实际等于N)int curr = head;while (curr != -1) {orig[len++] = curr;curr = nodes[curr].next;}// 第二步:双指针法构建重排后的节点地址序列int new_arr[N];  // 存储重排后的节点地址int left = 0, right = len - 1;  // 左右指针int idx = 0;                    // 新序列的下标int flag = 1;                   // 1:取右指针,0:取左指针(交替)while (left <= right) {if (flag) {new_arr[idx++] = orig[right--];  // 先取末尾节点} else {new_arr[idx++] = orig[left++];   // 再取开头节点}flag = !flag;  // 切换指针方向}// 第三步:更新重排后每个节点的next地址for (int i = 0; i < len - 1; ++i) {// 当前节点的next = 下一个节点的地址nodes[new_arr[i]].next = new_arr[i + 1];}// 最后一个节点的next设为-1(空地址)nodes[new_arr[len - 1]].next = -1;// 第四步:按格式输出重排后的链表for (int i = 0; i < len; ++i) {int addr = new_arr[i];int data = nodes[addr].data;int next = nodes[addr].next;// 地址输出为5位,不足补0;next为-1时直接输出-1if (next == -1) {printf("%05d %d %d\n", addr, data, next);} else {printf("%05d %d %05d\n", addr, data, next);}}return 0;
}

7-4 约瑟夫环

分数 20

作者 李廷元

单位 中国民用航空飞行学院

N个人围成一圈顺序编号,从1号开始按1、2、3......顺序报数,报p者退出圈外,其余的人再从1、2、3开始报数,报p的人再退出圈外,以此类推。
请按退出顺序输出每个退出人的原序号。

输入格式:

输入只有一行,包括一个整数N(1<=N<=3000)及一个整数p(1<=p<=5000)。

输出格式:

按退出顺序输出每个退出人的原序号,数据间以一个空格分隔,但行尾无空格。

输入样例:

在这里给出一组输入。例如:

7 3

输出样例:

3 6 2 7 5 1 4
#include<stdio.h>
#include<stdlib.h>
struct node
{int d;struct node *next;
};
int main()
{int n,p;scanf("%d %d",&n,&p);struct node *h,*t,*q;h=(struct node*)malloc(sizeof(struct node));h=NULL;t=NULL;for(int i=1;i<=n;i++){q=(struct node*)malloc(sizeof(struct node));q->d=i;q->next=NULL;if(h==NULL){h=q;t=q;}else{t->next=q;t=q;}}t->next=h;struct node *current=h;struct node *prev=t;int c=0,isFirst=1;while(n>0){current=prev->next;c++;if(c==p){if(isFirst){printf("%d",current->d);isFirst=0;}elseprintf(" %d",current->d);prev->next=current->next;free(current);c=0;n--;}elseprev=prev->next;}return 0;
}

7-5 单链表的创建及遍历

分数 15

作者 陈晓梅

单位 广东外语外贸大学

读入n值及n个整数,建立单链表并遍历输出。

输入格式:

读入n及n个整数。

输出格式:

输出n个整数,以空格分隔(最后一个数的后面没有空格)。

输入样例:

在这里给出一组输入。例如:

2
10 5

输出样例:

在这里给出相应的输出。例如:

10 5
#include<stdio.h>
#include<stdlib.h>
struct node
{int d;struct node *next;
};
int main()
{int n;scanf("%d",&n);struct node *h,*t,*p;h=(struct node*)malloc(sizeof(struct node));h->next=NULL;t=h;for(int i=0;i<n;i++){p=(struct node*)malloc(sizeof(struct node));scanf("%d",&p->d);p->next=NULL;t->next=p;t=p;}p=h->next;while(p!=NULL){if(p->next==NULL)printf("%d",p->d);elseprintf("%d ",p->d);p=p->next;}return 0;
}

7-6 链表去重

分数 20

作者 陈越

单位 浙江大学

给定一个带整数键值的链表 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 <stdlib.h>
#include <math.h>
// 定义节点结构:存储键值和下一个节点地址
struct Node {int key;   // 节点的键值int next;  // 下一个节点的地址(5位整数,-1表示空)
};
int main() {// 节点地址最大为99999,数组大小设为100000(下标=地址)struct Node nodes[100000];// 标记数组:记录某个绝对值是否已出现(键值绝对值≤1e4)int used[10001] = {0};  // 0=未出现,1=已出现int head, N;// 读取链表头地址和节点总数scanf("%d %d", &head, &N);// 第一步:读取所有节点,存入数组(下标=地址)for (int i = 0; i < N; ++i) {int addr, key, next;scanf("%d %d %d", &addr, &key, &next);nodes[addr].key = key;nodes[addr].next = next;}// 第二步:提取原链表的节点顺序(输入节点可能乱序,需按next指针排序)int orig[N];  // 存储原链表节点地址的顺序int orig_len = 0;  // 原链表实际长度(等于N)int curr = head;while (curr != -1) {orig[orig_len++] = curr;curr = nodes[curr].next;}// 第三步:拆分去重后的链表(res)和被删除的链表(del)int res[N], del[N];  // 存储两个结果链表的节点地址int res_len = 0, del_len = 0;  // 两个链表的长度for (int i = 0; i < orig_len; ++i) {int addr = orig[i];int abs_key = abs(nodes[addr].key);  // 计算键值的绝对值if (used[abs_key] == 0) {// 绝对值未出现:加入去重后的链表,标记为已出现used[abs_key] = 1;res[res_len++] = addr;} else {// 绝对值已出现:加入被删除的链表del[del_len++] = addr;}}// 第四步:设置两个结果链表的next指针(确保最后一个节点指向-1)// 处理去重后的链表for (int i = 0; i < res_len - 1; ++i) {nodes[res[i]].next = res[i + 1];  // 当前节点的next指向后一个节点}if (res_len > 0) {nodes[res[res_len - 1]].next = -1;  // 最后一个节点指向空}// 处理被删除的链表for (int i = 0; i < del_len - 1; ++i) {nodes[del[i]].next = del[i + 1];}if (del_len > 0) {nodes[del[del_len - 1]].next = -1;}// 第五步:按格式输出两个链表// 输出去重后的链表for (int i = 0; i < res_len; ++i) {int addr = res[i];int next = nodes[addr].next;// 地址格式化为5位,next为-1时直接输出,否则也格式化if (next == -1) {printf("%05d %d %d\n", addr, nodes[addr].key, next);} else {printf("%05d %d %05d\n", addr, nodes[addr].key, next);}}// 输出被删除的链表for (int i = 0; i < del_len; ++i) {int addr = del[i];int next = nodes[del[i]].next;if (next == -1) {printf("%05d %d %d\n", addr, nodes[addr].key, next);} else {printf("%05d %d %05d\n", addr, nodes[addr].key, next);}}return 0;
}

7-7 单链表就地逆置

分数 15

作者 usx程序设计类课程组

单位 绍兴文理学院

输入多个整数,以-1作为结束标志,顺序建立一个带头结点的单链表,之后对该单链表进行就地逆置(不增加新结点),并输出逆置后的单链表数据。

输入格式:

首先输入一个正整数T,表示测试数据的组数,然后是T组测试数据。每组测试输入多个整数,以-1作为该组测试的结束(-1不处理)。

输出格式:

对于每组测试,输出逆置后的单链表数据(数据之间留一个空格)。

输入样例:

1
1 2 3 4 5 -1

输出样例:

5 4 3 2 1
#include<stdio.h>
#include<stdlib.h>
struct node
{int d;struct node *next;
};
int main()
{int t;scanf("%d",&t);struct node *h,*p;for(int i=0;i<t;i++){h=(struct node*)malloc(sizeof(struct node));h->next=NULL;while(1){p=(struct node*)malloc(sizeof(struct node));scanf("%d",&p->d);if(p->d==-1)break;p->next=h->next;h->next=p;}p=h->next;while(p!=NULL){if(p->next==NULL)printf("%d\n",p->d);elseprintf("%d ",p->d);p=p->next;}}return 0;
}

7-8 带头节点的双向循环链表操作

分数 20

作者 achingz

单位 广西科技大学

本题目要求读入一系列整数,依次插入到双向循环链表的头部和尾部,然后顺序和逆序输出链表。

链表节点类型可以定义为

typedef int DataType;
typedef struct LinkedNode{DataType data;struct LinkedNode *prev;struct LinkedNode *next;
}LinkedNode;

链表类型可以定义为

typedef struct LinkedList{int length; /* 链表的长度 */LinkedNode head; /* 双向循环链表的头节点 */
}LinkedList;

初始化链表的函数可声明为

void init_list(LinkedList *list);

分配节点的函数可声明为

LinkedNode *alloc_node(DataType data);

头部插入的函数可声明为

void push_front(LinkedList *list, DataType data);

尾部插入的函数可声明为

void push_back(LinkedList *list, DataType data);

顺序遍历的函数可声明为

void traverse(LinkedList *list);

逆序遍历的函数可声明为

void traverse_back(LinkedList *list);

输入格式:

输入一行整数(空格分隔),以-1结束。

输出格式:

第一行输出链表顺序遍历的结果,第二行输出逆序遍历的结果。

输入样例:

在这里给出一组输入。例如:

1 2 3 4 5 6 -1

输出样例:

5 3 1 2 4 6
6 4 2 1 3 5
#include<bits/stdc++.h>
using namespace std;
struct node{int data;node * next;node *pre;
};
void puf(node *h, node *p)
{if (h->next == NULL) {h->next = p;p->next = h;p->pre = h;} else {p->next = h->next;h->next->pre = p;h->next = p;p->pre = h;}
}
void pub(node *h, node *p)
{if (h->next == NULL) {h->next = p;p->next = h;p->pre = h;} else {node *t = h->next;while (t->next != h) {t = t->next;}t->next = p;p->pre = t;p->next = h;h->pre = p;}
}
void shun(node *h)
{node *p = h->next;if (p != h) { // 添加判断条件,避免只有一个节点时的输出问题printf("%d", p->data);p = p->next;}while (p != h) {printf(" %d", p->data);p = p->next;}printf("\n");
}
void ni(node *h)
{node *p = h->pre;if (p != h) { // 添加判断条件,避免只有一个节点时的输出问题cout << p->data;p = p->pre;}while (p != h) {printf(" %d", p->data);p = p->pre;}
}
int main()
{int n, i = 0;node *h = new node;h->next = h->pre = h;while (~scanf("%d", &n) && n != -1){node *p = new node;p->data = n;if (i % 2 == 0) {puf(h, p);} else {pub(h, p);}i++;}shun(h);ni(h);return 0;
}

7-9 头插法创建单链表、遍历链表、删除链表

分数 20

作者 伍建全

单位 重庆科技大学

输入一系列自然数(0和正整数),输入-1时表示输入结束。按照输入的顺序,用头插法建立单链表,并遍历所建立的单链表,输出这些数据。注意 -1 不加入链表。

输入格式:

第一行是一个正整数k,表示以下会有k组测试数据。

每组测试数据是一系列以空格隔开的自然数(0和正整数)。数列末尾的 -1 表示本组测试数据结束。按照输入的顺序,用头插法建立单链表,并遍历所建立的单链表,输出这些数据。注意 -1 不加入链表。

输出格式:

对于每组测试数据,输出链表中各节点的数据域。每个数据后有一个空格。每组测试数据的输出占1行。

输入样例:

3
1 2 3 4 5 -1 
30 20 10 -1 
4 2 2 1 1 2 0 2 -1 

输出样例:

在这里给出相应的输出。例如:

5 4 3 2 1 
10 20 30 
2 0 2 1 1 2 2 4 

注意:对每组测试数据,创建链表,遍历链表输出之后,一定要删除链表,否则会出现“内存超限”。

#include<stdio.h>
#include<stdlib.h>
struct node
{int d;struct node *next;
};
void deleteList(struct node *h)
{struct node *t;while(h!=NULL){t=h;h=h->next;free(t);}
}
int main()
{int k;scanf("%d",&k);struct node *h,*p;for(int i=0;i<k;i++){h=(struct node*)malloc(sizeof(struct node));h->next=NULL;while(1){p=(struct node*)malloc(sizeof(struct node));scanf("%d",&p->d);if(p->d==-1){free(p);break;}p->next=h->next;h->next=p;}p=h->next;while(p!=NULL){printf("%d ",p->d);p=p->next;}printf("\n");deleteList(h);}return 0;
}
http://www.dtcms.com/a/450152.html

相关文章:

  • 在线免费开网站企业网站管理系统设计报告
  • 什么网站做ppt模板wordpress网页标签图标
  • 专栏丨华为HN8145XR光猫获取超级管理员密码
  • 小型企业网站开发公司wordpress 中文开发
  • Redis rdb持久化
  • AgentWorkflow 实战:从单 Agent 到多 Agent 协作的完整方案
  • 数据懒加载和虚拟列表
  • 江苏省建设注册中心网站首页在线制作简历网站
  • Java “线程池(2)”面试清单(含超通俗生活案例与深度理解)
  • Linux内核kallsyms符号压缩与解压机制
  • 米思米网站订单取消怎么做基金会网站模板
  • 公司网站源码做智能家居网站需要的参考文献
  • 11. Pandas 数据分类与区间分组(cut 与 qcut)
  • 找家里做的工作到什么网站淄博五厘网络技术有限公司
  • 国外哪些网站做产品推广比较好四川建设人员信息查询
  • 第二章:软件需求
  • AI Agent赋能产品经理:从需求分析到用户增长的全流程实践
  • 网站服务公司案例广州网站建设优化公司
  • AI学习日记——神经网络参数的更新
  • Java进阶教程,全面剖析Java多线程编程,多线程和堆内存栈内存的关系,笔记20
  • 建设春风摩托车官方网站百度站长论坛
  • 长春企业网站建设公司建设银行广州招聘网站
  • 网站 开发 周期定制app开发软件
  • 怎么做网站 ppt货代网站制作
  • 2025-10-06 Python不基础12——class原理
  • 龙泉驿建设局网站谷歌seo是什么职业
  • 从东方仙盟筑基期看 JavaScript 动态生成图片技术-东方仙盟
  • 怎么做电脑网站后台谷歌seo推广服务
  • 【笔记】2.1.1.1 电化学定义与组件特征
  • ISO 11452系列子标准介绍 道路车辆窄带辐射电磁能电干扰的部件试验方