链表-计分任务
编程题
1. 向有序链表中插入数据并输出最大和最小值
【问题描述】输入若干按升序排列的整数,建立单向链表,后输入一个整数,把该数按原顺序插入到原链表,输出新链表中数据的最大值和最小值并输出链表中所有数据。必须用链表完成,程序中不允许有数组出现。
【输入形式】输入若干按升序排列的整数以0作为结束,和待插入的整数。用单个空格隔开。
【输出形式】输出最大值和最小值及链表中的所有数据,数据之间用单个空格隔开。
【样例输入】1 3 4 5 6 7 8 0 2
【样例输出】8 1 1 2 3 4 5 6 7 8
【评分标准】链表用完后空间要释放!
#include<stdio.h>
#include<stdlib.h>
struct Node {
int a;
struct Node* next;
};
struct Node* create();
int main() {
int x, flag = 0;
struct Node* head, * p, * o = NULL, * u = NULL;
head = create();
scanf("%d", &x);
p = head;
if (head->a > x) {
u = (struct Node*)malloc(sizeof(struct Node*));
u->a = x;
u->next = head;
head = u;
}
else {
while (p != NULL) {
if (p->a < x) {
o = p;
flag = 1;
}
p = p->next;
}
if (flag == 1) {
u = (struct Node*)malloc(sizeof(struct Node*));
u->a = x;
u->next = o->next;
o->next = u;
}
else {
p = head;
while (p != NULL) {
o = p;
p = p->next;
}
u = (struct Node*)malloc(sizeof(struct Node*));
u->a = x;
o->next = u;
u->next = NULL;
}
}
p = head;
while (p != NULL) {
o = p;
p = p->next;
}
printf("%d ", o->a);
printf("%d ", head->a);
p = head;
while (p != NULL) {
printf("%d ", p->a);
p = p->next;
}
return 0;
}
struct Node* create() {
struct Node* head = NULL, * p1 = NULL, * p2 = NULL;
p1 = (struct Node*)malloc(sizeof(struct Node*));
scanf("%d", &p1->a);
while (p1->a != 0) {
if (head == NULL) {
head = p1;
}
else {
p2->next = p1;
}
p2 = p1;
p1 = (struct Node*)malloc(sizeof(struct Node*));
scanf("%d", &p1->a);
}
p2->next = NULL;
free(p1);
return head;
}
2. 输出单链表倒数第K个结点值
【问题描述】输入一个单向链表,输出该链表中倒数第k个结点,链表的最后一个结点是倒数第1个结点。
【输入形式】输入第一位为K值,其后接一串以空格分隔的整型值,用-1表示结束。
【输出形式】输出为倒数第K个结点的值,若无,则输出Not Found。
【样例输入】3 13 45 54 32 1 4 98 2 -1
【样例输出】4
【样例说明】K值为3,则输出链表倒数第3个结点的值为4。
【样例输入】5 13 4 -1
【样例输出】Not Found
【样例说明】K值为5,不存在倒数第5个结点,因此输出Not Found。
【评分标准】本题20分。不使用链表的不得分。
// 引入标准输入输出库和标准库
#include <stdio.h>
#include <stdlib.h>
// 定义链表节点结构体
typedef struct Node {
int val; // 节点的值
struct Node* next; // 指向下一个节点的指针
} Node;
// 创建链表的函数
Node* create() {
Node* head = NULL; // 头节点初始化为NULL
Node* tail = NULL; // 尾节点初始化为NULL
int val; // 存储从输入读取的值
// 当输入的值不是-1时,继续读取和创建新节点
while (scanf("%d", &val) && val != -1) {
Node* newNode = (Node*)malloc(sizeof(Node)); // 分配新节点内存
newNode->val = val; // 设置新节点的值为输入的值
newNode->next = NULL; // 新节点的下一个节点初始化为NULL
// 如果链表为空,则新节点为头节点和尾节点
if (head == NULL) {
head = newNode;
tail = newNode;
}
// 否则,将新节点添加到链表的尾部
else {
tail->next = newNode;
tail = newNode;
}
}
return head; // 返回头节点,即整个链表
}
// 查找链表中第k个节点的值函数
int findK(Node* head, int k) {
// 如果链表为空或k小于等于0,则返回-1表示未找到
if (head == NULL || k <= 0) {
return -1;
}
Node* p = head; // 定义两个指针p和q,都初始化为头节点
Node* q = head;
// 先让p指针移动k-1步,确保p指针指向第k个节点的前一个节点
for (int i = 0; i < k - 1; i++) {
if (p->next != NULL) { // 如果p的下一个节点存在,则移动p指针到下一个节点
p = p->next;
}
else { // 如果p的下一个节点不存在,则返回-1表示未找到第k个节点
return -1;
}
}
// 当p指针指向第k个节点的前一个节点时,同时移动p和q指针,直到p指针到达链表的末尾
while (p->next != NULL) {
p = p->next; // p移动到下一个节点
q = q->next; // q也移动到下一个节点,这样q始终指向第k个节点
}
// q现在指向第k个节点,返回该节点的值
return q->val; // 返回第k个节点的值
}
int main() {
int k; // 存储要查找的节点的位置k的值
scanf("%d", &k); // 从标准输入读取k的值
Node* head = create(); // 创建链表并获取头节点指针
int result = findK(head, k); // 使用findK函数查找第k个节点的值,并存储到result中
// 根据result的值判断是否找到第k个节点,并打印相应的消息
if (result == -1) { // 如果result为-1,则表示未找到第k个节点,打印"Not Found"消息
printf("Not Found\n");
}
else { // 反之,打印resule值
printf("%d\n", result);
}
return 0;
}
片段题
1. (指针做参数的函数定义)查找数组下标
【问题描述】从键盘输入数组元素数量 n 以及这 n 个元素;再输入 2 个数,找到这2个数在数组中的位置,即数组下标。若某个数在数组中不存在,输出 -1,注意若数组中存在多个待查找的数,要全部输出位置。
【输入形式】输入数组元素数量 n 以及这 n 个整数元素;再输入2个待查找的整数。
【输出形式】输出2个数的位置信息。
【样例输入】
3 56 85 41
27 58
【样例输出】
27 -1
58 -1
【样例输入】
4 101 25 5 444
5 101
【样例输出】
5 2
101 0
【样例输入】
6 2 6 8 8 6 8
8 6
【样例输出】
8 2 3 5
6 1 4
#include <stdio.h>
#include <stdlib.h>
int input_data(int* number);
void output_data(int* number, int n);
int main()
{
int n, x[20];
n = input_data(x);
output_data(x, n);
return 0;
}
// 定义一个函数,用于接收用户输入的数据数量并返回该数量
int input_data(int* number) {
int x; // 输入数据数量
scanf("%d", &x); // 读取用户输入的数量
for (int i = 0; i < x; i++) {
scanf("%d", number + i); // 循环读取x个整数并存储在数组number中
}
return x; // 返回读取的整数数量
}
// 定义一个函数,用于输出数据和位置信息
void output_data(int* number, int n) {
int i = 0, x = 0, a = 0, c = 0, y = 0; // 定义循环和条件判断变量
scanf("%d %d", &x, &y); // 读取两个整数x和y
for (i = 0; i < n; i++) { // 循环n次,n是数据数量
if (a == 0) { // 如果还没有找到x
if (*(number + i) == x) { // 如果找到x
printf("%d %d ", x, i); // 输出x和位置
a = 1; // 设置标志位,表示已找到x
continue; // 跳过本次循环的剩余部分
}
}
else { // 如果已经找到x
if (*(number + i) == x) { // 如果再次找到x
printf("%d ", i); // 输出位置
}
}
}
if (a == 0) { // 如果未找到x
printf("%d -1", x); // 输出x和-1表示索引无效
}
printf("\n"); // 换行,准备输出y的位置信息
for (i = 0; i < n; i++) { // 重新开始循环n次,重复上述过程以查找和y相等的数并输出其位置信息
if (c == 0) { // 如果还没有找到y
if (*(number + i) == y) { // 如果找到y
printf("%d %d ", y, i); // 输出y和位置
c = 1; // 设置标志位,表示已找到y
continue; // 跳过本次循环的剩余部分
}
}
else { // 如果已经找到y
if (*(number + i) == y) { // 如果再次找到y
printf("%d ", i); // 输出位置
}
}
}
if (c == 0) { // 如果未找到y
printf("%d -1", y); // 输出y和-1表示索引无效
}
}
2. (指针做参数的函数定义)规格化数据
【问题描述】输入 10 个整数,将其中最小的数与第一个数对换,把最大的数与最后一个数对换。写三个函数:
①输入 10 个数; 函数原型声明:void input_data(int *number)
②进行处理; 函数原型声明:void handle_val(int *number)
③输出 10 个数。 函数原型声明:void output_data(int *number)
【输入形式】输入 10 个整数。
【输出形式】输出对换后的10个整数。
【样例输入】10 25 6 15 87 3 26 31 85 7
【样例输出】3 25 6 15 7 10 26 31 85 87
#include <stdio.h>
#include <stdlib.h>
void input_data(int* number);
void handle_val(int* number);
void output_data(int* number);
int main()
{
int x[10];
input_data(x);
handle_val(x);
output_data(x);
return 0;
}
// 输入10个整数到数组
void input_data(int* number) {
int i;
for (i = 0; i < 10; i++) {
scanf("%d", number + i); // 从标准输入读取一个整数并存储到数组的当前位置
}
}
// 找到数组中的最大值和最小值,然后与数组的首尾元素交换
void handle_val(int* number) {
int i, * a, * b, t = 0;
a = number; // a指向数组首元素,用于寻找最大值
b = number; // b指向数组首元素,用于寻找最小值
for (i = 0; i < 10; i++) {
if (*a < *(number + i)) {
a = number + i; // 更新最大值的指针位置
}
}
for (i = 0; i < 10; i++) {
if (*b > *(number + i)) {
b = number + i; // 更新最小值的指针位置
}
}
// 交换首元素与最小值
t = *b;
*b = *number;
*number = t;
// 交换尾元素与最大值
t = *a;
*a = *(number + 9);
*(number + 9) = t;
}
// 输出数组中的所有元素
void output_data(int* number) {
for (int i = 0; i < 10; i++) {
printf("%d ", *(number + i)); // 打印数组的当前元素,并在后面加一个空格
}
}
3. 创建并输出链表
【问题描述】从键盘输入一行字符,以 # 结束,建立链表,打印输出链表。
【输入形式】输入一行字符,以 # 结束。
【输出形式】输出 # 之前的字符串(注意空表输出情况)。
【样例输入】123456789#124
【样例输出】123456789
#include <stdio.h> // 引入标准输入输出库(C风格)
#include <stdlib.h> // 引入标准库(内存分配等)
#define LEN sizeof(Node) // 定义Node结构体的大小
// 使用typedef为结构体重命名,使其更易读
typedef struct Node {
char a; // 存储一个字符
Node* next; // 指向下一个Node的指针
} Node; // 结束typedef定义
Node* create(); // 函数声明:创建链表
void print(Node* p); // 函数声明:打印链表
int main() { // 主函数开始
Node* head = NULL; // 初始化头指针为NULL
head = create(); // 调用create函数创建链表并返回头指针
print(head); // 打印链表
return 0; // 主函数返回0,程序结束
} // 主函数结束
Node* create() { // 创建链表的函数开始
Node* head = NULL, * p1, * p2; // 初始化头指针和两个临时指针
p1 = (Node*)malloc(sizeof(Node)); // 为p1分配内存并返回指向它的指针
scanf("%c", &p1->a); // 从标准输入读取一个字符并存储在p1的a字段中
while (p1->a != '#') { // 当读取的字符不是'#'时,继续循环
if (head == NULL) { // 如果链表为空,将p1设置为头指针
head = p1;
}
else { // 如果链表不为空,将p1添加到链表的末尾
p2->next = p1;
}
p2 = p1; // 将p2移动到p1的位置,准备添加下一个节点
p1 = (Node*)malloc(sizeof(Node)); // 为p1分配新的内存,准备读取下一个字符
scanf("%c", &p1->a); // 从标准输入读取下一个字符并存储在p1的a字段中
}
return head; // 返回头指针,链表创建完成
} // create函数结束
void print(Node* p) { // 打印链表的函数开始
while (p != NULL) { // 当当前节点不为空时,继续循环
printf("%c", p->a); // 打印当前节点的字符字段
p = p->next; // 将指针移动到下一个节点
} // 打印链表的函数结束
}
4. 删除链表中指定结点
【问题描述】输入链表 a,链表结点中包含学号、姓名,学号输入 -1,姓名随意代表一个链表输入结束。再输入待删除结点的学号 num,请编写删除链表中结点函数,从结点中删除学号为 num 的结点,并依次输出删除后的链表。若链表中不包含学号为 num 的结点,则先输出 no data,再依次输出链表结点。
【输入形式】输入链表 a 的数据和待删除结点的学号 num。其中,学号输入 -1,姓名随意代表一个链表输入结束。
【输出形式】输出删除后的新链表。
【样例输入】
101 Wang
102 Li
105 Zhang
106 Wei
-1 x
105
【样例输出】
101 Wang 102 Li 106 Wei
【样例输入】
101 Wang
102 Li
105 Zhang
106 Wei
-1 x
103
【样例输出】
no data 101 Wang 102 Li 105 Zhang 106 Wei
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LEN sizeof(NODE)
//用 typedef 将结构体改名字
typedef struct node {
int num;
char name[20];
struct node *next;
} NODE;
NODE *Create_LinkList();
//读入学号,并删除指定学号的结点,
//成功删除返回正数,未找到学号返回负数。
int Delete_LinkList(NODE *head);
void Display_LinkList(NODE *head,int flag);
void Free_LinkList(NODE *head);
int main()
{
NODE *head = NULL;
int flag;
head = Create_LinkList();//创建链表
flag=Delete_LinkList(head);
Display_LinkList(head,flag);//打印结果
Free_LinkList(head);
return 0;
}
NODE* Create_LinkList()//创建链表
{
NODE* head, *head1, * p1, * p2;
int n = 0;
head1= (NODE*)malloc(LEN);
head = NULL;
p1 = p2 = (NODE*)malloc(LEN);
scanf("%d %s",&p1->num,p1->name);
while (p1->num != -1)
{
n += 1;
if (n == 1)
{
head = p1;
}
else
{
p2->next = p1;
}
p2 = p1;
p1 = (NODE*)malloc(LEN);
scanf("%d %s", &p1->num, p1->name);
}
p2->next = NULL;
head1->next = head;
return head1;
}
int Delete_LinkList(NODE* head)//删除链表中某一个节点
{
int x = 0;
scanf("%d", &x);//输入需要删除的节点的数据
NODE* p;
p = head;
int flag = -1;//没找到时flag为-1
while (p->next != NULL)
{
if (p->next->num == x)
{
NODE* temp;
temp = p->next;
p->next = p->next->next;
free(temp);
flag = 1;//找到了就删除并且把flag变成1
break;
}
p = p->next;
}
return flag;
}
void Display_LinkList(NODE *head,int flag) //打印
{
NODE *p;
if(flag<0)
printf("no data ");
for (p = head->next; p != NULL; p = p->next)
printf ("%d %s ", p->num,p->name);
}
void Free_LinkList(NODE *head) //遍历释放
{
NODE *p, *q;
p = head;
while (p->next != NULL)
{
q = p->next;
p->next = q->next;
free (q);
}
free (head);
}
5. 用指针和函数实现3个数排序
【问题描述】输入 3 个整数,按由小到大的顺序输出。指针使用部分要求定义函数 void swap(int *x, int *y),函数功能是 x 和 y 两个数互换。
【输入形式】输入 3 个整数。
【输出形式】按由小到大的顺序输出,每个数用一个空格分隔。
【样例输入】5 -1 6
【样例输出】-1 5 6
#include <stdio.h> // 引入C标准库,用于输入输出函数如scanf和printf
#include <stdlib.h> // 引入C标准库,尽管这里没有用到其中的任何函数
// 声明一个swap函数,用于交换两个整数的值
void swap(int *x, int *y);
int main() // 主函数,程序的入口点
{
int x, y, z; // 定义三个整数变量x、y和z
// 从标准输入读取三个整数
scanf("%d%d%d", &x, &y, &z);
// 如果x大于y,调用swap函数交换它们的值
if (x > y)
swap(&x, &y);
// 如果y大于z,调用swap函数交换它们的值
if (y > z)
swap(&y, &z);
// 如果x大于y,再次调用swap函数交换它们的值。此时,x、y和z应该已经是升序排列的
if (x > y)
swap(&x, &y);
// 打印排序后的x、y和z的值
printf("%d %d %d", x, y, z);
return 0; // 主函数返回0,表示程序正常结束
}
// swap函数定义,用于交换两个整数的值
void swap(int *x, int *y)
{
int t; // 定义一个临时变量t,用于存储x的值
// 将x的值赋给t
t = *x;
// 将y的值赋给x
*x = *y;
// 将t(原来x的值)赋给y
*y = t;
}
今天的内容就分享这么多
求三连!!!
求关注!!!