1. 第一关 顺序表逆置
任务描述
本关任务:设计一个算法,将顺序表L的所有元素逆置
要求:空间复杂度应为 O(1)
编程要求
输入
多组数据,每组数据有两行,第一行为顺序表的长度n,第二行为顺序表中的n个元素(元素之间用空格分隔)。当n=0时输入结束。
输出
逆置后的顺序表
测试输入:
5
1 2 3 4 5
3
1 5 6
4
15 2 3 4
0
预期输出:
5 4 3 2 1
6 5 1
4 3 2 15
#include<iostream>
using namespace std;
#define MAXSIZE 100
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int Status;
typedef struct SqList
{
int *elem;
int length;
}SqList;
void ListReverse(SqList &L)
{
// 请在此编写代码
int left = 0, right = L.length - 1;
while (left < right) {
// 交换 left 和 right 指向的元素
int temp = L.elem[left];
L.elem[left] = L.elem[right];
L.elem[right] = temp;
// 移动指针
left++;
right--;
}
}
视频链接:数据结构代码专题,线性表的逆置_哔哩哔哩_bilibili
2.第二关 单链表逆置
任务描述
本关任务:设计一个算法,将带头结点的单链表L的所有元素逆置
要求:空间复杂度应为 O(1)
编程要求
输入
多组数据,每组数据有两行,第一行为单链表的长度n,第二行为单链表中的n个元素(元素之间用空格分隔)。当n=0时输入结束。
输出
逆置后的单链表
测试说明
平台会对你编写的代码进行测试:
测试输入:
5
1 2 3 4 5
3
1 5 6
4
15 2 3 4
0
预期输出:
5 4 3 2 1
6 5 1
4 3 2 15
#include <iostream>
using namespace std;
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int Status;
typedef struct LNode
{
int data;
struct LNode *next;
}LNode, *LinkList;
void ListReverse(LinkList &L)
{
//在此处填入代码
//判断头指针或者首元节点是否为空
if(L == NULL || L->next == NULL){
//为空返回
return;
}
// 创建两个指针,分别指向第一个节点和第二个节点
LNode* begin = L->next;
LNode* end = L->next->next;
while(end != NULL){
//连
begin->next = end->next;
//掉
end->next = L->next;
//接
L->next = end;
//姨(移)
end = begin->next;
}
}
- 连
begin->next = end->next;
- 掉
end->next = L->next;
- 接
L->next = end;
- 姨
end = begin->next;
你在连队里执行任务,突然调转回头去接你的大姨去吃饭
视频链接:终于把单链表反转搞明白了(一)_带头节点的单链表原地反转_哔哩哔哩_bilibili
第三关 链表的倒数第k个节点
任务描述
本关任务:设计一个算法,返回单链表中倒数第k个结点的指针,若不存在返回空指针
编程要求
输入
多组数据,每组数据有两行,第一行为单链表的长度n和倒数第k个结点的序号k,第二行为单链表中的n个元素(元素之间用空格分隔)。当n=0时输入结束。
输出
单链表的倒数第k个结点的值,如果不存在输出NULL
测试说明
平台会对你编写的代码进行测试:
测试输入:
5 3
1 2 3 4 5
3 1
1 5 6
4 4
15 2 3 4
3 4
1 2 3
0
预期输出:
3
6
15
NULL
#include <iostream>
using namespace std;
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int Status;
typedef struct LNode
{
int data;
struct LNode *next;
}LNode, *LinkList;
LNode* Last_kth_node(LinkList &L,int k)
{
//返回链表中倒数第k个结点的指针
//在此处填入代码
if(L == NULL){
return L;
}
//定义快慢指针
LNode* slow = L;
LNode* fast = L;
//快指针先移动
while(k-- > 0){
if(fast == NULL){
return NULL;
}
fast = fast->next;
}
while(fast != NULL){
fast = fast->next;
slow = slow->next;
}
}
视频链接:链表中倒数第K个节点(题解与算法)_哔哩哔哩_bilibili
第四关 顺序表删除指定范围值的元素
任务描述
本关任务:设计一个算法,删除顺序表中值在s与t之间的所有元素(包括s和t,s<t)。
要求尽可能少地移动元素
编程要求
输入
多组数据,每组数据有两行,第一行为顺序表的长度n,删除范围s与t,第二行为顺序表中的n个元素(元素之间用空格分隔)。当n=0时输入结束。
输出
删除指定元素之后的顺序表
测试说明
平台会对你编写的代码进行测试:
测试输入:
5 1 2
1 2 3 4 5
3 1 3
1 5 6
4 3 4
1 2 3 4
3 4 5
1 2 3
0
预期输出:
3 4 5
5 6
1 2
1 2 3
方法一
#include<iostream>
using namespace std;
#define MAXSIZE 100
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int Status;
typedef struct SqList
{
int *elem;
int length;
}SqList;
void Delete_s_t(SqList &L,int s,int t)
{
//请在此编写代码
//注意删除以后修改顺序表表长
int j = 0; // j 是新顺序表的指针
// 遍历顺序表
for (int i = 0; i < L.length; i++) {
// 保留不在 [s, t] 范围内的元素
if (L.elem[i] < s || L.elem[i] > t) {
L.elem[j++] = L.elem[i]; // 保留该元素
}
}
// 更新顺序表的长度
L.length = j;
}
方法二
#include<iostream>
using namespace std;
#define MAXSIZE 100
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int Status;
typedef struct SqList
{
int *elem;
int length;
}SqList;
void Delete_s_t(SqList &L,int s,int t)
{
int i = 0,j=0;
while(L.elem[i] < s && i < L.length){
i++;
}
if(i >= L.length){
return;
}
while(L.elem[j] <= t && j < L.length){
j++;
}
while(j < L.length){
L.elem[i++] = L.elem[j++];
}
L.length = i;
}
方法二视频链接:顺序表第四题(删除指定范围值)_哔哩哔哩_bilibili
第五关 用一维数组模拟双栈
- 双栈是指两个顺序栈,是一种特殊的顺序栈。
任务描述
本关任务:
用一个大小为MAXSIZE的数组模拟双栈,其中分为0栈和1栈,0栈从数组低位向高位增长,1栈从数组高位向低位增长。
请实现双栈的push函数和pop函数
void push(DualStack &S,int i,int x),i表示是入栈0栈还是1栈,x表示入栈的元素值
int pop(DualStack &S,int i),i表示0栈或1栈出栈,返回出栈元素值
编程要求
输入
多组数据,每组数据有若干行,第一行为要执行的操作,第二行开始为具体的入栈和出栈操作。
以-1作为输入结束
输出
执行入栈和出栈操作以后的0栈和1栈元素,若栈为空输出NULL。
如在出入栈中发生错误,会输出提示信息
测试说明
平台会对你编写的代码进行测试:
测试输入:
4
push 0 1
push 0 2
push 1 9
push 1 8
11
push 0 1
push 0 2
push 0 3
push 0 4
push 0 5
push 1 99
push 1 98
push 1 97
push 1 96
push 1 95
push 1 94
3
push 1 3
push 1 4
pop 0
预期输出:
1 2
9 8
栈满
1 2 3 4 5
99 98 97 96 95
0栈空
NULL
3 4
#include <iostream>
#include <cstdlib>
using namespace std;
#define MAXSIZE 10
typedef struct
{
int* stack; //初始化后栈内均为0
int top[2]; // top为两个栈顶指针,记录了栈顶元素在数组中的下标。top[0]表示0栈,top[1]表示1栈
//初始情况top[0]=-1,top[1]=MAXSIZE
}DualStack;
void push(DualStack &S,int i,int x)
{
//x表示要入栈的元素,i表示要入的栈,i取值为0和1
//当栈满时输出 “栈满” 加换行符
//请在此处填入代码
if(i == 0){
//判断是否栈满
if(S.top[0] + 1 == S.top[1]){
printf("栈满\n");
return;
}
S.stack[++S.top[0]] = x;
}else if(i == 1){
//判断是否栈满
if(S.top[1] - 1 == S.top[0]){
printf("栈满\n");
return;
}
S.stack[--S.top[1]] = x;
}else{
return;
}
}
int pop(DualStack &S,int i)
{
//i表示要出栈的栈,i取值为0和1
//当栈空时输出“0栈空”或“1栈空”,加换行符
//当栈空时返回0,栈非空时返回出栈元素值
//请在此处填入代码
if(i == 0){
//判断是否栈空
if(S.top[0] == -1){
printf("0栈空\n");
return 0;
}
return S.stack[S.top[0]--];
}else if(i == 1){
//判断是否栈空
if(S.top[1] == MAXSIZE){
printf("1栈空\n");
return 0;
}
return S.stack[S.top[1]++];
}else{
return 0;
}
}