数据结构与算法OG题目
线性结构的应用
删除单链表中的元素
【问题描述】
已知单链表L(带头节点)是一个递增有序表,试编写一算法,删除表中值大于min且小于max的节点(若表中有这样的节点),同时释放被删节点的空间,这里min和max是两个给定参数。
【输入形式】
首先输入正整数T,表示有T组测试数据。输入整数len定义链表长度,然后递增地给出链表的值。接着输入正整数q,表示进行q次操作,每次操作输入一个整数type表示操作类型:输入1,表示输出链表; 输入2, 表示删除链表;在选择删除时同时输入min 和 max的值表示删除范围。例如:输入2 2 4,表示删除大于2小于4的值。最后再次输入1,输出删除元素后的单链表。
【输出形式】
输出建立的单链表和删除元素后的单链表。
【样例输入】
1
5
1 2 3 4 5
3
1
2 2 4
1
【样例输出】
1 2 3 4 5
1 2 4 5
- 代码示例:
#include <iostream>
#include <malloc.h>
using namespace std;
typedef int ElemType;
typedef struct LNode {
ElemType data;
LNode* next;
}LNode;
//链表初始化
LNode* IniLinked(int len) {
LNode* L;//头结点
LNode* r;//总是指向尾结点
LNode* p;//临时结点
L = (LNode*)malloc( sizeof(LNode) );
r = L;
L->next = NULL;
int x;//存储输入的值
while (len > 0) {
cin >> x;
p = (LNode*)malloc(sizeof(LNode));
p->data = x;
p->next = NULL;
r->next = p;
r = p;
len--;
}
return L;
}
//删除链表中的区间元素
void DeleteL(int min,int max,LNode* L) {
LNode* p = (LNode*)malloc(sizeof(LNode));
p = L;//行动指针
LNode* pp;//临时指针
while (p->next != NULL){
if (p->next->data > min && p->next->data < max) {
pp = p->next;
p->next = p->next->next;
free(pp);
}
else {
p = p->next;
}
}
}
//打印链表
void printLinked(LNode *L) {
LNode* p = L;
while (p->next != NULL) {
cout << p->next->data << " ";
p = p->next;
}
cout << std::endl;
}
int main() {
//输入正整数T,表示有T组测试数据
int T = 0;
cin >> T;
while (T > 0) {
//输入整数len定义链表长度
int len = 0;
cin >> len;
//递增地给出链表的值
LNode* L = IniLinked(len);
int q,type;
cin >> q;
while (q > 0){
cin >> type;
if (type == 1) {
printLinked(L);
}
if (type == 2) {
int min, max;
cin >> min >> max;
DeleteL(min, max, L);
}
q--;
}
T--;
}
}
约瑟夫问题
【问题描述】
有编号为1, 2…n 的 n 个人按顺时针方向围坐一圈,每人持有一个正整数密码(每个人持有的密码m不一定相同)。开始给定一个正整数 m,从第一个人按顺时针方向自1开始报数,报到m者出列,不再参加报数,这时将出列者的密码作为m,从出列者顺时针方向的下一人开始重新自1开始报数。如此下去,直到所有人都出列。试设计算法,输出出列者的序列。可采用顺序或链式存储结构实现
【输入形式】
第一行输入一正整数a(a<10),表示共有a组测试数据。每组测试数据的第一行有一个整数n(n<100),表示有n个人;第二行有n个数表示每人手中的正整数密码(每人密码大于0小于10000且不一定相等);第三行输入一个正整数m,即上文提到的初始密码m。
【输出形式】
每组测试数据输出一行正整数,表示出列者的序列(每个正整数之间用空格隔开,每行末尾无空格)。
【样例输入】
1
6
2 5 3 7 5 4
3
【样例输出】
3 6 5 2 4 1
- 代码示例:
#include <iostream>
#include <malloc.h>
using namespace std;
typedef int ElemType;
typedef struct LNode {
ElemType data;
LNode* next;
ElemType index;//索引
}LNode;
//链表初始化
LNode* IniLinked(int len) {
LNode* L;//头结点
LNode* r;//总是指向最后面结点
LNode* p;//临时结点
L = (LNode*)malloc(sizeof(LNode));
r = L;
L->next = NULL;
int x;//存储输入的值
int n = 0;
while (n < len) {
cin >> x;
p = (LNode*)malloc(sizeof(LNode));
p->data = x;
p->index = n+1;//存储结点自身的位置
p->next = L;//指向头结点
r->next = p;
r = p;
n++;
}
return L;
}
void YSF(LNode* L, int m, int n){
LNode* p = L;
LNode* pp;//临时,释放空间的
int nn = n ;//一共循环的次数
while (nn-- > 0){
while (m>1){
if (p->next == L){
p->next = L->next;
}
p = p->next;
m--;
}
m = p->next->data;
cout << p->next->index <<" ";
pp = p->next;
p->next = p->next->next;
free(pp);
}
}
int main() {
//输入正整数a,表示有a组测试数据
int a = 0;
cin >> a;
while (a > 0) {
//每组测试数据的第一行有一个整数n(n<100),表示有n个人;
int n;
cin >> n;
//第二行有n个数表示每人手中的正整数密码(每人密码大于0小于10000且不一定相等);
LNode* L = IniLinked(n);
//第三行输入一个正整数m,即上文提到的初始密码m。
int m = 0;
cin >> m;
YSF(L, m, n);
a--;
}
}
十进制数到N进制数的转换
【问题描述】
将从键盘输入的十进制数转换为N(如二进制、八进制、十六进制)进制数据。(A--10,B--12....Z-35 大小写敏感)
【输入形式】
输入一个正整数num(大于0且在int范围内),再输入一个N(2<=N<=36)表示要转换成多少进制。
【输出形式】
输出转换结果
【样例输入】
3 2
【样例输出】
11
- 代码示例:
#include <iostream>
#include <stdlib.h>
using namespace std;
#define StackInitSize 50
typedef int StackElementType;
typedef struct {//栈的结构体的定义
StackElementType data[StackInitSize];//栈的存储空间
int top;//栈顶指针
}SeqStack;
SeqStack* InitStack(){//栈的初始化
SeqStack* s;
s = (SeqStack* )malloc(sizeof(SeqStack));
if (s != NULL){
s->top = -1;
return s;
} else {
cout << "抱歉,申请内存失败,程序运行终止" << endl;
exit(0);
}
}
//进栈
void Push(SeqStack* s,StackElementType x){
if (s->top == StackInitSize) {
cout << "栈满!程序终止运行!" << endl;
exit(0);
} else {
s->top ++;
s->data[s->top] = x;
}
}
//设置数组
void setC(char C[]){
int i = 0;
for(;i<10;i++){
C[i]='0'+i;
}
for(;i<37;i++){
C[i]='A'+i-10;
}
}
//弹栈
int pop (SeqStack* s){
if (s->top == -1){
cout << "栈空" <<endl;
exit(0);
} else {
int x = s->data[s->top--];
return x;
}
}
int main(){
SeqStack* s = InitStack();
char C[36];
setC(C);
//cout << "输入num" <<endl;
int num, radix; // 输入的数和进制数
cin >> num;
//cout << "输入radix" <<endl;
cin >> radix;
while (1) {
Push(s, num % radix);
num /= radix;
if (num == 0)
break;
}
while (s->top != -1){
cout << C[pop(s)];
}
}
二叉树的操作
二叉树的创建与遍历
【问题描述】
- 以二叉链表为存储结构,实现二叉树的创建、遍历
实验要求:在程序中定义下述函数,并实现要求的函数功能:
CreateTree():按从键盘输入的扩展前序序列,创建二叉树
PreOrderTree():前序遍历树(递归)
InOrderTree():中序(非递归)遍历树
LaOrderTree(): 后序遍历树(递归)
【输入形式】
以扩展二叉树的前序遍历序列作为输入,创建二叉树。
【输出形式】
输出前、中、后序遍历结果
【样例输入】
AB#D##C##
【样例输出】
ABDC
BDAC
DBCA
- 代码示例:
#include<iostream>
#include<cstdlib>
using namespace std;
struct BiTNode{
char data;
BiTNode* lchild, * rchild;
};
//CreateTree():按从键盘输入的扩展前序序列,创建二叉树
BiTNode* CreateTree() {
BiTNode* T;
char ch = getchar();
if (ch == '#') T = NULL;
else {
T = (BiTNode*)malloc(sizeof(BiTNode));
if (!T) exit(1);
T->data = ch;
T->lchild = CreateTree();
T->rchild = CreateTree();
}
return T;
}
void PreOrderTree(BiTNode* root) {//前序递归遍历
if (root == NULL) return;
cout << root->data;
PreOrderTree(root->lchild);
PreOrderTree(root->rchild);
}
void LaOrderTree(BiTNode* root) {//中序递归遍历
if (root == NULL) return;
LaOrderTree(root->lchild);
LaOrderTree(root->rchild);
cout << root->data;
}
void InOrderTree(BiTNode* root) {//后序递归遍历
if (root == NULL) return;
InOrderTree(root->lchild);
cout << root->data;
InOrderTree(root->rchild);
}
void NOrderTree(BiTNode* root) {//中序非递归遍历
BiTNode* p;
BiTNode* stack[30];
int top = 0;
if (root == NULL) return;
p = root;
while (!(p==NULL && top == 0)){
while (p != NULL) {
if (top < 30 - 1) {
stack[top] = p;//将当前指针p压栈
top++;
}
else {
cout << "栈溢出" << endl;
return;
}
p = p->lchild;//指针指向p的左孩子
}
if (top <= 0) return;
else{
top--;
p = stack[top];
cout << p->data;
p = p->rchild;
}
}
}
int main() {
BiTNode* root;
root = CreateTree();
PreOrderTree(root);
cout << endl;
NOrderTree(root);
cout << endl;
LaOrderTree(root);
cout << endl;
}
求二叉树中节点的路径
【问题描述】
在二叉树中,P为二叉树中任一给定结点的值,编写算法求从根结点到P结点之间的路径。
实验要求:以二叉链表作为存储结构
【输入形式】
首先以扩展二叉树的前序遍历序列作为输入,创建二叉树。换一行输入p所指节点的值。
【输出形式】
输出从根节点到p节点的路径(结点序列)。
【样例输入】
AB#D##C##
【样例输出】
ABD
- 代码示例:
#include<iostream>
#include<cstdlib>
#include<stack>
using namespace std;
stack<char> s;
struct TreeNode {
char data;
TreeNode* lchild;
TreeNode* rchild;
};
TreeNode* CreateTree() {
TreeNode* T;
char ch = getchar();
if (ch == '#') T = NULL;
else {
T = (TreeNode*)malloc(sizeof(TreeNode));
if (!T) exit(1);
T->data = ch;
T->lchild = CreateTree();
T->rchild = CreateTree();
}
return T;
}
void path(TreeNode* root, char ch) {
TreeNode* s[20];
int top = -1, i;
TreeNode* p,* q;
p = root;
q = NULL;
while (p != NULL || top != -1) {
//遍历左子树
if (p) {
s[++top] = p;
p = p->lchild;
}
else {
p = s[top];
//右子树为空或者右子树已经访问
if (p->rchild == NULL || p->rchild == q) {
if (p->data == ch) {
for (i = 0; i <= top; i++)
cout << s[i]->data;
return;
}
else {
//q保存已经访问过的结点
q = p;
top--;
p = NULL;
}
}
//遍历右子树
else p = p->rchild;
}
}
}
int main() {
TreeNode* root;
root = CreateTree();
char x;
cin >> x;
path(root,x);
}
按层次顺序遍历二叉树
【问题描述】
编写按层次顺序遍历二叉树的算法
实验要求:以二叉链表作为存储结构
【输入形式】
以扩展二叉树前序遍历序列作为输入,创建二叉树。
【输出形式】
输出层次遍历节点的编号,每层按从左到右顺序输出。
【样例输入】
AB#D##C##
【样例输出】
ABCD
- 代码示例:
#include<iostream>
#include<cstdlib>
#include<queue>
using namespace std;
struct BiTNode {
char data;
BiTNode* lchild, *rchild;
};
//CreateTree():按从键盘输入的扩展前序序列,创建二叉树//AB#D##C##
BiTNode* CreateTree() {
BiTNode* T;
BiTNode* p;
char ch = getchar();
if (ch == '#') T = NULL;
else {
T = (BiTNode*)malloc(sizeof(BiTNode));
if (!T) exit(1);
T->data = ch;
T->lchild = CreateTree();
T->rchild = CreateTree();
}
return T;
}
void levelorder(BiTNode* x) {
if (x == NULL) return;
queue<BiTNode*> q;
q.push(x);
while (!q.empty()) {
BiTNode* p = q.front();
q.pop();
cout << p->data;
if (p->lchild != NULL) {
q.push(p->lchild);
}
if (p->rchild != NULL) {
q.push(p->rchild);
}
}
}
int main() {
BiTNode* root;
root = CreateTree();
levelorder(root);
}
求二叉树高度及宽度
【问题描述】
二叉树高度是指树中所有节点的最大层数,二叉树宽度是指在二叉树的各层上,具有节点数最多的那一层上的节点总数。编写算法求二叉树高度及宽度。
实验要求:以二叉链表作为存储结构
【输入形式】
以扩展二叉树的前序遍历序列作为输入,创建二叉树。
【输出形式】
输出二叉树的高度和宽度(中间有空格)
【样例输入】
AB#D##C##
【样例输出】
3 2
- 代码示例:
#include<iostream>
#include<cstdlib>
#include<queue>
using namespace std;
struct TreeNode {
char data;
TreeNode* lchild;
TreeNode* rchild;
};
TreeNode* CreateTree() {
TreeNode* T;
char ch = getchar();
if (ch == '#') T = NULL;
else {
T = (TreeNode*)malloc(sizeof(TreeNode));
if (!T) exit(1);
T->data = ch;
T->lchild = CreateTree();
T->rchild = CreateTree();
}
return T;
}
int getDeep(TreeNode* root) {
if (root == NULL) {
return 0;
}
else {
int lchild = getDeep(root->lchild);
int rchild = getDeep(root->rchild);
return 1 + (lchild > rchild ? lchild : rchild);
}
}
int levelorder(TreeNode* x) {
if (x == NULL) return 0;
queue<TreeNode*> q;
q.push(x);
int curCountInQueue = 0;//二叉树当前层已经存在队列中的个数
unsigned int maxwidth = 0;//节点数最大的层的节点数
while (!q.empty() ){
if (curCountInQueue == 0) {
maxwidth = maxwidth > q.size() ? maxwidth : q.size();
curCountInQueue = q.size();
}
TreeNode* p = q.front();
q.pop();
if (p->lchild != NULL) {
q.push(p->lchild);
}
if (p->rchild != NULL) {
q.push(p->rchild);
}
curCountInQueue--;
}
return maxwidth;
}
int main() {
TreeNode* root;
root = CreateTree();
cout << getDeep(root);
cout << " ";
cout << levelorder(root);
}
本文来自博客园,作者:NeverLateThanBetter,转载请注明原文链接:https://www.cnblogs.com/do-it-520/p/SJJG.html
韶华易逝,不能虚度年华。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?