docs: 添加仓库地址到README;chore: 整理实验分析;feat: Kruskal最小生成树与图存储结构

This commit is contained in:
2025-12-14 14:06:31 +08:00
parent be03307655
commit f2b8d1fe4c
52 changed files with 4600 additions and 291 deletions
+2 -2
View File
@@ -8,8 +8,8 @@
"args": [], "args": [],
"stopAtEntry": false, "stopAtEntry": false,
"externalConsole": true, "externalConsole": true,
"cwd": "d:/Code/C_code/数据结构/陈越数据结构", "cwd": "d:/Code/C_code/exercise",
"program": "d:/Code/C_code/数据结构/陈越数据结构/build/Debug/outDebug", "program": "d:/Code/C_code/exercise/build/Debug/outDebug",
"MIMode": "gdb", "MIMode": "gdb",
"miDebuggerPath": "gdb", "miDebuggerPath": "gdb",
"setupCommands": [ "setupCommands": [
+1 -1
View File
@@ -4,7 +4,7 @@
"C_Cpp_Runner.debuggerPath": "gdb", "C_Cpp_Runner.debuggerPath": "gdb",
"C_Cpp_Runner.cStandard": "c17", "C_Cpp_Runner.cStandard": "c17",
"C_Cpp_Runner.cppStandard": "c++17", "C_Cpp_Runner.cppStandard": "c++17",
"C_Cpp_Runner.msvcBatchPath": "C:/Program Files/Microsoft Visual Studio/VR_NR/Community/VC/Auxiliary/Build/vcvarsall.bat", "C_Cpp_Runner.msvcBatchPath": "",
"C_Cpp_Runner.useMsvc": false, "C_Cpp_Runner.useMsvc": false,
"C_Cpp_Runner.warnings": [ "C_Cpp_Runner.warnings": [
"-Wall", "-Wall",
+3
View File
@@ -3,6 +3,9 @@
## 项目简介 ## 项目简介
这是一个完整的C语言学习代码库,包含了从基础语法到高级项目的全面学习内容。代码库涵盖了翁凯老师C语言课程的所有章节练习、课堂代码实践以及完整的项目实战。 这是一个完整的C语言学习代码库,包含了从基础语法到高级项目的全面学习内容。代码库涵盖了翁凯老师C语言课程的所有章节练习、课堂代码实践以及完整的项目实战。
### 仓库地址
- GitHub仓库为:https://github.com/LHY0125/Learn_C.git
## 项目结构 ## 项目结构
### 📚 翁凯C语言/ - 系统化学习路径 ### 📚 翁凯C语言/ - 系统化学习路径
+177
View File
@@ -0,0 +1,177 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#ifdef _WIN32
#include <windows.h>
#include <direct.h>
#endif
#define MAX_SIZE 1000
// 栈结构用于存储数字
typedef struct
{
int data[MAX_SIZE];
int top;
} Stack;
// 初始化栈
void initStack(Stack *s)
{
s->top = -1;
}
// 判断栈是否为空
int isEmpty(Stack *s)
{
return s->top == -1;
}
// 入栈
void push(Stack *s, int value)
{
if (s->top < MAX_SIZE - 1)
{
s->data[++s->top] = value;
}
}
// 出栈
int pop(Stack *s)
{
if (!isEmpty(s))
{
return s->data[s->top--];
}
return 0;
}
// 获取栈顶元素
int peek(Stack *s)
{
if (!isEmpty(s))
{
return s->data[s->top];
}
return 0;
}
// 判断运算符优先级
int precedence(char op)
{
if (op == '+' || op == '-')
return 1;
if (op == '*' || op == '/')
return 2;
return 0;
}
// 执行运算
int calculate(int a, int b, char op)
{
switch (op)
{
case '+':
return a + b;
case '-':
return a - b;
case '*':
return a * b;
case '/':
return a / b;
default:
return 0;
}
}
// 计算表达式
int evaluateExpression(char *expression)
{
Stack numbers;
Stack operators;
initStack(&numbers);
initStack(&operators);
int len = strlen(expression);
for (int i = 0; i < len; i++)
{
// 跳过空格
if (expression[i] == ' ')
{
continue;
}
// 如果是数字
if (isdigit(expression[i]))
{
int num = 0;
// 读取完整的数字
while (i < len && isdigit(expression[i]))
{
num = num * 10 + (expression[i] - '0');
i++;
}
i--; // 回退一位,因为for循环会自动增加
push(&numbers, num);
}
// 如果是运算符
else if (expression[i] == '+' || expression[i] == '-' ||
expression[i] == '*' || expression[i] == '/')
{
// 处理运算符优先级
while (!isEmpty(&operators) &&
precedence((char)peek(&operators)) >= precedence(expression[i]))
{
int b = pop(&numbers);
int a = pop(&numbers);
char op = (char)pop(&operators);
push(&numbers, calculate(a, b, op));
}
push(&operators, expression[i]);
}
}
// 处理剩余的运算符
while (!isEmpty(&operators))
{
int b = pop(&numbers);
int a = pop(&numbers);
char op = (char)pop(&operators);
push(&numbers, calculate(a, b, op));
}
return pop(&numbers);
}
int main()
{
// 设置控制台编码为UTF-8,防止中文乱码
#ifdef _WIN32
system("chcp 65001 > nul"); // 设置控制台编码为UTF-8
SetConsoleOutputCP(65001); // 设置控制台输出编码
SetConsoleCP(65001); // 设置控制台输入编码
_mkdir("records");
#endif
char expression[MAX_SIZE];
// 读取表达式
if (fgets(expression, sizeof(expression), stdin) != NULL)
{
// 去除换行符
int len = strlen(expression);
if (len > 0 && expression[len - 1] == '\n')
{
expression[len - 1] = '\0';
}
// 计算并输出结果
int result = evaluateExpression(expression);
printf("%d\n", result);
}
return 0;
}
+158
View File
@@ -0,0 +1,158 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#define MAX_SIZE 10002
// 栈结构
typedef struct
{
char data[MAX_SIZE];
int top;
} Stack;
// 初始化栈
void initStack(Stack *s)
{
s->top = -1;
}
// 判断栈是否为空
bool isEmpty(Stack *s)
{
return s->top == -1;
}
// 判断栈是否已满
bool isFull(Stack *s)
{
return s->top == MAX_SIZE - 1;
}
// 入栈
bool push(Stack *s, char item)
{
if (isFull(s))
{
return false;
}
s->data[++s->top] = item;
return true;
}
// 出栈
bool pop(Stack *s, char *item)
{
if (isEmpty(s))
{
return false;
}
*item = s->data[s->top--];
return true;
}
// 判断字符是否为左括号
bool isLeftBracket(char c)
{
return c == '(' || c == '[' || c == '{';
}
// 判断字符是否为右括号
bool isRightBracket(char c)
{
return c == ')' || c == ']' || c == '}';
}
// 判断左右括号是否匹配
bool isMatching(char left, char right)
{
return (left == '(' && right == ')') ||
(left == '[' && right == ']') ||
(left == '{' && right == '}');
}
// 括号匹配验证函数
bool isValidBrackets(char *s)
{
Stack stack;
initStack(&stack);
int len = strlen(s);
// 空字符串返回true
if (len == 0)
{
return true;
}
for (int i = 0; i < len; i++)
{
char current = s[i];
// 如果是左括号,入栈
if (isLeftBracket(current))
{
if (!push(&stack, current))
{
// 栈满,返回false
return false;
}
}
// 如果是右括号,检查匹配
else if (isRightBracket(current))
{
// 栈为空,说明没有对应的左括号
if (isEmpty(&stack))
{
return false;
}
char top;
pop(&stack, &top);
// 检查是否匹配
if (!isMatching(top, current))
{
return false;
}
}
// 根据题目描述,输入只包含括号字符,不应该有其他字符
}
// 最后栈应该为空,表示所有括号都已匹配
return isEmpty(&stack);
}
int main()
{
char s[MAX_SIZE];
// 读取输入字符串
if (fgets(s, sizeof(s), stdin) != NULL)
{
// 去除换行符
int len = strlen(s);
if (len > 0 && s[len - 1] == '\n')
{
s[len - 1] = '\0';
}
// 验证括号匹配并输出结果
if (isValidBrackets(s))
{
printf("true\n");
}
else
{
printf("false\n");
}
}
else
{
// 如果读取失败,输出false
printf("false\n");
}
return 0;
}
+163
View File
@@ -0,0 +1,163 @@
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#ifdef _WIN32
#include <windows.h>
#include <direct.h>
#endif
#define NUM_COUNT 10000
#define INPUT_FILE "random_numbers.txt"
#define OUTPUT_FILE "sorted_numbers.txt"
/* 选择排序函数 */
void SelectSort(int arr[], int n)
{
int i, j, minIndex, temp;
for (i = 0; i < n - 1; i++)
{
// 假设当前索引i的元素为最小值
minIndex = i;
for (j = i + 1; j < n; j++)
{
// 在未排序部分查找更小元素
if (arr[j] < arr[minIndex])
{
// 更新最小值的索引
minIndex = j;
}
}
// 将找到的最小值与当前位置交换
if (minIndex != i)
{
temp = arr[i];
arr[i] = arr[minIndex];
arr[minIndex] = temp;
}
}
}
/* 生成随机数并写入文件 */
void MakeRandomNumber(const char *filename)
{
FILE *file = fopen(filename, "w");
if (file == NULL)
{
printf("错误:无法创建文件 %s\n", filename);
exit(1);
}
// 初始化随机数种子
srand((unsigned int)time(NULL));
for (int i = 0; i < NUM_COUNT; i++)
{
// 生成0-99999范围内的随机数
fprintf(file, "%d\n", rand() % 100000);
}
fclose(file);
printf("已生成 %d 个随机数到文件 %s\n", NUM_COUNT, filename);
}
/* 从文件读取数字到数组 */
int ReadNumbers(const char *filename, int arr[])
{
FILE *file = fopen(filename, "r");
if (file == NULL)
{
printf("错误:无法打开文件 %s\n", filename);
exit(1);
}
int count = 0;
while (fscanf(file, "%d", &arr[count]) != EOF && count < NUM_COUNT)
{
count++;
}
fclose(file);
printf("已从文件 %s 读取 %d 个数字\n", filename, count);
return count;
}
/* 将数组中的数字写入文件 */
void writeNumbersToFile(const char *filename, int arr[], int n)
{
FILE *file = fopen(filename, "w");
if (file == NULL)
{
printf("错误:无法创建文件 %s\n", filename);
exit(1);
}
for (int i = 0; i < n; i++)
{
fprintf(file, "%d\n", arr[i]);
}
fclose(file);
printf("已将 %d 个排序后的数字写入文件 %s\n", n, filename);
}
int main()
{
// 设置控制台编码为UTF-8,防止中文乱码
#ifdef _WIN32
system("chcp 65001 > nul"); // 设置控制台编码为UTF-8
SetConsoleOutputCP(65001); // 设置控制台输出编码
SetConsoleCP(65001); // 设置控制台输入编码
_mkdir("records");
#endif
int numbers[NUM_COUNT];
int actual_count;
clock_t start, end;
double time_used;
printf("=== 选择排序执行时间测量程序 ===\n");
// 生成随机数并写入文件
printf("\n1. 生成随机数...\n");
MakeRandomNumber(INPUT_FILE);
// 从文件读取数字到数组
printf("\n2. 读取文件...\n");
actual_count = ReadNumbers(INPUT_FILE, numbers);
// 显示部分未排序数据
printf("\n3. 未排序数据(前10个): ");
for (int i = 0; i < 10 && i < actual_count; i++)
{
printf("%d ", numbers[i]);
}
printf("\n");
// 测量选择排序执行时间
printf("\n4. 开始选择排序...\n");
// 记录开始时间
start = clock();
SelectSort(numbers, actual_count);
// 记录结束时间
end = clock();
// 计算并显示执行时间
time_used = ((double)(end - start)) / CLOCKS_PER_SEC;
printf("选择排序完成!\n");
printf("执行时间: %.6f 秒\n", time_used);
// 显示部分已排序数据
printf("\n6. 已排序数据(前10个): ");
for (int i = 0; i < 10 && i < actual_count; i++)
{
printf("%d ", numbers[i]);
}
printf("\n");
// 将排序后的数据写入新文件
printf("\n7. 写入排序结果...\n");
writeNumbersToFile(OUTPUT_FILE, numbers, actual_count);
printf("\n=== 程序执行完成 ===\n");
return 0;
}
+388
View File
@@ -0,0 +1,388 @@
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#ifdef _WIN32
#include <windows.h>
#include <direct.h>
#endif
// 定义双向链表节点结构体
struct Node
{
int data;
struct Node *prev;
struct Node *next;
};
// 定义双向链表结构体
struct DoubleList
{
struct Node *head;
struct Node *tail;
};
// 初始化双向链表
void initDoubleList(struct DoubleList *list)
{
list->head = NULL;
list->tail = NULL;
}
// 获取双向链表长度
int getListLength(struct DoubleList *list)
{
int length = 0;
struct Node *current = list->head;
while (current != NULL)
{
length++;
current = current->next;
}
return length;
}
// 向双向链表头部添加节点
void addNodeToHead(struct DoubleList *list, int data)
{
// 分配新节点内存
struct Node *newNode = (struct Node *)malloc(sizeof(struct Node));
newNode->data = data;
newNode->prev = NULL;
newNode->next = list->head;
// 如果链表为空,则新节点同时是头节点和尾节点
if (list->head == NULL)
{
list->tail = newNode;
}
else
{
list->head->prev = newNode;
}
// 更新头节点为新节点
list->head = newNode;
}
// 向双向链表尾部添加节点
void addNodeToTail(struct DoubleList *list, int data)
{
// 分配新节点内存
struct Node *newNode = (struct Node *)malloc(sizeof(struct Node));
newNode->data = data;
newNode->prev = list->tail;
newNode->next = NULL;
// 如果链表为空,则新节点同时是头节点和尾节点
if (list->tail == NULL)
{
list->head = newNode;
}
else
{
list->tail->next = newNode;
}
// 更新尾节点为新节点
list->tail = newNode;
}
// 在指定位置插入节点
void insertNode(struct DoubleList *list, int data, int position)
{
// 分配新节点内存
struct Node *newNode = (struct Node *)malloc(sizeof(struct Node));
newNode->data = data;
// 如果插入位置为0,则在头部插入
if (position == 0)
{
addNodeToHead(list, data);
}
// 如果插入位置大于等于链表长度,则在尾部插入
else if (position >= getListLength(list))
{
addNodeToTail(list, data);
}
// 否则,在指定位置插入
else
{
// 首先遍历到指定位置
struct Node *current = list->head;
for (int i = 0; i < position; i++)
{
current = current->next;
}
// 然后插入到指定位置
newNode->prev = current->prev;
newNode->next = current;
// 更新当前节点的前一个节点的next指针
current->prev->next = newNode;
// 更新当前节点的前指针为新节点
current->prev = newNode;
}
}
// 删除指定位置的节点
int delectNode(struct DoubleList *list, int position)
{
// 如果删除位置为0,则删除头节点
if (position == 0)
{
// 如果链表只有一个节点,则删除后链表为空
if (list->head == list->tail)
{
free(list->head);
list->head = NULL;
list->tail = NULL;
}
else
{
// 更新头节点为下一个节点
list->head = list->head->next;
// 释放旧头节点内存,更新新头节点的prev指针为NULL
free(list->head->prev);
list->head->prev = NULL;
}
return 1;
}
// 如果删除位置大于等于链表长度,则删除尾节点
else if (position >= getListLength(list))
{
// 更新尾节点为前一个节点
list->tail = list->tail->prev;
// 释放旧尾节点内存,更新新尾节点的next指针为NULL
free(list->tail->next);
list->tail->next = NULL;
return 1;
}
// 如果删除位置在中间,则删除指定位置节点
else
{
// 首先遍历到指定位置
struct Node *current = list->head;
for (int i = 0; i < position; i++)
{
current = current->next;
}
// 更新前一个节点的next指针为后一个节点
current->prev->next = current->next;
// 更新后一个节点的prev指针为前一个节点,更新当前节点的next指针为NULL
current->next->prev = current->prev;
free(current);
return 1;
}
}
// 修改指定位置节点的数据
int modifyNode(struct DoubleList *list, int data, int position)
{
// 首先遍历到指定位置
struct Node *current = list->head;
for (int i = 0; i < position; i++)
{
current = current->next;
}
// 修改节点数据
current->data = data;
return 1;
}
// 查找指定数据的节点位置
int findNodePosition(struct DoubleList *list, int data)
{
// 从头节点开始遍历
struct Node *current = list->head;
int position = 0;
while (current != NULL)
{
// 如果找到匹配数据,则返回当前位置
if (current->data == data)
{
return position;
}
// 否则,继续遍历下一个节点
current = current->next;
position++;
}
// 如果遍历完链表仍未找到匹配数据,则返回-1
return -1;
}
// 查找指定位置的节点数据
int findNodeData(struct DoubleList *list, int position)
{
// 首先遍历到指定位置
struct Node *current = list->head;
for (int i = 0; i < position; i++)
{
current = current->next;
}
// 返回当前节点数据
return current->data;
}
// 打印链表所有节点数据
void printList(struct DoubleList *list)
{
// 从头节点开始遍历
struct Node *current = list->head;
while (current != NULL)
{
// 打印当前节点数据
printf("%d ", current->data);
// 继续遍历下一个节点
current = current->next;
}
// 打印换行符
printf("\n");
}
int main()
{
// 设置控制台编码为UTF-8,防止中文乱码
#ifdef _WIN32
system("chcp 65001 > nul"); // 设置控制台编码为UTF-8
SetConsoleOutputCP(65001); // 设置控制台输出编码
SetConsoleCP(65001); // 设置控制台输入编码
#endif
// 初始化双端链表
struct DoubleList list;
initDoubleList(&list);
// 输入节点数据
printf("请输入初始节点数据的数量(默认在链表尾端插入):");
int count;
scanf("%d", &count);
for (int i = 0; i < count; i++)
{
printf("请输入第 %d 个节点数据:", i + 1);
int data;
scanf("%d", &data);
addNodeToTail(&list, data);
}
while (1)
{
// 打印菜单
printf("1. 插入节点\n");
printf("2. 删除节点\n");
printf("3. 修改节点\n");
printf("4. 查找节点\n");
printf("5. 打印链表\n");
printf("0. 退出程序\n");
printf("请输入操作选择:");
int choice;
scanf("%d", &choice);
// 根据选择执行相应操作
switch (choice)
{
case 1:
printf("1. 在链表头插入节点\n");
printf("2. 在链表尾插入节点\n");
printf("3. 在指定位置插入节点\n");
printf("请输入插入方式选择:");
int addchoice;
scanf("%d", &addchoice);
printf("请输入要插入的数据:");
int insertData;
scanf("%d", &insertData);
switch (addchoice)
{
case 1:
addNodeToHead(&list, insertData);
break;
case 2:
addNodeToTail(&list, insertData);
break;
case 3:
printf("请输入要插入的位置:");
int insertPosition;
scanf("%d", &insertPosition);
insertNode(&list, insertData, insertPosition);
break;
default:
printf("无效选择,请重新输入\n");
break;
}
break;
case 2:
printf("请输入要删除的位置:");
int deletePosition;
scanf("%d", &deletePosition);
delectNode(&list, deletePosition);
break;
case 3:
printf("请输入要修改的数据:");
int modifyData;
scanf("%d", &modifyData);
printf("请输入要修改的位置:");
int modifyPosition;
scanf("%d", &modifyPosition);
modifyNode(&list, modifyData, modifyPosition);
break;
case 4:
printf("1. 查找指定数据的节点位置\n");
printf("2. 查找指定位置的节点数据\n");
printf("请输入查找方式选择:");
int findchoice;
scanf("%d", &findchoice);
switch (findchoice)
{
case 1:
printf("请输入要查找的数据:");
int findData;
scanf("%d", &findData);
int position = findNodePosition(&list, findData);
if (position != -1)
{
printf("数据 %d 位于链表第 %d 个节点\n", findData, position);
}
else
{
printf("链表中不存在数据 %d\n", findData);
}
break;
case 2:
printf("请输入要查找的位置:");
int findPosition;
scanf("%d", &findPosition);
int data = findNodeData(&list, findPosition);
if (data != -1)
{
printf("链表第 %d 个节点的数据为 %d\n", findPosition, data);
}
else
{
printf("链表中不存在第 %d 个节点\n", findPosition);
}
break;
default:
printf("无效选择,请重新输入\n");
break;
}
break;
case 5:
printList(&list);
break;
case 0:
printf("程序退出\n");
return 0;
default:
printf("无效选择,请重新输入\n");
break;
}
}
return 0;
}
+136
View File
@@ -0,0 +1,136 @@
#ifdef _WIN32
#include <windows.h>
#include <direct.h>
#endif
#include <stdio.h>
#include <stdlib.h>
// 二叉树节点定义
typedef struct BiTNode {
char data;
struct BiTNode *lchild;
struct BiTNode *rchild;
} BiTNode, *BiTree;
static void CreateBiTree(BiTree *T) {
char ch;
if (scanf(" %c", &ch) != 1) {
*T = NULL;
return;
}
if (ch == '#') {
*T = NULL;
} else {
*T = (BiTNode *)malloc(sizeof(BiTNode));
if (!*T) {
fprintf(stderr, "内存分配失败\n");
exit(EXIT_FAILURE);
}
(*T)->data = ch;
CreateBiTree(&(*T)->lchild);
CreateBiTree(&(*T)->rchild);
}
}
static void PreOrderTraverse(BiTree T) {
if (T) {
putchar(T->data);
putchar(' ');
PreOrderTraverse(T->lchild);
PreOrderTraverse(T->rchild);
}
}
static void InOrderTraverse(BiTree T) {
if (T) {
InOrderTraverse(T->lchild);
putchar(T->data);
putchar(' ');
InOrderTraverse(T->rchild);
}
}
static void PostOrderTraverse(BiTree T) {
if (T) {
PostOrderTraverse(T->lchild);
PostOrderTraverse(T->rchild);
putchar(T->data);
putchar(' ');
}
}
static void DestroyTree(BiTree T) {
if (!T) return;
DestroyTree(T->lchild);
DestroyTree(T->rchild);
free(T);
}
static void PrintMenu(void) {
printf("\n--- 选择遍历方式 ---\n");
printf("1. 先序遍历\n");
printf("2. 中序遍历\n");
printf("3. 后序遍历\n");
printf("4. 退出\n");
printf("请输入选择 (1-4): ");
}
int main() {
// 设置控制台编码为UTF-8,防止中文乱码
#ifdef _WIN32
system("chcp 65001 > nul"); // 设置控制台编码为UTF-8
SetConsoleOutputCP(65001); // 设置控制台输出编码
SetConsoleCP(65001); // 设置控制台输入编码
#endif
// 初始化二叉树
BiTree T = NULL;
int choice = 0;
printf("=== 链式二叉树遍历系统 ===\n");
printf("请输入先序扩展序列构建二叉树(# 表示空节点,例如 AB#C##D##):\n");
// 构建二叉树
CreateBiTree(&T);
// 主循环处理用户选择
while (choice != 4)
{
PrintMenu();
if (scanf("%d", &choice) != 1)
{
fprintf(stderr, "输入错误,程序结束。\n");
break;
}
switch (choice)
{
case 1:
// 先序遍历
printf("先序遍历结果: ");
PreOrderTraverse(T);
putchar('\n');
break;
case 2:
// 中序遍历
printf("中序遍历结果: ");
InOrderTraverse(T);
putchar('\n');
break;
case 3:
// 后序遍历
printf("后序遍历结果: ");
PostOrderTraverse(T);
putchar('\n');
break;
case 4:
printf("程序已退出。\n");
break;
default:
printf("无效输入,请输入 1~4 之间的数字!\n");
}
}
// 销毁二叉树
DestroyTree(T);
return 0;
}
+42
View File
@@ -0,0 +1,42 @@
// 二叉树先序遍历(给出每个结点的左右孩子编号)
// 输入:n,随后 n 行,每行两个整数 l、r 表示结点 i 的左右孩子编号(0 表示空)
// 根节点固定为 1。输出:先序遍历序列(每个数字后均有一个空格)。
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int n;
if (scanf("%d", &n) != 1) return 0;
int *L = (int *)malloc((n + 1) * sizeof(int));
int *R = (int *)malloc((n + 1) * sizeof(int));
if (!L || !R) return 0;
for (int i = 1; i <= n; ++i) {
int l, r;
if (scanf("%d %d", &l, &r) != 2) {
free(L); free(R);
return 0;
}
L[i] = l; R[i] = r;
}
// 迭代版先序遍历,避免最坏情况下递归栈溢出(n 可达 1e5)
int *stack = (int *)malloc((n + 1) * sizeof(int));
int top = 0;
stack[top++] = 1; // 根节点编号为 1
while (top) {
int u = stack[--top];
if (u == 0) continue;
printf("%d ", u);
// 先压右再压左,保证左子树先被访问
if (R[u]) stack[top++] = R[u];
if (L[u]) stack[top++] = L[u];
}
free(stack);
free(L); free(R);
return 0;
}
+43
View File
@@ -0,0 +1,43 @@
// 二叉树中序遍历(给出每个结点的左右孩子编号,根为1)
// 输入:n,随后 n 行,每行两个整数 l、r(0 表示空)。
// 输出:中序遍历序列,每个数字后均输出一个空格。
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int n;
if (scanf("%d", &n) != 1) return 0;
int *L = (int *)malloc((n + 1) * sizeof(int));
int *R = (int *)malloc((n + 1) * sizeof(int));
if (!L || !R) return 0;
for (int i = 1; i <= n; ++i) {
int l, r;
if (scanf("%d %d", &l, &r) != 2) {
free(L); free(R);
return 0;
}
L[i] = l; R[i] = r;
}
// 迭代式中序遍历:一路向左压栈,弹栈访问,再转向右子树
int *stack = (int *)malloc((n + 1) * sizeof(int));
int top = 0;
int cur = 1; // 根节点编号为 1
while (cur || top) {
while (cur) { // 沿左链入栈
stack[top++] = cur;
cur = L[cur];
}
int u = stack[--top];
printf("%d ", u);
cur = R[u];
}
free(stack);
free(L); free(R);
return 0;
}
+49
View File
@@ -0,0 +1,49 @@
// 二叉树后序遍历(给出每个结点的左右孩子编号,根为1)
// 输入:n,随后 n 行,每行两个整数 l、r(0 表示空)。
// 输出:后序遍历序列,每个数字后均输出一个空格。
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int n;
if (scanf("%d", &n) != 1) return 0;
int *L = (int *)malloc((n + 1) * sizeof(int));
int *R = (int *)malloc((n + 1) * sizeof(int));
if (!L || !R) return 0;
for (int i = 1; i <= n; ++i) {
int l, r;
if (scanf("%d %d", &l, &r) != 2) {
free(L); free(R);
return 0;
}
L[i] = l; R[i] = r;
}
// 迭代式后序遍历:使用两个栈
// 栈1:根右左;栈2:左右根(输出时弹出栈2)
int *s1 = (int *)malloc((n + 1) * sizeof(int));
int *s2 = (int *)malloc((n + 1) * sizeof(int));
int t1 = 0, t2 = 0;
s1[t1++] = 1; // 根节点为 1
while (t1) {
int u = s1[--t1];
if (u == 0) continue;
s2[t2++] = u;
// 先压左,再压右,使栈2形成 左右根 的逆序
if (L[u]) s1[t1++] = L[u];
if (R[u]) s1[t1++] = R[u];
}
while (t2) {
int u = s2[--t2];
printf("%d ", u);
}
free(s1); free(s2);
free(L); free(R);
return 0;
}
+41
View File
@@ -0,0 +1,41 @@
// 非递归先序遍历(给出每个结点的左右孩子编号,根为1)
// 输入:n,随后 n 行,每行两个整数 l、r(0 表示无孩子)。
// 输出:先序遍历序列,每个数字后均输出一个空格。
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int n;
if (scanf("%d", &n) != 1) return 0;
int *L = (int *)malloc((n + 1) * sizeof(int));
int *R = (int *)malloc((n + 1) * sizeof(int));
if (!L || !R) return 0;
for (int i = 1; i <= n; ++i) {
int l, r;
if (scanf("%d %d", &l, &r) != 2) {
free(L); free(R);
return 0;
}
L[i] = l; R[i] = r;
}
// 迭代版先序遍历:使用一个栈,根开始;弹出访问当前结点,先压右再压左
int *stack = (int *)malloc((n + 1) * sizeof(int));
int top = 0;
stack[top++] = 1; // 根节点为 1
while (top) {
int u = stack[--top];
if (u == 0) continue;
printf("%d ", u);
if (R[u]) stack[top++] = R[u];
if (L[u]) stack[top++] = L[u];
}
free(stack);
free(L); free(R);
return 0;
}
+43
View File
@@ -0,0 +1,43 @@
// 非递归中序遍历。给出每个结点的左右孩子编号,根为 1。
// 输入:n,随后 n 行,每行两个整数 l、r(0 表示无孩子)。
// 输出:中序遍历序列,每个数字后均输出一个空格。
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int n;
if (scanf("%d", &n) != 1) return 0;
int *L = (int *)malloc((n + 1) * sizeof(int));
int *R = (int *)malloc((n + 1) * sizeof(int));
if (!L || !R) return 0;
for (int i = 1; i <= n; ++i) {
int l, r;
if (scanf("%d %d", &l, &r) != 2) {
free(L); free(R);
return 0;
}
L[i] = l; R[i] = r;
}
// 非递归中序遍历(栈)
int *stack = (int *)malloc((n + 1) * sizeof(int));
int top = 0;
int cur = 1; // 根结点为 1
while (cur || top) {
while (cur) { // 沿左链压栈
stack[top++] = cur;
cur = L[cur];
}
int u = stack[--top]; // 访问栈顶
printf("%d ", u);
cur = R[u]; // 转向右子树
}
free(stack);
free(L); free(R);
return 0;
}
+52
View File
@@ -0,0 +1,52 @@
// 非递归后序遍历(给出每个结点的左右孩子编号,根为1)
// 输入:n,随后 n 行,每行两个整数 l、r(0 表示无孩子)。
// 输出:后序遍历序列,每个数字后均输出一个空格。
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int n;
if (scanf("%d", &n) != 1) return 0;
int *L = (int *)malloc((n + 1) * sizeof(int));
int *R = (int *)malloc((n + 1) * sizeof(int));
if (!L || !R) return 0;
for (int i = 1; i <= n; ++i) {
int l, r;
if (scanf("%d %d", &l, &r) != 2) {
free(L); free(R);
return 0;
}
L[i] = l; R[i] = r;
}
// 单栈 + 最近访问标记 实现后序遍历
int *stack = (int *)malloc((n + 1) * sizeof(int));
int top = 0;
int cur = 1; // 根结点编号为 1
int prev = 0; // 最近一次输出的结点编号
while (cur || top) {
if (cur) {
stack[top++] = cur;
cur = L[cur]; // 沿左链压栈
} else {
int u = stack[top - 1];
// 若右子树存在且未被处理,则转向右子树
if (R[u] && prev != R[u]) {
cur = R[u];
} else {
// 右子树为空或已处理,弹栈并输出该结点
--top;
printf("%d ", u);
prev = u;
}
}
}
free(stack);
free(L); free(R);
return 0;
}
+50
View File
@@ -0,0 +1,50 @@
// 题目描述
// 给定一个只包括()
// {} [] 的字符串
// s
// s ,判断字符串是否有效。
// 有效字符串需满足:
// 左括号必须用相同类型的右括号闭合。
// 左括号必须以正确的顺序闭合。
// 每个右括号都有一个对应的相同类型的左括号。
// 输入
// 输入一个字符串
// s
// (
// 1
// ≤ s
// ≤ 10 4)
// s(1≤s≤10 4)。
// 输出
// 有效字符串输出 true,否则输出 false。
// 样例
// 输入 #1 复制代码()
// 输出 #1 复制代码
// true 输入 #2 复制代码()[]
// {
// }
// 输出 #2
// 复制代码
// true
// 输入 #3
// 复制代码
// (]
// 输出 #3
// 复制代码
// false
// 输入 #4
// 复制代码
// ([])
// 输出 #4
// 复制代码
// true
// 输入 #5
// 复制代码
// ()[{]}
// 输出 #5
// 复制代码
//
+44
View File
@@ -0,0 +1,44 @@
// 非递归层序遍历(BFS)(给出每个结点的左右孩子编号,根为1)
// 输入:n,随后 n 行,每行两个整数 l、r(0 表示无孩子)。
// 输出:层序遍历序列,每个数字后均输出一个空格。
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int n;
if (scanf("%d", &n) != 1) return 0;
if (n <= 0) return 0;
int *L = (int *)malloc((n + 1) * sizeof(int));
int *R = (int *)malloc((n + 1) * sizeof(int));
if (!L || !R) return 0;
for (int i = 1; i <= n; ++i) {
int l, r;
if (scanf("%d %d", &l, &r) != 2) {
free(L); free(R);
return 0;
}
L[i] = l; R[i] = r;
}
// 队列 BFS,从根 1 开始,左到右按层输出
int *q = (int *)malloc((n + 1) * sizeof(int));
if (!q) { free(L); free(R); return 0; }
int head = 0, tail = 0;
q[tail++] = 1; // 根节点为 1
while (head < tail) {
int u = q[head++];
if (u == 0) continue;
printf("%d ", u);
if (L[u]) q[tail++] = L[u];
if (R[u]) q[tail++] = R[u];
}
free(q);
free(L); free(R);
return 0;
}
+88
View File
@@ -0,0 +1,88 @@
// 前序线索二叉树构建(根为1
// 输入:n,随后 n 行,每行两个整数 l、r(0 表示无孩子)。
// 输出:n 行,每行四个整数:lchild(i) ltag(i) rchild(i) rtag(i)
// 规则:
// - 若有左儿子:ltag(i)=0lchild(i) 为左儿子编号;否则 ltag(i)=1,lchild(i) 为前序前驱,无前驱为 -2。
// - 若有右儿子:rtag(i)=0rchild(i) 为右儿子编号;否则 rtag(i)=1,rchild(i) 为前序后继,无后继为 -1。
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int n;
if (scanf("%d", &n) != 1) return 0;
if (n <= 0) return 0;
int *L = (int *)malloc((n + 1) * sizeof(int));
int *R = (int *)malloc((n + 1) * sizeof(int));
if (!L || !R) return 0;
for (int i = 1; i <= n; ++i) {
int l, r;
if (scanf("%d %d", &l, &r) != 2) {
free(L); free(R);
return 0;
}
L[i] = l; R[i] = r;
}
// 迭代前序遍历,生成访问序列 order
int *stack = (int *)malloc((n + 1) * sizeof(int));
int *order = (int *)malloc(n * sizeof(int));
if (!stack || !order) { free(L); free(R); return 0; }
int top = 0, k = 0;
stack[top++] = 1; // 根为 1
while (top) {
int u = stack[--top];
if (u == 0) continue;
order[k++] = u;
if (R[u]) stack[top++] = R[u];
if (L[u]) stack[top++] = L[u];
}
// 位置映射:pos[node] = 在前序序列中的索引
int *pos = (int *)malloc((n + 1) * sizeof(int));
if (!pos) { free(stack); free(order); free(L); free(R); return 0; }
for (int i = 1; i <= n; ++i) pos[i] = -1;
for (int i = 0; i < k; ++i) pos[order[i]] = i;
// 输出域与标记域
int *outL = (int *)malloc((n + 1) * sizeof(int));
int *ltag = (int *)malloc((n + 1) * sizeof(int));
int *outR = (int *)malloc((n + 1) * sizeof(int));
int *rtag = (int *)malloc((n + 1) * sizeof(int));
if (!outL || !ltag || !outR || !rtag) {
free(pos); free(stack); free(order); free(L); free(R);
return 0;
}
for (int i = 1; i <= n; ++i) {
if (L[i]) { // 有左儿子
ltag[i] = 0;
outL[i] = L[i];
} else { // 无左儿子,线索到前序前驱
ltag[i] = 1;
if (pos[i] > 0) outL[i] = order[pos[i] - 1];
else outL[i] = -2; // 无前驱
}
if (R[i]) { // 有右儿子
rtag[i] = 0;
outR[i] = R[i];
} else { // 无右儿子,线索到前序后继
rtag[i] = 1;
if (pos[i] >= 0 && pos[i] < k - 1) outR[i] = order[pos[i] + 1];
else outR[i] = -1; // 无后继
}
}
for (int i = 1; i <= n; ++i) {
printf("%d %d %d %d\n", outL[i], ltag[i], outR[i], rtag[i]);
}
free(outL); free(ltag); free(outR); free(rtag);
free(pos); free(stack); free(order);
free(L); free(R);
return 0;
}
+91
View File
@@ -0,0 +1,91 @@
// 中序线索二叉树构建(根为1
// 输入:n,随后 n 行,每行两个整数 l、r(0 表示无孩子)。
// 输出:n 行,每行四个整数:lchild(i) ltag(i) rchild(i) rtag(i)
// 规则:
// - 若有左儿子:ltag(i)=0lchild(i) 为左儿子编号;否则 ltag(i)=1,lchild(i) 为中序前驱,无前驱为 -2。
// - 若有右儿子:rtag(i)=0rchild(i) 为右儿子编号;否则 rtag(i)=1,rchild(i) 为中序后继,无后继为 -1。
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int n;
if (scanf("%d", &n) != 1) return 0;
if (n <= 0) return 0;
int *L = (int *)malloc((n + 1) * sizeof(int));
int *R = (int *)malloc((n + 1) * sizeof(int));
if (!L || !R) return 0;
for (int i = 1; i <= n; ++i) {
int l, r;
if (scanf("%d %d", &l, &r) != 2) {
free(L); free(R);
return 0;
}
L[i] = l; R[i] = r;
}
// 迭代中序遍历,生成访问序列 order
int *stack = (int *)malloc((n + 1) * sizeof(int));
int *order = (int *)malloc(n * sizeof(int));
if (!stack || !order) { free(L); free(R); return 0; }
int top = 0, k = 0;
int cur = 1; // 根为 1
while (cur || top) {
if (cur) {
stack[top++] = cur;
cur = L[cur];
} else {
int u = stack[--top];
order[k++] = u;
cur = R[u];
}
}
// 位置映射:pos[node] = 在中序序列中的索引
int *pos = (int *)malloc((n + 1) * sizeof(int));
if (!pos) { free(stack); free(order); free(L); free(R); return 0; }
for (int i = 1; i <= n; ++i) pos[i] = -1;
for (int i = 0; i < k; ++i) pos[order[i]] = i;
// 输出域与标记域
int *outL = (int *)malloc((n + 1) * sizeof(int));
int *ltag = (int *)malloc((n + 1) * sizeof(int));
int *outR = (int *)malloc((n + 1) * sizeof(int));
int *rtag = (int *)malloc((n + 1) * sizeof(int));
if (!outL || !ltag || !outR || !rtag) {
free(pos); free(stack); free(order); free(L); free(R);
return 0;
}
for (int i = 1; i <= n; ++i) {
if (L[i]) { // 有左儿子
ltag[i] = 0;
outL[i] = L[i];
} else { // 无左儿子,线索到中序前驱
ltag[i] = 1;
if (pos[i] > 0) outL[i] = order[pos[i] - 1];
else outL[i] = -2; // 无前驱
}
if (R[i]) { // 有右儿子
rtag[i] = 0;
outR[i] = R[i];
} else { // 无右儿子,线索到中序后继
rtag[i] = 1;
if (pos[i] >= 0 && pos[i] < k - 1) outR[i] = order[pos[i] + 1];
else outR[i] = -1; // 无后继
}
}
for (int i = 1; i <= n; ++i) {
printf("%d %d %d %d\n", outL[i], ltag[i], outR[i], rtag[i]);
}
free(outL); free(ltag); free(outR); free(rtag);
free(pos); free(stack); free(order);
free(L); free(R);
return 0;
}
+98
View File
@@ -0,0 +1,98 @@
// 后序线索二叉树构建(根为1
// 输入:n,随后 n 行,每行两个整数 l、r(0 表示无孩子)。
// 输出:n 行,每行四个整数:lchild(i) ltag(i) rchild(i) rtag(i)
// 规则:
// - 若有左儿子:ltag(i)=0lchild(i) 为左儿子编号;否则 ltag(i)=1,lchild(i) 为后序前驱,无前驱为 -2。
// - 若有右儿子:rtag(i)=0rchild(i) 为右儿子编号;否则 rtag(i)=1,rchild(i) 为后序后继,无后继为 -1。
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int n;
if (scanf("%d", &n) != 1) return 0;
if (n <= 0) return 0;
int *L = (int *)malloc((n + 1) * sizeof(int));
int *R = (int *)malloc((n + 1) * sizeof(int));
if (!L || !R) return 0;
for (int i = 1; i <= n; ++i) {
int l, r;
if (scanf("%d %d", &l, &r) != 2) {
free(L); free(R);
return 0;
}
L[i] = l; R[i] = r;
}
// 迭代后序遍历,生成访问序列 order
int *stack = (int *)malloc((n + 1) * sizeof(int));
int *order = (int *)malloc(n * sizeof(int));
if (!stack || !order) { free(L); free(R); return 0; }
int top = 0, k = 0;
int cur = 1; // 根为 1
int prev = 0; // 最近已输出的结点
while (cur || top) {
if (cur) {
stack[top++] = cur;
cur = L[cur]; // 沿左链压栈
} else {
int u = stack[top - 1];
if (R[u] && prev != R[u]) {
cur = R[u]; // 右子树存在且未处理,转向右子树
} else {
// 右子树为空或已处理,弹栈并记录该结点
--top;
order[k++] = u;
prev = u;
}
}
}
// 位置映射:pos[node] = 在后序序列中的索引
int *pos = (int *)malloc((n + 1) * sizeof(int));
if (!pos) { free(stack); free(order); free(L); free(R); return 0; }
for (int i = 1; i <= n; ++i) pos[i] = -1;
for (int i = 0; i < k; ++i) pos[order[i]] = i;
// 输出域与标记域
int *outL = (int *)malloc((n + 1) * sizeof(int));
int *ltag = (int *)malloc((n + 1) * sizeof(int));
int *outR = (int *)malloc((n + 1) * sizeof(int));
int *rtag = (int *)malloc((n + 1) * sizeof(int));
if (!outL || !ltag || !outR || !rtag) {
free(pos); free(stack); free(order); free(L); free(R);
return 0;
}
for (int i = 1; i <= n; ++i) {
if (L[i]) { // 有左儿子
ltag[i] = 0;
outL[i] = L[i];
} else { // 无左儿子,线索到后序前驱
ltag[i] = 1;
if (pos[i] > 0) outL[i] = order[pos[i] - 1];
else outL[i] = -2; // 无前驱
}
if (R[i]) { // 有右儿子
rtag[i] = 0;
outR[i] = R[i];
} else { // 无右儿子,线索到后序后继
rtag[i] = 1;
if (pos[i] >= 0 && pos[i] < k - 1) outR[i] = order[pos[i] + 1];
else outR[i] = -1; // 无后继
}
}
for (int i = 1; i <= n; ++i) {
printf("%d %d %d %d\n", outL[i], ltag[i], outR[i], rtag[i]);
}
free(outL); free(ltag); free(outR); free(rtag);
free(pos); free(stack); free(order);
free(L); free(R);
return 0;
}
+209
View File
@@ -0,0 +1,209 @@
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#ifdef _WIN32
#include <windows.h>
#include <direct.h>
#endif
// 栈结构定义
typedef struct
{
long long *data;
int top;
int capacity;
} Stack;
// 栈初始化
void stack_init(Stack *st, int initial_capacity)
{
int cap = initial_capacity > 0 ? initial_capacity : 2;
st->data = (long long *)malloc(sizeof(long long) * cap);
st->top = 0;
st->capacity = cap;
}
// 栈释放
void stack_free(Stack *st)
{
free(st->data);
st->data = NULL;
st->top = 0;
st->capacity = 0;
}
// 栈是否为空
int stack_empty(const Stack *st)
{
return st->top == 0;
}
// 栈压栈
void stack_push(Stack *st, long long v)
{
if (st->top >= st->capacity)
{
int new_cap = st->capacity ? st->capacity * 2 : 2;
long long *nd = (long long *)realloc(st->data, sizeof(long long) * new_cap);
if (!nd)
{
free(st->data);
exit(0);
}
st->data = nd;
st->capacity = new_cap;
}
st->data[st->top++] = v;
}
// 栈弹栈
long long stack_pop(Stack *st)
{
if (st->top == 0)
{
return 0;
}
return st->data[--st->top];
}
// 栈顶元素
long long stack_top(const Stack *st)
{
if (st->top == 0)
{
return 0;
}
return st->data[st->top - 1];
}
int main(void)
{
// 设置控制台编码为UTF-8,防止中文乱码
#ifdef _WIN32
system("chcp 65001 > nul"); // 设置控制台编码为UTF-8
SetConsoleOutputCP(65001); // 设置控制台输出编码
SetConsoleCP(65001); // 设置控制台输入编码
#endif
// 动态读取一行表达式
size_t cap = 1024, len = 0;
char *s = (char *)malloc(cap);
if (!s)
return 0;
int ch;
// 读取表达式
while ((ch = getchar()) != EOF && ch != '\n')
{
if (len + 1 >= cap)
{
// 容量不足时,倍增扩容
cap <<= 1;
char *ns = (char *)realloc(s, cap);
if (!ns)
{
free(s);
return 0;
}
s = ns;
}
// 逐字符写入
s[len++] = (char)ch;
}
s[len] = '\0';
if (len == 0)
{
free(s);
return 0;
}
Stack st;
stack_init(&st, (int)len + 1);
long long num = 0;
// 记录最近的运算符,初始为加号
char op = '+';
for (size_t i = 0; i < len; ++i)
{
char c = s[i];
// 跳过空格字符
if (isspace((unsigned char)c))
continue;
if (isdigit((unsigned char)c))
{
// 累积多位数字
num = num * 10 + (c - '0');
}
else
{
// 根据“前一个”运算符 op 处理当前数字 num;
// 乘除即时计算以确保高于加减的优先级
switch (op)
{
case '+':
stack_push(&st, num);
break;
case '-':
stack_push(&st, -num);
break;
case '*':
{
long long a = stack_pop(&st);
stack_push(&st, a * num);
break;
}
case '/':
{
long long a = stack_pop(&st);
stack_push(&st, a / num);
break;
}
default:
break;
}
// 更新待应用的运算符为当前位置字符
op = c;
// 重置当前数字,继续解析
num = 0;
}
}
// 处理末尾累积数字(循环结束后最后一个数尚未被处理)
switch (op)
{
case '+':
stack_push(&st, num);
break;
case '-':
stack_push(&st, -num);
break;
case '*':
{
long long a = stack_pop(&st);
stack_push(&st, a * num);
break;
}
case '/':
{
long long a = stack_pop(&st);
// C 的整数除法向零截断
stack_push(&st, a / num);
break;
}
default:
break;
}
long long ans = 0;
// 栈中为已应用乘除的加减项,累加得到结果
while (!stack_empty(&st))
ans += stack_pop(&st);
printf("%lld\n", ans);
stack_free(&st);
free(s);
return 0;
}
+86
View File
@@ -0,0 +1,86 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef _WIN32
#include <windows.h>
#include <direct.h>
#endif
// 简单环形队列
typedef struct
{
int *buf;
int cap;
int head;
int tail;
int len;
} Queue;
static void q_init(Queue *q, int cap)
{
q->buf = (int *)malloc(sizeof(int) * cap);
q->cap = cap;
q->head = 0;
q->tail = 0;
q->len = 0;
}
static int q_empty(const Queue *q) { return q->len == 0; }
static void q_push(Queue *q, int x)
{
q->buf[q->tail] = x;
q->tail = (q->tail + 1) % q->cap;
q->len++;
}
static int q_pop(Queue *q)
{
int x = q->buf[q->head];
q->head = (q->head + 1) % q->cap;
q->len--;
return x;
}
static void q_free(Queue *q)
{
free(q->buf);
q->buf = NULL;
q->cap = q->head = q->tail = q->len = 0;
}
int main(void)
{
// 设置控制台编码为UTF-8,防止中文乱码
#ifdef _WIN32
system("chcp 65001 > nul"); // 设置控制台编码为UTF-8
SetConsoleOutputCP(65001); // 设置控制台输出编码
SetConsoleCP(65001); // 设置控制台输入编码
#endif
int n, m;
if (scanf("%d %d", &n, &m) != 2)
return 0;
if (n <= 0 || m <= 0)
return 0;
Queue q;
q_init(&q, n);
for (int i = 1; i <= n; ++i)
q_push(&q, i);
while (!q_empty(&q))
{
// 旋转 m-1 次:把队头移动到队尾(取模优化减少旋转次数)
int k = (m - 1) % q.len;
for (int t = 0; t < k; ++t)
{
q_push(&q, q_pop(&q));
}
int out = q_pop(&q);
printf("%d\n", out);
}
q_free(&q);
return 0;
}
+108
View File
@@ -0,0 +1,108 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef _WIN32
#include <windows.h>
#include <direct.h>
#endif
// 简单环形队列
typedef struct
{
int *buf; // 队列缓冲区
int cap; // 队列容量
int head; // 队头指针
int tail; // 队尾指针
int len; // 当前队列长度
} Queue;
// 初始化队列
static void Queue_init(Queue *q, int cap)
{
q->buf = (int *)malloc(sizeof(int) * cap);
q->cap = cap;
q->head = 0;
q->tail = 0;
q->len = 0;
}
// 检查队列是否为空
static int Queue_empty(const Queue *q)
{
return q->len == 0;
}
// 入队操作
static void Queue_push(Queue *q, int x)
{
q->buf[q->tail] = x;
q->tail = (q->tail + 1) % q->cap;
q->len++;
}
// 弹出队列元素
static int Queue_pop(Queue *q)
{
int x = q->buf[q->head];
q->head = (q->head + 1) % q->cap;
q->len--;
return x;
}
// 释放队列内存(避免与标准库 free 冲突)
static void Queue_free(Queue *q)
{
free(q->buf);
q->buf = NULL;
q->cap = 0;
q->head = 0;
q->tail = 0;
q->len = 0;
}
int main(void)
{
// 设置控制台编码为UTF-8,防止中文乱码
#ifdef _WIN32
system("chcp 65001 > nul"); // 设置控制台编码为UTF-8
SetConsoleOutputCP(65001); // 设置控制台输出编码
SetConsoleCP(65001); // 设置控制台输入编码
#endif
int n, m;
printf("请输入约瑟夫环的人数n和报数m: ");
scanf("%d %d", &n, &m);
if (n < 8 || n > 15 || m < 5 || m > 32767)
{
printf("输入错误,请重新输入!\n");
printf("请重输入约瑟夫环的人数n和报数m: ");
scanf("%d %d", &n, &m);
}
// 初始化队列
Queue q;
Queue_init(&q, n);
// 入队操作
for (int i = 0; i < n; i++)
{
Queue_push(&q, i + 1);
}
// 出队操作:模拟报数过程
while (!Queue_empty(&q))
{
// 旋转 m-1 次:把队头移动到队尾(取模优化减少旋转次数)
int k = (m - 1) % q.len;
for (int t = 0; t < k; ++t)
{
Queue_push(&q, Queue_pop(&q));
}
int out = Queue_pop(&q);
printf("%d ", out);
}
// 释放队列内存
Queue_free(&q);
return 0;
}
+116
View File
@@ -0,0 +1,116 @@
#include <stdio.h>
#include <stdlib.h>
// 目标:在允许使用容量为 c 的栈缓冲的前提下,
// 将输入序列(商店从上到下)重排为字典序最小的最终堆叠(从下到上)。
// 操作等价于:依次读取输入;每次要么将下一个元素压入栈(若未满),要么从栈顶弹出到输出;
// 栈容量不超过 c;输出顺序即为最终堆叠的自下而上的编号。
int main(void)
{
int n, c;
if (scanf("%d %d", &n, &c) != 2)
return 0;
int *a = (int *)malloc(sizeof(int) * n);
for (int i = 0; i < n; ++i)
scanf("%d", &a[i]);
// 栈缓冲(手上带着的箱子),存储值
int *stk = (int *)malloc(sizeof(int) * n);
int len = 0; // 当前栈大小
// 单调队列(维护接下来可压入窗口中的最小值及其位置)
int *dq_val = (int *)malloc(sizeof(int) * n);
int *dq_idx = (int *)malloc(sizeof(int) * n);
int dq_head = 0, dq_tail = 0; // [head, tail) 有效
int i = 0; // 下一个待读取的输入位置
int j = 0; // 已加入单调队列的输入位置(下一个待加入的位置)
int out_cnt = 0;
while (out_cnt < n)
{
// 计算当前还能压入的最大数量 R(窗口大小)
int R = c - len;
if (R < 0)
R = 0;
// 扩充单调队列,使其覆盖 [i, min(i+R-1, n-1)]
while (j < n && j < i + R)
{
int v = a[j];
while (dq_tail > dq_head && dq_val[dq_tail - 1] > v)
--dq_tail;
dq_val[dq_tail] = v;
dq_idx[dq_tail] = j;
++dq_tail;
++j;
}
// 若栈非空,比较栈顶与窗口内最小值,决定弹出还是继续压入到最小值位置
if (len > 0)
{
int top = stk[len - 1];
int hasUpcoming = (dq_tail > dq_head);
int minUpcoming = hasUpcoming ? dq_val[dq_head] : 2147483647; // INF
if (!hasUpcoming || top <= minUpcoming)
{
// 栈顶不大于可达窗口中的最小值(或无可压入项),弹出栈顶到输出
printf("%d", top);
++out_cnt;
if (out_cnt < n)
putchar(' ');
--len;
continue;
}
}
// 否则(栈为空或栈顶较大且尚有可压入项),把队列窗口的最小值所在位置的元素压入到栈顶,然后立即弹出
if (dq_tail > dq_head)
{
int target_pos = dq_idx[dq_head];
// 逐个压入直到到达 target_pos
while (i <= target_pos)
{
stk[len++] = a[i++];
}
// 清理队列中过期项(索引 < i 的)
while (dq_tail > dq_head && dq_idx[dq_head] < i)
++dq_head;
// 弹出刚压入的最小值
int val = stk[len - 1];
printf("%d", val);
++out_cnt;
if (out_cnt < n)
putchar(' ');
--len;
}
else
{
// 没有可压入项,但仍需输出 -> 只能弹出栈顶
if (len > 0)
{
int val = stk[len - 1];
printf("%d", val);
++out_cnt;
if (out_cnt < n)
putchar(' ');
--len;
}
else
{
// 理论上不会到这里(既无可压入项又无栈元素),为安全直接中断
break;
}
}
}
putchar('\n');
free(a);
free(stk);
free(dq_val);
free(dq_idx);
return 0;
}
+84
View File
@@ -0,0 +1,84 @@
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int *data;
int *mins;
int top; // index of next insertion in data
int mtop; // index of next insertion in mins
int cap; // capacity
} MinStack;
static void ms_init(MinStack *s, int cap) {
s->data = (int *)malloc(sizeof(int) * cap);
s->mins = (int *)malloc(sizeof(int) * cap);
s->top = 0;
s->mtop = 0;
s->cap = cap;
}
static int ms_empty(const MinStack *s) { return s->top == 0; }
static void ms_push(MinStack *s, int x) {
// Assume total pushes won't exceed cap per problem constraints
s->data[s->top++] = x;
if (s->mtop == 0 || x <= s->mins[s->mtop - 1]) {
s->mins[s->mtop++] = x;
}
}
static void ms_pop(MinStack *s) {
if (s->top == 0) return; // ignore if empty
int v = s->data[s->top - 1];
s->top--;
if (s->mtop > 0 && v == s->mins[s->mtop - 1]) {
s->mtop--;
}
}
static int ms_top(const MinStack *s) {
return s->data[s->top - 1];
}
static int ms_get_min(const MinStack *s) {
return s->mins[s->mtop - 1];
}
static void ms_free(MinStack *s) {
free(s->data);
free(s->mins);
s->data = s->mins = NULL;
s->top = s->mtop = s->cap = 0;
}
int main(void) {
int n;
if (scanf("%d", &n) != 1) return 0;
MinStack st;
ms_init(&st, n > 0 ? n : 1);
for (int i = 0; i < n; ++i) {
int t;
if (scanf("%d", &t) != 1) t = 0;
if (t == 1) {
int x;
scanf("%d", &x);
ms_push(&st, x);
} else if (t == 2) {
ms_pop(&st);
} else if (t == 3) {
if (!ms_empty(&st)) {
printf("%d\n", ms_top(&st));
}
} else if (t == 4) {
if (!ms_empty(&st)) {
printf("%d\n", ms_get_min(&st));
}
} else {
// ignore unknown command
}
}
ms_free(&st);
return 0;
}
+66
View File
@@ -0,0 +1,66 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 计算最长合法括号子串长度及数量(数量指达到该最长长度的子串个数)
// 使用经典 DP:dp[i] 表示以 i 结尾的最长合法括号长度。
// 当 maxLen 为 0 时,按题意输出 "0 1"。
int main(void)
{
const int MAXN = 1000005; // 题面最大长度约 1e6
char *s = (char *)malloc(MAXN);
if (!s) return 0;
if (scanf("%1000000s", s) != 1) {
free(s);
return 0;
}
int n = (int)strlen(s);
if (n == 0) {
printf("0 1\n");
free(s);
return 0;
}
int *dp = (int *)calloc(n, sizeof(int));
if (!dp) {
free(s);
return 0;
}
int maxLen = 0;
int count = 1; // 若最终 maxLen 为 0,答案应为 0 1
for (int i = 1; i < n; ++i) {
if (s[i] == ')') {
if (s[i - 1] == '(') {
dp[i] = 2 + (i >= 2 ? dp[i - 2] : 0);
} else {
int prev = i - dp[i - 1] - 1;
if (prev >= 0 && s[prev] == '(') {
dp[i] = dp[i - 1] + 2 + (prev >= 1 ? dp[prev - 1] : 0);
}
}
if (dp[i] > 0) {
if (dp[i] > maxLen) {
maxLen = dp[i];
count = 1;
} else if (dp[i] == maxLen) {
count++;
}
}
}
}
if (maxLen == 0) {
printf("0 1\n");
} else {
printf("%d %d\n", maxLen, count);
}
free(dp);
free(s);
return 0;
}
+53
View File
@@ -0,0 +1,53 @@
#include <stdio.h>
int main()
{
int T;
scanf("%d", &T);
while (T--)
{
int N;
scanf("%d", &N);
int a[10000];
// 读取序列
for (int i = 0; i < N; i++)
{
scanf("%d", &a[i]);
}
// 找最大值和最小值的位置
int max_pos = 0, min_pos = 0;
for (int i = 0; i < N; i++)
{
if (a[i] > a[max_pos])
{
max_pos = i;
}
if (a[i] < a[min_pos])
{
min_pos = i;
}
}
// 交换最大值和最小值
int temp = a[max_pos];
a[max_pos] = a[min_pos];
a[min_pos] = temp;
// 输出结果
for (int i = 0; i < N; i++)
{
printf("%d", a[i]);
if (i < N - 1)
{
printf(" ");
}
}
printf("\n");
}
return 0;
}
+65
View File
@@ -0,0 +1,65 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 语法:
// E := T ('|' T)* // 选择,取较长长度
// T := F+ // 连接,长度相加
// F := 'a' | '(' E ')' // 原子:一个 a 或括号组
// 输出化简后(全为 a)的长度
static const char *s;
static int n, pos;
static int parse_E(void);
static int parse_T(void);
static int parse_F(void);
static int parse_E(void)
{
int best = parse_T();
while (pos < n && s[pos] == '|') {
++pos; // consume '|'
int t = parse_T();
if (t > best) best = t;
}
return best;
}
static int parse_T(void)
{
int sum = 0;
while (pos < n && s[pos] != ')' && s[pos] != '|') {
sum += parse_F();
}
return sum;
}
static int parse_F(void)
{
if (pos < n && s[pos] == 'a') {
++pos;
return 1;
}
if (pos < n && s[pos] == '(') {
++pos; // consume '('
int v = parse_E();
if (pos < n && s[pos] == ')') ++pos; // consume ')'
return v;
}
// 理论上不会到达(保证输入合法且不含空串),安全返回 0
return 0;
}
int main(void)
{
// 读取一行字符串(仅包含 a | ( )),长度不超过 1e5
static char buf[1000005];
if (scanf("%1000000s", buf) != 1) return 0;
s = buf;
n = (int)strlen(s);
pos = 0;
int ans = parse_E();
printf("%d\n", ans);
return 0;
}
+119
View File
@@ -0,0 +1,119 @@
// 可随机访问的“栈”,支持按下标 O(1) 访问与快 I/O
// 操作:
// 1 x:压入整数 x
// 2:输出栈顶元素
// 3 i:输出第 i 个元素(从 0 开始)
// 4:弹出栈顶元素
// 约束:操作数最多 5,000,000;执行 3 时保证 i 有效
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 快读整数
static inline int read_int(void) {
int c = getchar();
while (c != EOF && (c == ' ' || c == '\n' || c == '\t' || c == '\r')) c = getchar();
int sign = 1;
if (c == '-') { sign = -1; c = getchar(); }
int x = 0;
while (c >= '0' && c <= '9') { x = x * 10 + (c - '0'); c = getchar(); }
return sign * x;
}
// 快速输出整数并换行
static inline void write_int_ln(int x) {
char buf[32];
char *p = buf + sizeof(buf);
*(--p) = '\n';
unsigned int ux;
if (x < 0) {
ux = (unsigned int)(-(long long)x);
} else {
ux = (unsigned int)x;
}
do {
*(--p) = (char)('0' + (ux % 10));
ux /= 10;
} while (ux);
if (x < 0) *(--p) = '-';
fwrite(p, 1, (size_t)(buf + sizeof(buf) - p), stdout);
}
typedef struct {
int *a;
size_t len;
size_t cap;
} RAStack;
static inline void ras_init(RAStack *s) {
s->len = 0;
s->cap = 1024; // 初始容量
s->a = (int*)malloc(s->cap * sizeof(int));
if (!s->a) {
// 若内存紧张,回退到较小容量以继续运行
s->cap = 16;
s->a = (int*)malloc(s->cap * sizeof(int));
if (!s->a) exit(1);
}
}
static inline void ras_reserve(RAStack *s, size_t need) {
if (need <= s->cap) return;
size_t new_cap = s->cap;
while (new_cap < need) {
// 约 1.5 倍扩容,以便在超大输入时节省内存
new_cap = new_cap + (new_cap >> 1);
if (new_cap < s->cap + 1) new_cap = s->cap + 1; // 避免停滞
}
int *na = (int*)realloc(s->a, new_cap * sizeof(int));
if (!na) {
// 若 1.5 倍失败则尝试翻倍
new_cap = s->cap * 2;
na = (int*)realloc(s->a, new_cap * sizeof(int));
if (!na) exit(1);
}
s->a = na;
s->cap = new_cap;
}
static inline void ras_push(RAStack *s, int x) {
if (s->len == s->cap) ras_reserve(s, s->len + 1);
s->a[s->len++] = x;
}
static inline int ras_top(const RAStack *s) {
return s->a[s->len - 1];
}
static inline int ras_get(const RAStack *s, size_t i) {
return s->a[i]; // 从底部 0 开始计数
}
static inline void ras_pop(RAStack *s) {
--s->len;
}
int main(void) {
RAStack st;
ras_init(&st);
int n = read_int();
for (int k = 0; k < n; ++k) {
int op = read_int();
if (op == 1) {
int x = read_int();
ras_push(&st, x);
} else if (op == 2) {
write_int_ln(ras_top(&st));
} else if (op == 3) {
int i = read_int();
write_int_ln(ras_get(&st, (size_t)i));
} else if (op == 4) {
ras_pop(&st);
}
}
free(st.a);
return 0;
}
+87
View File
@@ -0,0 +1,87 @@
// 计算含运算符 '&'(取两数较小值)与 '|'(取两数较大值)的表达式
// 两者同优先级,按从左到右结合;遇到括号优先计算括号内表达式。
// 输入:一行字符串,仅由数字、&、|、(、) 组成
// 输出:一个整数,表示表达式的值
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
static inline int min_i(int a, int b) { return a < b ? a : b; }
static inline int max_i(int a, int b) { return a > b ? a : b; }
static inline void apply_top(int *vals, int *vtop, char *ops, int *otop) {
char op = ops[--(*otop)];
int b = vals[--(*vtop)];
int a = vals[--(*vtop)];
int r = (op == '&') ? min_i(a, b) : max_i(a, b);
vals[(*vtop)++] = r;
}
int main(void) {
// 读取整行输入
char *line = NULL;
size_t cap = 0;
{
// getline 若不可用则用 fgets 简易读取
// Windows 平台无 getline,这里使用 fgets
size_t bufcap = 16384; // 大于题目约束的 10000
line = (char*)malloc(bufcap);
if (!line) return 1;
if (!fgets(line, (int)bufcap, stdin)) return 0;
size_t len = strlen(line);
// 去掉行尾 CR/LF
while (len && (line[len-1] == '\n' || line[len-1] == '\r')) line[--len] = '\0';
cap = len + 1;
}
size_t L = strlen(line);
int *vals = (int*)malloc((L + 1) * sizeof(int));
char *ops = (char*)malloc(L + 1);
if (!vals || !ops) return 1;
int vtop = 0, otop = 0;
for (size_t i = 0; i < L;) {
char c = line[i];
if (isspace((unsigned char)c)) { ++i; continue; } // 忽略空白
if (c >= '0' && c <= '9') {
int x = 0;
while (i < L && line[i] >= '0' && line[i] <= '9') {
x = x * 10 + (line[i] - '0');
++i;
}
vals[vtop++] = x;
} else if (c == '&' || c == '|') {
// 同优先级:在遇到 '(' 之前,应用所有已入栈的运算符
while (otop > 0 && ops[otop - 1] != '(') {
apply_top(vals, &vtop, ops, &otop);
}
ops[otop++] = c;
++i;
} else if (c == '(') {
ops[otop++] = c;
++i;
} else if (c == ')') {
while (otop > 0 && ops[otop - 1] != '(') {
apply_top(vals, &vtop, ops, &otop);
}
if (otop > 0 && ops[otop - 1] == '(') --otop; // 弹出左括号
++i;
} else {
// 非法字符:跳过以增强鲁棒性
++i;
}
}
while (otop > 0) {
apply_top(vals, &vtop, ops, &otop);
}
if (vtop > 0) printf("%d\n", vals[vtop - 1]);
free(vals);
free(ops);
free(line);
return 0;
}
+170
View File
@@ -0,0 +1,170 @@
// 算术表达式求值:支持 + - * / ^ 和小括号
// 规则:
// - 运算符优先级:括号 > 一元± > ^(右结合)> * /(左结合)> + -(左结合)
// - 输入为一行表达式,可能包含多余括号与空格
// - 输出为结果,按四舍五入取整
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
// 手写整数乘方(支持负指数):右结合的 ^ 使用该实现
static inline long double powi_ld(long double base, long long exp) {
if (exp == 0) return 1.0L;
int neg = 0;
if (exp < 0) { neg = 1; exp = -exp; }
long double res = 1.0L, a = base;
while (exp) {
if (exp & 1LL) res *= a;
a *= a;
exp >>= 1LL;
}
if (neg) {
// 避免 1/0 产生异常(表达式一般不会出现该情况)
if (res == 0.0L) return 0.0L; // 约定返回 0,防止 RE
return 1.0L / res;
}
return res;
}
// 手写四舍五入为 long long,避免依赖 llround
static inline long long roundll(long double x) {
return (x >= 0.0L) ? (long long)(x + 0.5L) : (long long)(x - 0.5L);
}
// 操作符优先级
static inline int prec(char op) {
switch (op) {
case '~': return 4; // 一元负号
case '^': return 3; // 乘方,右结合
case '*': case '/': return 2; // 乘除
case '+': case '-': return 1; // 加减
default: return 0;
}
}
// 应用一个操作符到栈顶操作数
static inline void apply_top(long double *vals, int *vtop, char *ops, int *otop) {
char op = ops[--(*otop)];
if (op == '~') {
long double a = vals[--(*vtop)];
vals[(*vtop)++] = -a;
return;
}
long double b = vals[--(*vtop)];
long double a = vals[--(*vtop)];
long double r;
switch (op) {
case '+': r = a + b; break;
case '-': r = a - b; break;
case '*': r = a * b; break;
case '/':
// 防御除零导致的 RE:约定返回 0(题目数据通常不会出现此情况)
if (b == 0.0L) r = 0.0L; else r = a / b;
break;
case '^': {
long long be = roundll(b); // 指数按近似整数处理
r = powi_ld(a, be);
break;
}
default: r = 0.0; break;
}
vals[(*vtop)++] = r;
}
int main(void) {
// 读取整行表达式
char *line = NULL;
size_t cap = 0;
{
size_t bufcap = 1024; // 表达式长度 ≤ 30,这里足够
line = (char*)malloc(bufcap);
if (!line) return 1;
if (!fgets(line, (int)bufcap, stdin)) return 0;
size_t len = strlen(line);
while (len && (line[len-1] == '\n' || line[len-1] == '\r')) line[--len] = '\0';
cap = len + 1;
}
size_t L = strlen(line);
// 栈容量按输入长度分配
long double *vals = (long double*)malloc((L + 1) * sizeof(long double));
char *ops = (char*)malloc(L + 1);
if (!vals || !ops) return 1;
int vtop = 0, otop = 0;
int expect_unary = 1; // 是否期待一元运算符(开头或在'('或二元运算符之后)
for (size_t i = 0; i < L;) {
char c = line[i];
if (isspace((unsigned char)c)) { ++i; continue; }
if (c >= '0' && c <= '9') {
// 解析数字(整数)
long long x = 0;
while (i < L && line[i] >= '0' && line[i] <= '9') {
x = x * 10 + (line[i] - '0');
++i;
}
vals[vtop++] = (long double)x;
expect_unary = 0;
} else if (c == '(') {
ops[otop++] = c;
++i;
expect_unary = 1;
} else if (c == ')') {
while (otop > 0 && ops[otop - 1] != '(') {
apply_top(vals, &vtop, ops, &otop);
}
if (otop > 0 && ops[otop - 1] == '(') --otop; // 弹出左括号
++i;
expect_unary = 0;
} else if (c == '+' || c == '-' || c == '*' || c == '/' || c == '^') {
// 处理一元 ±
if (expect_unary && (c == '+' || c == '-')) {
if (c == '-') {
// 一元负号入栈(最高优先级)
ops[otop++] = '~';
}
// 一元 '+' 不产生效果,直接跳过
++i;
expect_unary = 1; // 仍可能继续接 '(' 或 数字
continue;
}
// 处理二元运算符的结合与优先级
int p = prec(c);
int right_assoc = (c == '^');
while (otop > 0 && ops[otop - 1] != '(') {
int pt = prec(ops[otop - 1]);
if ((right_assoc && pt > p) || (!right_assoc && pt >= p)) {
apply_top(vals, &vtop, ops, &otop);
} else break;
}
ops[otop++] = c;
++i;
expect_unary = 1;
} else {
// 其他字符(若存在):跳过
++i;
}
}
// 清空剩余操作符
while (otop > 0) {
apply_top(vals, &vtop, ops, &otop);
}
// 四舍五入输出整数
if (vtop > 0) {
long double res = vals[vtop - 1];
long long rounded = roundll(res);
printf("%lld\n", rounded);
}
free(vals);
free(ops);
free(line);
return 0;
}
+133
View File
@@ -0,0 +1,133 @@
// 逆波兰式逐步规约打印
// 输入:仅含 0-9、+ - * / 和小括号 () 的中缀表达式,数字均为一位
// 要求:
// - 先将中缀转为后缀(RPN
// - 按从左到右每次规约一个“两个数字 + 一个运算符”的三元组,得到新的后缀表达式
// - 逐行输出:首行是完整后缀表达式;之后每行比上一行少 1 个运算符和 1 个数字;最后一行只有一个数字(最终结果)
// - 令 / 为整除(向零截断),允许中间结果为负数
// - 输出格式:各符号之间以单个空格分隔;只有首行和最后一行行末保留一个空格,其他行末无空格
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
typedef struct {
int is_num; // 1 表示数字,0 表示运算符
int val; // 数字值
char op; // 运算符字符
} Token;
// 运算符优先级:* / 高于 + -,全部左结合
static inline int prec(char c) {
if (c == '*' || c == '/') return 2;
if (c == '+' || c == '-') return 1;
return 0;
}
// 打印一行后缀表达式:tokens[0..n-1]
// 参数 trailing_space 控制是否在行末额外打印一个空格
static void print_tokens(const Token *t, int n, int trailing_space) {
for (int i = 0; i < n; ++i) {
if (t[i].is_num) {
printf("%d", t[i].val);
} else {
printf("%c", t[i].op);
}
if (i + 1 < n) putchar(' ');
}
if (trailing_space) putchar(' ');
putchar('\n');
}
// 计算 a (op) b,/ 为整除(向零),其余为常规整数算术
static inline int apply_int(int a, int b, char op) {
switch (op) {
case '+': return a + b;
case '-': return a - b;
case '*': return a * b;
case '/': return (b == 0 ? 0 : a / b); // 题面保证不会越界;防御除零
default: return 0;
}
}
int main(void) {
// 读取整行
char line[256];
if (!fgets(line, sizeof(line), stdin)) return 0;
size_t len = strlen(line);
while (len && (line[len-1] == '\n' || line[len-1] == '\r')) line[--len] = '\0';
// 中缀转后缀(shunting-yard
Token out[256];
int on = 0;
char ops[256];
int ot = 0;
for (size_t i = 0; i < len; ++i) {
char c = line[i];
if (isspace((unsigned char)c)) continue;
if (c >= '0' && c <= '9') {
out[on].is_num = 1;
out[on].val = c - '0';
out[on].op = 0;
++on;
} else if (c == '+' || c == '-' || c == '*' || c == '/') {
int p = prec(c);
while (ot > 0 && ops[ot - 1] != '(' && prec(ops[ot - 1]) >= p) {
out[on].is_num = 0;
out[on].op = ops[--ot];
++on;
}
ops[ot++] = c;
} else if (c == '(') {
ops[ot++] = c;
} else if (c == ')') {
while (ot > 0 && ops[ot - 1] != '(') {
out[on].is_num = 0;
out[on].op = ops[--ot];
++on;
}
if (ot > 0 && ops[ot - 1] == '(') --ot; // 弹出左括号
} else {
// 题面保证无需判错
}
}
while (ot > 0) {
out[on].is_num = 0;
out[on].op = ops[--ot];
++on;
}
// 打印首行(保留行末空格)
print_tokens(out, on, 1);
// 逐步规约:每次找到第一个运算符(其前必有两个数字),规约为一个数字
Token cur[256];
memcpy(cur, out, on * sizeof(Token));
int n = on;
while (n > 1) {
int idx = -1;
for (int i = 0; i < n; ++i) {
if (!cur[i].is_num) { idx = i; break; }
}
// 规约 cur[idx-2], cur[idx-1], cur[idx]
int a = cur[idx - 2].val;
int b = cur[idx - 1].val;
int r = apply_int(a, b, cur[idx].op);
// 将结果写回到 idx-2,并左移覆盖 idx-1 与 idx
cur[idx - 2].is_num = 1;
cur[idx - 2].val = r;
// 左移 n-(idx+1) 个元素
for (int j = idx - 1; j + 2 < n; ++j) {
cur[j] = cur[j + 2];
}
n -= 2;
// 是否最后一行:n==1 时保留行末空格,否则不保留
print_tokens(cur, n, (n == 1));
}
return 0;
}
+111
View File
@@ -0,0 +1,111 @@
// 简单逻辑表达式求值:支持 true/false 与 not/and/or,带错误检测
// 规则:
// - 仅包含单词 true, false, not, and, or 与空格;全部小写
// - 优先级:not > and > or;同级从左到右(左结合)
// - 输入为一行,输出为 true / false;如果语法或词法错误,输出 error
#include <stdio.h>
#include <string.h>
#include <ctype.h>
typedef enum { TK_TRUE, TK_FALSE, TK_AND, TK_OR, TK_NOT } Tok;
// 读取一行到缓冲区,并去除尾部换行符
static int read_line(char *buf, size_t sz) {
if (!fgets(buf, (int)sz, stdin)) return 0;
size_t n = strlen(buf);
while (n && (buf[n-1] == '\n' || buf[n-1] == '\r')) buf[--n] = '\0';
return 1;
}
// 词法:按字母分组,提取单词,映射到令牌;出错返回 -1
static int tokenize(const char *s, Tok *out, int maxn) {
int nt = 0;
size_t i = 0, n = strlen(s);
while (i < n) {
while (i < n && isspace((unsigned char)s[i])) ++i;
if (i >= n) break;
if (!isalpha((unsigned char)s[i])) return -1; // 非法字符
size_t j = i;
while (j < n && isalpha((unsigned char)s[j])) ++j;
size_t wlen = j - i;
if (wlen == 4 && strncmp(s + i, "true", 4) == 0) {
if (nt >= maxn) return -1;
out[nt++] = TK_TRUE;
} else if (wlen == 5 && strncmp(s + i, "false", 5) == 0) {
if (nt >= maxn) return -1;
out[nt++] = TK_FALSE;
} else if (wlen == 3 && strncmp(s + i, "and", 3) == 0) {
if (nt >= maxn) return -1;
out[nt++] = TK_AND;
} else if (wlen == 2 && strncmp(s + i, "or", 2) == 0) {
if (nt >= maxn) return -1;
out[nt++] = TK_OR;
} else if (wlen == 3 && strncmp(s + i, "not", 3) == 0) {
if (nt >= maxn) return -1;
out[nt++] = TK_NOT;
} else {
return -1; // 未知单词
}
i = j;
}
return nt;
}
// 递归下降(迭代实现)语法:
// unary := { not }* ( true | false )
// and := unary { and unary }*
// or := and { or and }*
static int parse_unary(const Tok *toks, int nt, int *idx, int *ok) {
int neg = 0;
while (*idx < nt && toks[*idx] == TK_NOT) { ++neg; ++*idx; }
if (*idx >= nt) { *ok = 0; return 0; }
int val;
if (toks[*idx] == TK_TRUE) { val = 1; }
else if (toks[*idx] == TK_FALSE) { val = 0; }
else { *ok = 0; return 0; }
++*idx;
if (neg & 1) val = !val;
return val;
}
static int parse_and(const Tok *toks, int nt, int *idx, int *ok) {
int lhs = parse_unary(toks, nt, idx, ok);
if (!*ok) return 0;
while (*idx < nt && toks[*idx] == TK_AND) {
++*idx;
int rhs = parse_unary(toks, nt, idx, ok);
if (!*ok) return 0;
lhs = (lhs && rhs);
}
return lhs;
}
static int parse_or(const Tok *toks, int nt, int *idx, int *ok) {
int lhs = parse_and(toks, nt, idx, ok);
if (!*ok) return 0;
while (*idx < nt && toks[*idx] == TK_OR) {
++*idx;
int rhs = parse_and(toks, nt, idx, ok);
if (!*ok) return 0;
lhs = (lhs || rhs);
}
return lhs;
}
int main(void) {
char line[512];
if (!read_line(line, sizeof(line))) return 0;
Tok toks[300];
int nt = tokenize(line, toks, 300);
if (nt <= 0) { printf("error\n"); return 0; }
int idx = 0, ok = 1;
int result = parse_or(toks, nt, &idx, &ok);
if (!ok || idx != nt) { printf("error\n"); return 0; }
printf(result ? "true\n" : "false\n");
return 0;
}
+87
View File
@@ -0,0 +1,87 @@
// 地道连通查询(线性房屋 1..n):支持操作
// D x: 摧毁房屋 x;R: 修复上一次摧毁的房屋;Q x: 询问士兵在 x 能到达的房屋数
// 思路:维护“被摧毁房屋”的有序集合,查询时找离 x 最近的左右两个摧毁位置。
// 为了在 C 中高效实现前驱/后继,使用树状数组(Fenwick)存放摧毁标记(1 表示摧毁),
// 并用“按前缀和查找第 k 个 1”的技巧 O(log n) 求出前驱/后继位置。
#include <stdio.h>
#include <stdlib.h>
static int N; // 房屋总数
static int *bit; // 树状数组,1..N
static int *dead; // 摧毁标记
static int *stackD; // 摧毁栈,支持 R
static int topD = 0;
static inline int lowbit(int x) { return x & -x; }
static void bit_add(int i, int delta) {
for (; i <= N; i += lowbit(i)) bit[i] += delta;
}
static int bit_sum(int i) {
int s = 0;
for (; i > 0; i -= lowbit(i)) s += bit[i];
return s;
}
// 返回使得前缀和等于 k 的最小下标(1..N)。要求 k>=1 且 k<=sum(N)
static int bit_find_kth(int k) {
int idx = 0;
// 最大 2 的幂覆盖到 N
int p = 1;
while ((p << 1) <= N) p <<= 1;
for (; p; p >>= 1) {
int next = idx + p;
if (next <= N && bit[next] < k) {
idx = next;
k -= bit[next];
}
}
return idx + 1; // 1..N
}
int main(void) {
int n, m;
if (scanf("%d %d", &n, &m) != 2) return 0;
N = n;
bit = (int *)calloc((size_t)N + 1u, sizeof(int));
dead = (int *)calloc((size_t)N + 2u, sizeof(int));
stackD = (int *)malloc(((size_t)m + 5u) * sizeof(int));
if (!bit || !dead || !stackD) return 0;
for (int i = 0; i < m; ++i) {
char cmd[8];
if (scanf("%7s", cmd) != 1) break;
if (cmd[0] == 'D') {
int x; scanf("%d", &x);
if (x >= 1 && x <= n && !dead[x]) {
dead[x] = 1;
bit_add(x, +1);
stackD[topD++] = x;
}
} else if (cmd[0] == 'R') {
if (topD > 0) {
int x = stackD[--topD];
if (dead[x]) { dead[x] = 0; bit_add(x, -1); }
}
} else if (cmd[0] == 'Q') {
int x; scanf("%d", &x);
if (x < 1 || x > n) { printf("0\n"); continue; }
if (dead[x]) {
printf("0\n");
} else {
int left_cnt = bit_sum(x - 1);
int total_cnt = bit_sum(n);
int upto_x_cnt = bit_sum(x);
int left_break = (left_cnt == 0) ? 0 : bit_find_kth(left_cnt);
int right_break = (upto_x_cnt == total_cnt) ? (n + 1) : bit_find_kth(upto_x_cnt + 1);
int reachable = right_break - left_break - 1;
printf("%d\n", reachable);
}
}
}
free(bit); free(dead); free(stackD);
return 0;
}
+152
View File
@@ -0,0 +1,152 @@
// 随机连续子序列的最小值期望满意度:
// 选取所有子数组(连续子序列)均匀随机;score 为该子数组的最小值;满意度为 max(0, score - expect)
// 目标:对每个 expect 求 E[max(0, min - expect)],用最简分数输出。
// 做法:
// - 用单调栈统计每个位置作为“子数组最小值的代表”的子数组个数 c_i,采用去重规则:
// prev 为前一个 < 当前值的位置,next 为后一个 <= 当前值的位置;贡献个数为 (i-prev)*(next-i)
// - 将相同值的贡献累加,得到“最小值为 v 的子数组个数” count[v]
// - 总子数组数 T = n*(n+1)/2;对 expect=e,有
// E = (1/T) * sum_{v>e} (v-e) * count[v]
// = (1/T) * ( sum_{v>e} v*count[v] - e * sum_{v>e} count[v] )
// - 预先按 v 排序并做前缀和,查询时二分找 v>e 的起点,O(log n) 得到分子;化简为最简分数输出。
#include <stdio.h>
#include <stdlib.h>
typedef long long ll;
typedef unsigned long long ull;
typedef __int128 i128;
typedef unsigned __int128 u128;
typedef struct { ll v; ull c; } Pair;
static int cmp_pair(const void *a, const void *b) {
const Pair *x = (const Pair *)a, *y = (const Pair *)b;
if (x->v < y->v) return -1;
if (x->v > y->v) return 1;
return 0;
}
static void print_u128(u128 x) {
if (x == 0) { putchar('0'); return; }
char buf[64];
int p = 0;
while (x) {
unsigned int d = (unsigned int)(x % 10);
buf[p++] = (char)('0' + d);
x /= 10;
}
while (p--) putchar(buf[p]);
}
static ull gcd_ull(ull a, ull b) {
while (b) { ull t = a % b; a = b; b = t; }
return a;
}
int main(void) {
int T;
if (scanf("%d", &T) != 1) return 0;
for (int tc = 1; tc <= T; ++tc) {
int n; if (scanf("%d", &n) != 1) return 0;
ll *a = (ll *)malloc(((size_t)n + 5u) * sizeof(ll));
for (int i = 1; i <= n; ++i) scanf("%lld", &a[i]);
// 单调栈:prev(<) 与 next(<=)
int *prev = (int *)malloc(((size_t)n + 5u) * sizeof(int));
int *next = (int *)malloc(((size_t)n + 5u) * sizeof(int));
int *st = (int *)malloc(((size_t)n + 5u) * sizeof(int));
int top = 0;
for (int i = 1; i <= n; ++i) {
while (top > 0 && a[st[top - 1]] >= a[i]) --top;
prev[i] = (top == 0 ? 0 : st[top - 1]);
st[top++] = i;
}
top = 0;
for (int i = n; i >= 1; --i) {
while (top > 0 && a[st[top - 1]] > a[i]) --top;
next[i] = (top == 0 ? (n + 1) : st[top - 1]);
st[top++] = i;
}
// 生成 (value, count) 对
Pair *pairs = (Pair *)malloc(((size_t)n + 5u) * sizeof(Pair));
for (int i = 1; i <= n; ++i) {
ull L = (ull)(i - prev[i]);
ull R = (ull)(next[i] - i);
pairs[i - 1].v = a[i];
pairs[i - 1].c = L * R;
}
qsort(pairs, (size_t)n, sizeof(Pair), cmp_pair);
// 压缩相同值
int k = 0;
Pair *uniq = (Pair *)malloc(((size_t)n + 5u) * sizeof(Pair));
for (int i = 0; i < n; ) {
ll v = pairs[i].v; u128 csum = 0;
while (i < n && pairs[i].v == v) { csum += (u128)pairs[i].c; ++i; }
uniq[k].v = v; // csum 可能 >2^64,但总子数组数 <= 5e10,仍可放进 64bit
// 但为了稳妥,仍按 64 位存储(安全范围内)
unsigned long long cc = (unsigned long long)csum; // csum <= n*(n+1)/2 <= 5e10
uniq[k].c = cc;
++k;
}
// 前缀和(用于后缀查询)
unsigned long long *prefC = (unsigned long long *)malloc(((size_t)k + 5u) * sizeof(unsigned long long));
u128 *prefVC = (u128 *)malloc(((size_t)k + 5u) * sizeof(u128));
u128 sVC = 0; unsigned long long sC = 0;
for (int i = 0; i < k; ++i) {
sC += uniq[i].c;
sVC += (u128)((i128)uniq[i].v) * (u128)uniq[i].c;
prefC[i] = sC;
prefVC[i] = sVC;
}
// 总子数组数
unsigned long long Total = (unsigned long long)n * (unsigned long long)(n + 1) / 2ull;
int m; scanf("%d", &m);
printf("Case %d:\n", tc);
for (int qi = 0; qi < m; ++qi) {
long long e; scanf("%lld", &e);
// 二分找第一个 v>e 的位置
int lo = 0, hi = k;
while (lo < hi) {
int mid = (lo + hi) >> 1;
if (uniq[mid].v <= e) lo = mid + 1; else hi = mid;
}
if (lo == k) { puts("0"); continue; }
// 后缀和
unsigned long long S2 = prefC[k - 1] - (lo ? prefC[lo - 1] : 0ull);
u128 S1 = prefVC[k - 1] - (lo ? prefVC[lo - 1] : (u128)0);
// 分子:S1 - e*S2
u128 Numer = S1 - (u128)((i128)e) * (u128)S2;
if (Numer == 0) { puts("0"); continue; }
// 若可整除,输出整数
u128 mod = Numer % (u128)Total;
if (mod == 0) {
u128 A = Numer / (u128)Total;
print_u128(A); putchar('\n');
} else {
unsigned long long r = (unsigned long long)mod; // mod < Total
unsigned long long g = gcd_ull(Total, r);
u128 A = Numer / (u128)g;
unsigned long long B = Total / g;
print_u128(A); putchar('/');
// 打印 B64 位)
char buf[32]; int p = 0; unsigned long long Bb = B;
if (Bb == 0) { putchar('0'); }
else {
while (Bb) { buf[p++] = (char)('0' + (Bb % 10)); Bb /= 10; }
while (p--) putchar(buf[p]);
}
putchar('\n');
}
}
free(a); free(prev); free(next); free(st); free(pairs); free(uniq); free(prefC); free(prefVC);
}
return 0;
}
+79
View File
@@ -0,0 +1,79 @@
// 优化版:每个区间长度 k(1..n) 的最大区间价值 max(subarray_max * subarray_min)
// 算法:最大值笛卡尔树 + 跨越合并(单调两指针),整体显著优于 O(n^2)
// 说明:对每个树节点 i 及其覆盖段 [l,r],所有包含 i 的子数组最大值均为 a[i];
// 设从 i 向左取 x 个、向右取 y 个,长度 k=x+y+1,区间最小值为 min(Lmin[x], Rmin[y])
// 其中 Lmin/Rmin 为以 i 为中心的左/右最小值前后缀。对固定 s=x+y,
// 利用两指针在可行范围内最大化 min(Lmin[s-y], Rmin[y])O(lenL+lenR) 完成一次合并。
#include <stdio.h>
#include <stdlib.h>
typedef long long ll;
static inline ll minll(ll a, ll b) { return a < b ? a : b; }
// 构建“以最大值为堆”的笛卡尔树。相等值用 <= 弹出以保证唯一性(倾向右侧作为父)。
// 输出:left child lcright child rcparent;返回根下标。
static int build_cartesian_tree(const ll *a, int n, int *lc, int *rc, int *parent) {
int *st = (int*)malloc((n + 1) * sizeof(int));
int top = 0;
int root = 0;
for (int i = 1; i <= n; ++i) {
int last = 0;
while (top > 0 && a[st[top - 1]] <= a[i]) {
last = st[--top];
}
if (top > 0) {
rc[st[top - 1]] = i;
parent[i] = st[top - 1];
} else {
root = i;
parent[i] = 0;
}
lc[i] = last;
if (last) parent[last] = i;
st[top++] = i;
}
free(st);
return root;
}
int main(void) {
int n;
if (scanf("%d", &n) != 1) return 0;
int cap = n + 5;
int *dq = (int*)malloc((size_t)cap * sizeof(int));
int head = 0, tail = 0, size = 0;
char *out = (char*)malloc((size_t)(n * 14 + 1));
int pos = 0;
for (int i = 0; i < n; ++i) {
int op;
scanf("%d", &op);
if (op == 1) {
int x; scanf("%d", &x);
head = (head - 1 + cap) % cap;
dq[head] = x;
++size;
} else if (op == 2) {
int x; scanf("%d", &x);
dq[tail] = x;
tail = (tail + 1) % cap;
++size;
} else if (op == 3) {
pos += sprintf(out + pos, "%d\n", dq[head]);
} else if (op == 4) {
int idx = (tail - 1 + cap) % cap;
pos += sprintf(out + pos, "%d\n", dq[idx]);
} else if (op == 5) {
head = (head + 1) % cap;
--size;
} else if (op == 6) {
tail = (tail - 1 + cap) % cap;
--size;
}
}
fwrite(out, 1, (size_t)pos, stdout);
free(out);
free(dq);
return 0;
}
+30
View File
@@ -0,0 +1,30 @@
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int n, m;
if (scanf("%d %d", &n, &m) != 2) return 0;
int *a = (int*)malloc((size_t)(n + 1) * sizeof(int));
for (int i = 1; i <= n; ++i) scanf("%d", &a[i]);
int *cnt = (int*)calloc((size_t)(m + 1), sizeof(int));
int covered = 0;
int l = 1;
int best_l = 1, best_r = n;
int best_len = n;
for (int r = 1; r <= n; ++r) {
int c = a[r];
if (cnt[c] == 0) ++covered;
++cnt[c];
if (covered == m) {
while (cnt[a[l]] > 1) { --cnt[a[l]]; ++l; }
int len = r - l + 1;
if (len < best_len || (len == best_len && l < best_l)) {
best_len = len; best_l = l; best_r = r;
}
}
}
printf("%d %d\n", best_l, best_r);
free(cnt);
free(a);
return 0;
}
+34
View File
@@ -0,0 +1,34 @@
#include <stdio.h>
// 递归实现
long long f_recursive(int n)
{
if (n == 1)
{
return 1;
}
return n + f_recursive(n - 1);
}
// 数学公式实现(更高效)
long long f_formula(long long n)
{
return n * (n + 1) / 2;
}
int main()
{
int T;
scanf("%d", &T);
while (T--)
{
long long n;
scanf("%lld", &n);
// 由于n可能很大(<10^9),使用数学公式更安全
printf("%lld\n", f_formula(n));
}
return 0;
}
+156
View File
@@ -0,0 +1,156 @@
#include <stdio.h>
#include <stdlib.h>
#ifdef _WIN32
#include <windows.h>
#include <direct.h>
#endif
// 二叉树节点定义
struct BiTNode
{
char data; // 节点数据
struct BiTNode *lchild; // 左子节点
struct BiTNode *rchild; // 右子节点
};
typedef struct BiTNode *BiTree;
// 函数声明
void CreateBiTree(BiTree *T); // 创建二叉树
void PreOrderTraverse(BiTree T); // 先序遍历
void InOrderTraverse(BiTree T); // 中序遍历
void PostOrderTraverse(BiTree T); // 后序遍历
void PrintMenu(); // 打印菜单
void FreeTree(BiTree T);
int main()
{
// 设置控制台编码为UTF-8,防止中文乱码
#ifdef _WIN32
system("chcp 65001 > nul"); // 设置控制台编码为UTF-8
SetConsoleOutputCP(65001); // 设置控制台输出编码
SetConsoleCP(65001); // 设置控制台输入编码
#endif
BiTree T = NULL;
int choice;
printf("=== 链式二叉树遍历系统 (C语言版本) ===\n");
printf("请输入先序扩展序列构建二叉树(# 表示空节点,例如 AB#C##D##):\n");
CreateBiTree(&T);
do
{
PrintMenu();
if (scanf("%d", &choice) != 1)
{
return 0;
}
switch (choice)
{
case 1:
printf("先序遍历结果: ");
PreOrderTraverse(T);
printf("\n");
break;
case 2:
printf("中序遍历结果: ");
InOrderTraverse(T);
printf("\n");
break;
case 3:
printf("后序遍历结果: ");
PostOrderTraverse(T);
printf("\n");
break;
case 4:
printf("程序已退出。\n");
break;
default:
printf("无效输入,请输入 1~4 之间的数字!\n");
}
} while (choice != 4);
FreeTree(T);
return 0;
}
// 创建二叉树(先序扩展输入)
void CreateBiTree(BiTree *T)
{
char ch;
if (scanf(" %c", &ch) != 1)
{
*T = NULL;
return;
}
if (ch == '#')
{
*T = NULL;
}
else
{
*T = (struct BiTNode *)malloc(sizeof(struct BiTNode));
(*T)->data = ch;
(*T)->lchild = NULL;
(*T)->rchild = NULL;
CreateBiTree(&(*T)->lchild);
CreateBiTree(&(*T)->rchild);
}
}
// 先序遍历:根 -> 左 -> 右
void PreOrderTraverse(BiTree T)
{
if (T != NULL)
{
printf("%c ", T->data);
PreOrderTraverse(T->lchild);
PreOrderTraverse(T->rchild);
}
}
// 中序遍历:左 -> 根 -> 右
void InOrderTraverse(BiTree T)
{
if (T != NULL)
{
InOrderTraverse(T->lchild);
printf("%c ", T->data);
InOrderTraverse(T->rchild);
}
}
// 后序遍历:左 -> 右 -> 根
void PostOrderTraverse(BiTree T)
{
if (T != NULL)
{
PostOrderTraverse(T->lchild);
PostOrderTraverse(T->rchild);
printf("%c ", T->data);
}
}
// 打印菜单
void PrintMenu()
{
printf("\n--- 选择遍历方式 ---\n");
printf("1. 先序遍历\n");
printf("2. 中序遍历\n");
printf("3. 后序遍历\n");
printf("4. 退出\n");
printf("请输入选择 (1-4): ");
}
void FreeTree(BiTree T)
{
if (T)
{
FreeTree(T->lchild);
FreeTree(T->rchild);
free(T);
}
}
+312
View File
@@ -0,0 +1,312 @@
#include <stdio.h>
#include <stdlib.h>
#ifdef _WIN32
#include <windows.h>
#include <direct.h>
#endif
// 链式二叉树节点结构
struct BiTNode
{
char data;
struct BiTNode *lchild;
struct BiTNode *rchild;
};
// 二叉树指针类型定义
typedef struct BiTNode *BiTree;
// 函数声明
void CreateBiTree(BiTree *T); // 创建二叉树
void PreOrderTraverse(BiTree T); // 先序遍历
void InOrderTraverse(BiTree T); // 中序遍历
void PostOrderTraverse(BiTree T); // 后序遍历
void LevelOrderTraverse(BiTree T); // 层次遍历
int MaxWidth(BiTree T); // 计算最大宽度
void PrintMenu(); // 打印菜单
void FreeTree(BiTree T); // 释放二叉树内存
int main(void)
{
// 设置控制台编码为UTF-8,防止中文乱码
#ifdef _WIN32
system("chcp 65001 > nul"); // 设置控制台编码为UTF-8
SetConsoleOutputCP(65001); // 设置控制台输出编码
SetConsoleCP(65001); // 设置控制台输入编码
#endif
BiTree T = NULL;
int choice;
printf("=== 链式二叉树遍历系统 (C语言非递归) ===\n");
printf("请输入先序扩展序列构建二叉树(# 表示空节点,例如 AB#C##D##):\n");
CreateBiTree(&T);
do
{
PrintMenu();
if (scanf("%d", &choice) != 1)
{
printf("无效输入,请输入1~6之间的数字!\n");
continue;
}
switch (choice)
{
case 1:
printf("先序遍历结果: ");
PreOrderTraverse(T);
printf("\n");
break;
case 2:
printf("中序遍历结果: ");
InOrderTraverse(T);
printf("\n");
break;
case 3:
printf("后序遍历结果: ");
PostOrderTraverse(T);
printf("\n");
break;
case 4:
printf("层次遍历结果: ");
LevelOrderTraverse(T);
printf("\n");
break;
case 5:
printf("程序已退出。\n");
break;
case 6:
printf("最大宽度: %d\n", MaxWidth(T));
break;
default:
printf("无效输入,请输入 1~6 之间的数字!\n");
}
} while (choice != 5);
FreeTree(T);
return 0;
}
// 创建二叉树(先序扩展输入)
void CreateBiTree(BiTree *T)
{
char ch;
if (scanf(" %c", &ch) != 1)
{
*T = NULL;
return;
}
if (ch == '#')
{
*T = NULL;
return;
}
else
{
*T = (struct BiTNode *)malloc(sizeof(struct BiTNode));
(*T)->data = ch;
(*T)->lchild = NULL;
(*T)->rchild = NULL;
CreateBiTree(&(*T)->lchild);
CreateBiTree(&(*T)->rchild);
}
}
// 先序遍历:根 -> 左 -> 右
void PreOrderTraverse(BiTree T)
{
if (!T)
{
return;
}
// 栈初始化,用栈来显性表示递归时的函数调用
int cap = 128, top = 0;
BiTree *st = (BiTree *)malloc(sizeof(BiTree) * cap);
st[top++] = T;
while (top)
{
BiTree p = st[--top];
printf("%c ", p->data);
if (p->rchild)
{
if (top >= cap)
{
cap *= 2;
st = (BiTree *)realloc(st, sizeof(BiTree) * cap);
}
st[top++] = p->rchild;
}
if (p->lchild)
{
if (top >= cap)
{
cap *= 2;
st = (BiTree *)realloc(st, sizeof(BiTree) * cap);
}
st[top++] = p->lchild;
}
}
free(st);
}
// 中序遍历:左 -> 根 -> 右
void InOrderTraverse(BiTree T)
{
int cap = 128, top = 0;
BiTree *st = (BiTree *)malloc(sizeof(BiTree) * cap);
BiTree cur = T;
while (cur || top)
{
while (cur)
{
if (top >= cap)
{
cap *= 2;
st = (BiTree *)realloc(st, sizeof(BiTree) * cap);
}
st[top++] = cur;
cur = cur->lchild;
}
BiTree p = st[--top];
printf("%c ", p->data);
cur = p->rchild;
}
free(st);
}
// 后序遍历:左 -> 右 -> 根
void PostOrderTraverse(BiTree T)
{
int cap = 128, top = 0;
BiTree *st = (BiTree *)malloc(sizeof(BiTree) * cap);
BiTree cur = T, last = NULL;
while (cur || top)
{
while (cur)
{
if (top >= cap)
{
cap *= 2;
st = (BiTree *)realloc(st, sizeof(BiTree) * cap);
}
st[top++] = cur;
cur = cur->lchild;
}
BiTree p = st[top - 1];
if (p->rchild && last != p->rchild)
{
cur = p->rchild;
}
else
{
printf("%c ", p->data);
last = p;
--top;
}
}
free(st);
}
// 层次遍历:按层从左到右遍历
void LevelOrderTraverse(BiTree T)
{
if (!T)
{
return;
}
int cap = 128;
BiTree *q = (BiTree *)malloc(sizeof(BiTree) * cap);
int head = 0, tail = 0;
q[tail++] = T;
while (head < tail)
{
BiTree p = q[head++];
printf("%c ", p->data);
if (p->lchild)
{
if (tail >= cap)
{
cap *= 2;
q = (BiTree *)realloc(q, sizeof(BiTree) * cap);
}
q[tail++] = p->lchild;
}
if (p->rchild)
{
if (tail >= cap)
{
cap *= 2;
q = (BiTree *)realloc(q, sizeof(BiTree) * cap);
}
q[tail++] = p->rchild;
}
}
free(q);
}
// 计算二叉树的最大宽度
int MaxWidth(BiTree T)
{
if (!T) return 0;
int cap = 128;
BiTree *q = (BiTree *)malloc(sizeof(BiTree) * cap);
int head = 0, tail = 0;
int maxw = 0;
q[tail++] = T;
while (head < tail)
{
int level_size = tail - head;
if (level_size > maxw) maxw = level_size;
for (int i = 0; i < level_size; ++i)
{
BiTree p = q[head++];
if (p->lchild)
{
if (tail >= cap)
{
cap *= 2;
q = (BiTree *)realloc(q, sizeof(BiTree) * cap);
}
q[tail++] = p->lchild;
}
if (p->rchild)
{
if (tail >= cap)
{
cap *= 2;
q = (BiTree *)realloc(q, sizeof(BiTree) * cap);
}
q[tail++] = p->rchild;
}
}
}
free(q);
return maxw;
}
// 打印菜单
void PrintMenu(void)
{
printf("\n--- 选择遍历方式(非递归) ---\n");
printf("1. 先序遍历\n");
printf("2. 中序遍历\n");
printf("3. 后序遍历\n");
printf("4. 层次遍历\n");
printf("5. 退出\n");
printf("6. 最大宽度\n");
printf("请输入选择 (1-6): ");
}
// 释放二叉树内存
void FreeTree(BiTree T)
{
if (T)
{
FreeTree(T->lchild);
FreeTree(T->rchild);
free(T);
}
}
+211
View File
@@ -0,0 +1,211 @@
#include <stdio.h>
#include <stdlib.h>
#ifdef _WIN32
#include <windows.h>
#endif
// 图的邻接矩阵表示
typedef struct
{
int n;
int directed;
int **mat;
} GraphMat;
// 图的邻接表边的表示
typedef struct Edge
{
int to;
struct Edge *next;
} Edge;
// 图的邻接表表示
typedef struct
{
int n;
int directed;
Edge **head;
} GraphList;
// 创建邻接矩阵表示的图
GraphMat GraphMatCreate(int n, int directed)
{
GraphMat g;
g.n = n;
g.directed = directed;
g.mat = (int **)malloc((size_t)n * sizeof(int *));
for (int i = 0; i < n; ++i)
{
g.mat[i] = (int *)calloc((size_t)n, sizeof(int));
}
return g;
}
// 添加邻接矩阵表示的图的边
void GraphMatAddEdge(GraphMat *g, int u, int v)
{
int n = g->n;
if (u >= 1 && u <= n && v >= 1 && v <= n)
{
g->mat[u - 1][v - 1] = 1;
if (!g->directed)
{
g->mat[v - 1][u - 1] = 1;
}
}
}
// 释放邻接矩阵表示的图
void GraphMatFree(GraphMat *g)
{
if (g->mat)
{
for (int i = 0; i < g->n; ++i)
free(g->mat[i]);
free(g->mat);
g->mat = NULL;
}
}
// 创建邻接表表示的图
GraphList GraphListCreate(int n, int directed)
{
GraphList g;
g.n = n;
g.directed = directed;
g.head = (Edge **)calloc((size_t)n + 1, sizeof(Edge *));
return g;
}
// 添加邻接表表示的图的边
void GraphListAddEdge(GraphList *g, int u, int v)
{
int n = g->n;
if (u >= 1 && u <= n && v >= 1 && v <= n)
{
Edge *e = (Edge *)malloc(sizeof(Edge));
e->to = v;
e->next = g->head[u];
g->head[u] = e;
if (!g->directed)
{
Edge *e2 = (Edge *)malloc(sizeof(Edge));
e2->to = u;
e2->next = g->head[v];
g->head[v] = e2;
}
}
}
// 释放邻接表表示的图
void GraphListFree(GraphList *g)
{
for (int i = 1; i <= g->n; ++i)
{
Edge *p = g->head[i];
while (p)
{
Edge *nxt = p->next;
free(p);
p = nxt;
}
}
free(g->head);
g->head = NULL;
}
// 打印邻接矩阵表示的图
void PrintMatrix(const GraphMat *g)
{
int n = g->n;
printf("邻接矩阵:\n");
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < n; ++j)
{
if (j)
{
printf(" ");
}
printf("%d", g->mat[i][j]);
}
printf("\n");
}
}
// 打印邻接表表示的图
void PrintList(const GraphList *g)
{
printf("邻接表:\n");
for (int i = 1; i <= g->n; ++i)
{
printf("%d:", i);
Edge *p = g->head[i];
if (p)
{
printf(" ");
}
int first = 1;
while (p)
{
if (!first)
{
printf(" ");
}
printf("%d", p->to);
first = 0;
p = p->next;
}
printf("\n");
}
}
int main(void)
{
#ifdef _WIN32
system("chcp 65001 > nul");
SetConsoleOutputCP(65001);
SetConsoleCP(65001);
#endif
// 图的顶点数、边数和是否有向
int n, m, dir;
printf("请输入图的顶点数、边数和是否有向(0:无向, 1:有向): ");
if (scanf("%d %d %d", &n, &m, &dir) != 3)
{
printf("输入错误\n");
return 0;
}
if (n <= 0 || m < 0 || (dir != 0 && dir != 1))
{
printf("输入错误\n");
return 0;
}
// 创建邻接矩阵表示的图和邻接表表示的图
GraphMat gm = GraphMatCreate(n, dir);
GraphList gl = GraphListCreate(n, dir);
for (int i = 0; i < m; ++i)
{
int u, v;
if (scanf("%d %d", &u, &v) != 2)
{
printf("输入错误\n");
break;
}
// 添加邻接矩阵表示的图的边和邻接表表示的图的边
GraphMatAddEdge(&gm, u, v);
GraphListAddEdge(&gl, u, v);
}
// 打印邻接矩阵表示的图和邻接表表示的图
PrintMatrix(&gm);
PrintList(&gl);
// 释放邻接矩阵表示的图和邻接表表示的图
GraphMatFree(&gm);
GraphListFree(&gl);
return 0;
}
+119
View File
@@ -0,0 +1,119 @@
#include <stdio.h>
#include <stdlib.h>
#ifdef _WIN32
#include <windows.h>
#endif
// 图的边的表示
typedef struct
{
int u, v;
int w;
} Edge;
// 边的比较函数,用于排序
static int cmp_edge(const void *a, const void *b)
{
int wa = ((const Edge *)a)->w;
int wb = ((const Edge *)b)->w;
return (wa > wb) - (wa < wb);
}
// 并查集的查找函数
static int find(int *parent, int x)
{
if (parent[x] == x)
{
return x;
}
return parent[x] = find(parent, parent[x]);
}
// 并查集的合并函数
static void unite(int *parent, int *sz, int a, int b)
{
if (sz[a] < sz[b])
{
int t = a;
a = b;
b = t;
}
parent[b] = a;
sz[a] += sz[b];
}
int main(void)
{
#ifdef _WIN32
system("chcp 65001 > nul");
SetConsoleOutputCP(65001);
SetConsoleCP(65001);
#endif
// 读取图的边数和节点数
int n, m;
if (scanf("%d %d", &n, &m) != 2)
{
printf("输入错误\n");
return 0;
}
// 读取图的边
Edge *e = (Edge *)malloc((size_t)m * sizeof(Edge));
for (int i = 0; i < m; ++i)
{
int u, v, w;
scanf("%d %d %d", &u, &v, &w);
e[i].u = u;
e[i].v = v;
e[i].w = w;
}
// 初始化并查集
int *parent = (int *)malloc((size_t)(n + 1) * sizeof(int));
int *sz = (int *)malloc((size_t)(n + 1) * sizeof(int));
for (int i = 1; i <= n; ++i)
{
parent[i] = i;
sz[i] = 1;
}
// 对边按权重排序
qsort(e, (size_t)m, sizeof(Edge), cmp_edge);
// 最小生成树的计算
long long ans = 0;
int cnt = 0;
for (int i = 0; i < m && cnt < n - 1; ++i)
{
// 跳过无效的边
int u = e[i].u, v = e[i].v;
if (u < 1 || u > n || v < 1 || v > n)
{
continue;
}
// 检查是否形成环
int ru = find(parent, u), rv = find(parent, v);
if (ru != rv)
{
ans += e[i].w;
unite(parent, sz, ru, rv);
++cnt;
}
}
// 检查是否所有节点都在最小生成树中
if (cnt == n - 1)
{
printf("%lld\n", ans);
}
else
{
printf("impossible\n");
}
free(sz);
free(parent);
free(e);
return 0;
}
+46
View File
@@ -0,0 +1,46 @@
#include <stdio.h>
#include <string.h>
int main()
{
int T;
scanf("%d", &T);
while (T--)
{
char str[10001];
scanf("%s", str);
// 统计每个小写字母的出现次数
int count[26] = {0}; // a-z对应0-25
int len = strlen(str);
for (int i = 0; i < len; i++)
{
char c = str[i];
// 只统计小写字母
if (c >= 'a' && c <= 'z')
{
count[c - 'a']++;
}
}
// 找出出现次数最多的字母,如果次数相同则选择字典序最小的
int max_count = 0;
char result = 'a';
// 从a到z遍历,保证字典序最小
for (int i = 0; i < 26; i++)
{
if (count[i] > max_count)
{
max_count = count[i];
result = 'a' + i;
}
}
printf("%c\n", result);
}
return 0;
}
+32
View File
@@ -0,0 +1,32 @@
#include <stdio.h>
#include <string.h>
int main()
{
int T;
scanf("%d", &T);
while (T--)
{
char str[10001];
scanf("%s", str);
int count = 0;
int len = strlen(str);
// 遍历字符串,统计小写字母个数
for (int i = 0; i < len; i++)
{
char c = str[i];
// 判断是否为小写字母
if (c >= 'a' && c <= 'z')
{
count++;
}
}
printf("%d\n", count);
}
return 0;
}
+36
View File
@@ -0,0 +1,36 @@
#include <stdio.h>
int main()
{
int N;
scanf("%d", &N);
while (N--)
{
int AH, AM, AS, BH, BM, BS;
scanf("%d %d %d %d %d %d", &AH, &AM, &AS, &BH, &BM, &BS);
// 直接相加
int total_hours = AH + BH;
int total_minutes = AM + BM;
int total_seconds = AS + BS;
// 处理秒的进位
if (total_seconds >= 60)
{
total_minutes += total_seconds / 60;
total_seconds = total_seconds % 60;
}
// 处理分钟的进位
if (total_minutes >= 60)
{
total_hours += total_minutes / 60;
total_minutes = total_minutes % 60;
}
printf("%d %d %d\n", total_hours, total_minutes, total_seconds);
}
return 0;
}
+124
View File
@@ -0,0 +1,124 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef _WIN32
#include <windows.h>
#include <direct.h>
#endif
#define MAX_SIZE 10
typedef struct
{
int data[MAX_SIZE]; // 存储数据的数组
int length; // 当前顺序表长度
} List;
// 初始化顺序表
void InitList(List *L)
{
L->length = 0;
memset(L->data, 0, sizeof(L->data));
}
// 判断顺序表是否已满
int IsFull(List *L)
{
return L->length == MAX_SIZE;
}
// 在指定位置插入元素
int InsertLoc(List *L, int loc, int value)
{
if (IsFull(L))
{
return 0;
}
if (loc < 1 || loc > L->length + 1)
{
return 0;
}
// 将插入位置后的元素后移
for (int i = L->length; i >= loc; i--)
{
L->data[i] = L->data[i - 1];
}
// 插入新元素和更新长度
L->data[loc - 1] = value;
L->length++;
return 1;
}
// 显示顺序表内容
void DisplayList(List *L)
{
for (int i = 0; i < L->length; i++)
{
printf("%d\n", L->data[i]);
}
}
int main()
{
// 设置控制台编码为UTF-8,防止中文乱码
#ifdef _WIN32
system("chcp 65001 > nul"); // 设置控制台编码为UTF-8
SetConsoleOutputCP(65001); // 设置控制台输出编码
SetConsoleCP(65001); // 设置控制台输入编码
_mkdir("records");
#endif
List L;
InitList(&L);
// 插入一些元素以测试
for (int i = 0; i < 9; i++)
{
scanf("%d", &L.data[i]);
L.length++;
}
// 验证输入数组是否有序
for (int i = 1; i < L.length; i++)
{
if (L.data[i] < L.data[i - 1])
{
printf("输入数组未按升序排列\n");
return 1;
}
}
// 找到value插入的位置
int value, loc;
scanf("%d", &value);
// 默认插入到最后
loc = L.length + 1;
for (int i = 0; i < L.length; i++)
{
if (value <= L.data[i])
{
loc = i + 1;
break;
}
}
// 插入元素
if (L.length >= MAX_SIZE)
{
printf("插入失败:顺序表已满\n");
return 1;
}
if (!InsertLoc(&L, loc, value))
{
printf("插入失败\n");
return 1;
}
// 显示顺序表内容
DisplayList(&L);
return 0;
}
+73
View File
@@ -0,0 +1,73 @@
#include <stdio.h>
#ifdef _WIN32
#include <windows.h>
#include <direct.h>
#endif
// 删除数组中下标为 i 的元素
void del(int a[], int n, int i)
{
if (i < 0 || i >= n)
{
printf("下标超出范围\n");
return;
}
for (int j = i; j < n - 1; j++)
{
a[j] = a[j + 1];
}
}
// 输出数组的前 n 个元素
void PrintArr(int a[], int n)
{
for (int j = 0; j < n; j++)
{
printf("%d", a[j]);
if (j < n - 1)
{
printf(" ");
}
}
printf("\n");
}
int main()
{
// 设置控制台编码为UTF-8,防止中文乱码
#ifdef _WIN32
system("chcp 65001 > nul"); // 设置控制台编码为UTF-8
SetConsoleOutputCP(65001); // 设置控制台输出编码
SetConsoleCP(65001); // 设置控制台输入编码
_mkdir("records");
#endif
int n;
scanf("%d", &n);
if (n <= 0 || n >= 10)
{
printf("数组长度不合法\n");
return 1;
}
int a[10];
for (int i = 0; i < n; i++)
{
scanf("%d", &a[i]);
}
int index;
scanf("%d", &index);
if (index < 0 || index >= n)
{
printf("下标超出范围\n");
return 1;
}
del(a, n, index);
PrintArr(a, n - 1);
return 0;
}
-35
View File
@@ -1,35 +0,0 @@
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#ifdef _WIN32
#include <windows.h>
#include <direct.h>
#endif
// 计算斐波那契第n项(公式法)
long long fib_binet(int n)
{
const double phi = (1 + sqrt(5)) / 2; // 黄金分割比
const double sqrt5 = sqrt(5); // 根号5
double value = pow(phi, n) / sqrt5; // 核心计算项
return llround(value); // 四舍五入取整(避免小数误差)
}
int main()
{
// 设置控制台编码为UTF-8,防止中文乱码
#ifdef _WIN32
system("chcp 65001 > nul"); // 设置控制台编码为UTF-8
SetConsoleOutputCP(65001); // 设置控制台输出编码
SetConsoleCP(65001); // 设置控制台输入编码
_mkdir("records");
#endif
// 计算第47项及后续3项(47~50项)
for (int n = 47; n <= 50; n++)
{
long long result = fib_binet(n);
printf("第%d项: %lld\n", n, result);
}
return 0;
}
-244
View File
@@ -1,244 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
// 宏定义:状态码与元素类型
typedef int Status; // 函数返回状态
typedef int SElemType; // 栈元素类型(可根据需求修改,如char、float等)
// 双栈数据结构定义(题目给定)
typedef struct
{
int top[2], bot[2]; // 栈顶、栈底指针(top[0]对应0号栈,top[1]对应1号栈)
SElemType *V; // 共享的数组空间
int m; // 数组最大容量(双栈总容量)
} DblStack;
/**
*
* @param s
* @param m
* @return OKOVERFLOW
*/
Status InitDblStack(DblStack *s, int m)
{
if (m <= 0)
return 0; // 容量无效
s->V = (SElemType *)malloc(m * sizeof(SElemType));
if (!s->V)
return -1; // 内存分配失败
s->m = m;
// 初始化0号栈:栈底在数组起始位置(索引0),空栈时top[0] = -1
s->top[0] = -1;
s->bot[0] = 0;
// 初始化1号栈:栈底在数组末尾(索引m-1),空栈时top[1] = m
s->top[1] = m;
s->bot[1] = m - 1;
return 1;
}
/**
*
* @param s
*/
void DestroyDblStack(DblStack *s)
{
if (s->V)
{
free(s->V); // 释放数组空间
s->V = NULL;
}
s->m = 0;
s->top[0] = -1;
s->top[1] = 0;
s->bot[0] = s->bot[1] = 0;
}
/**
*
* @param s
* @param stackNum 01
* @return OKERRORERROR
*/
Status IsEmpty(DblStack s, int stackNum)
{
if (stackNum != 0 && stackNum != 1)
return 0; // 栈号无效
if (stackNum == 0)
{
return (s.top[0] == -1) ? 1 : 0; // 0号栈空:top[0] = -1
}
else
{
return (s.top[1] == s.m) ? 1 : 0; // 1号栈空:top[1] = m
}
}
/**
*
* @param s
* @return OKERROR
*/
Status IsFull(DblStack s)
{
// 0号栈顶的下一个位置等于1号栈顶时,无剩余空间
return (s.top[0] + 1 == s.top[1]) ? 1 : 0;
}
/**
*
* @param s
* @param stackNum 01
* @param e
* @return OK/ERROR
*/
Status Push(DblStack *s, int stackNum, SElemType e)
{
if (stackNum != 0 && stackNum != 1)
return 0; // 栈号无效
if (IsFull(*s) == 1)
{
printf("双栈已满,无法进栈!\n");
return 0;
}
if (stackNum == 0)
{
// 0号栈:栈顶指针上移(+1),元素存入新栈顶
s->top[0]++;
s->V[s->top[0]] = e;
}
else
{
// 1号栈:栈顶指针下移(-1),元素存入新栈顶
s->top[1]--;
s->V[s->top[1]] = e;
}
return 1;
}
/**
*
* @param s
* @param stackNum 01
* @param e
* @return OK/ERROR
*/
Status Pop(DblStack *s, int stackNum, SElemType *e)
{
if (stackNum != 0 && stackNum != 1)
return 0; // 栈号无效
if (IsEmpty(*s, stackNum) == 1)
{
printf("栈%d为空,无法出栈!\n", stackNum);
return 0;
}
if (stackNum == 0)
{
// 0号栈:取出当前栈顶元素,栈顶指针下移(-1)
*e = s->V[s->top[0]];
s->top[0]--;
}
else
{
// 1号栈:取出当前栈顶元素,栈顶指针上移(+1)
*e = s->V[s->top[1]];
s->top[1]++;
}
return 1;
}
/**
*
* @param s
* @param stackNum 01
* @param e
* @return OK/ERROR
*/
Status GetTop(DblStack s, int stackNum, SElemType *e)
{
if (stackNum != 0 && stackNum != 1)
return 0; // 栈号无效
if (IsEmpty(s, stackNum) == 1)
{
printf("栈%d为空,无栈顶元素!\n", stackNum);
return 0;
}
if (stackNum == 0)
{
*e = s.V[s.top[0]]; // 0号栈顶元素
}
else
{
*e = s.V[s.top[1]]; // 1号栈顶元素
}
return 1;
}
/**
*
*/
void TestDblStack()
{
DblStack s;
int m = 5; // 双栈总容量为5
SElemType e;
// 初始化双栈
if (InitDblStack(&s, m) != 1)
{
printf("双栈初始化失败!\n");
return;
}
printf("初始化双栈成功(容量:%d\n", m);
// 测试栈空
printf("栈0是否为空?%s\n", IsEmpty(s, 0) == 1 ? "" : ""); // 是
printf("栈1是否为空?%s\n", IsEmpty(s, 1) == 1 ? "" : ""); // 是
// 0号栈进栈
Push(&s, 0, 10);
Push(&s, 0, 20);
Push(&s, 0, 30);
printf("0号栈进栈元素:10, 20, 30\n");
GetTop(s, 0, &e);
printf("0号栈顶元素:%d\n", e); // 30
// 1号栈进栈
Push(&s, 1, 100);
Push(&s, 1, 200);
printf("1号栈进栈元素:100, 200\n");
GetTop(s, 1, &e);
printf("1号栈顶元素:%d\n", e); // 200
// 测试栈满(此时0号栈顶=2,1号栈顶=3,2+1=3 → 满)
printf("双栈是否已满?%s\n", IsFull(s) == 1 ? "" : ""); // 是
// 尝试继续进栈(应失败)
Push(&s, 0, 40); // 提示"双栈已满"
// 出栈操作
Pop(&s, 0, &e);
printf("0号栈出栈元素:%d\n", e); // 30
Pop(&s, 1, &e);
printf("1号栈出栈元素:%d\n", e); // 200
// 出栈后栈顶
GetTop(s, 0, &e);
printf("0号栈顶元素(出栈后):%d\n", e); // 20
GetTop(s, 1, &e);
printf("1号栈顶元素(出栈后):%d\n", e); // 100
// 销毁双栈
DestroyDblStack(&s);
printf("双栈销毁完成\n");
}
int main()
{
TestDblStack();
return 0;
}
@@ -2,6 +2,9 @@
本目录包含数据结构相关的C语言实现代码,专注于基础数据结构的学习和实践。 本目录包含数据结构相关的C语言实现代码,专注于基础数据结构的学习和实践。
## 仓库地址
- GitHub仓库为:https://github.com/LHY0125/Learn_C.git
## 📁 文件列表 ## 📁 文件列表
### 核心实现 ### 核心实现
+7 -8
View File
@@ -6,8 +6,7 @@
#include <direct.h> #include <direct.h>
#endif #endif
typedef int Status; // 函数返回状态 typedef int SElemType; // 栈元素类型,方便自定义栈的数据类型
typedef int SElemType; // 栈元素类型
typedef struct typedef struct
{ {
@@ -17,7 +16,7 @@ typedef struct
} DblStack; } DblStack;
// 双栈的初始化 // 双栈的初始化
Status Init(DblStack *s, int m) int Init(DblStack *s, int m)
{ {
// 容量无效 // 容量无效
if (m <= 0) if (m <= 0)
@@ -56,7 +55,7 @@ void Destroy(DblStack *s)
} }
// 判断栈是否为空 // 判断栈是否为空
Status IsEmpty(DblStack s, int Num) int IsEmpty(DblStack s, int Num)
{ {
// 栈号无效 // 栈号无效
if (Num != 0 && Num != 1) if (Num != 0 && Num != 1)
@@ -91,7 +90,7 @@ Status IsEmpty(DblStack s, int Num)
} }
// 判断双栈是否已满 // 判断双栈是否已满
Status IsFull(DblStack s) int IsFull(DblStack s)
{ {
// 两栈顶相遇 // 两栈顶相遇
if (s.top[0] + 1 == s.top[1]) if (s.top[0] + 1 == s.top[1])
@@ -105,7 +104,7 @@ Status IsFull(DblStack s)
} }
// 进栈操作 // 进栈操作
Status Push(DblStack *s, int Num, SElemType e) int Push(DblStack *s, int Num, SElemType e)
{ {
// 栈号无效 // 栈号无效
if (Num != 0 && Num != 1) if (Num != 0 && Num != 1)
@@ -134,7 +133,7 @@ Status Push(DblStack *s, int Num, SElemType e)
} }
// 出栈操作 // 出栈操作
Status Pop(DblStack *s, int Num, SElemType *e) int Pop(DblStack *s, int Num, SElemType *e)
{ {
// 栈号无效 // 栈号无效
if (Num != 0 && Num != 1) if (Num != 0 && Num != 1)
@@ -163,7 +162,7 @@ Status Pop(DblStack *s, int Num, SElemType *e)
} }
// 获取栈顶元素 // 获取栈顶元素
Status GetTop(DblStack s, int Num, SElemType *e) int GetTop(DblStack s, int Num, SElemType *e)
{ {
// 栈号无效 // 栈号无效
if (Num != 0 && Num != 1) if (Num != 0 && Num != 1)
@@ -0,0 +1,23 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef _WIN32
#include <windows.h>
#include <direct.h>
#endif
int main()
{
// 设置控制台编码为UTF-8,防止中文乱码
#ifdef _WIN32
system("chcp 65001 > nul"); // 设置控制台编码为UTF-8
SetConsoleOutputCP(65001); // 设置控制台输出编码
SetConsoleCP(65001); // 设置控制台输入编码
_mkdir("records");
#endif
return 0;
}
-1
View File
@@ -8,7 +8,6 @@
#include <direct.h> #include <direct.h>
#endif #endif
// clock_t 是一个无符号整数类型,用于表示时钟 ticks 的数量。
clock_t start, stop; clock_t start, stop;
// 记录程序运行时间 // 记录程序运行时间