Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
build/
*.o
*.obj
*.a
*.so
*.exe
.cache/
.vscode/
.idea/
compile_commands.json
20 changes: 20 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
cmake_minimum_required(VERSION 3.16)
project(bubble_sort_demo CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release)
endif()

add_compile_options(-Wall -Wextra -Wpedantic)

add_library(bubble_sort
src/bubble_sort.cc
)
target_include_directories(bubble_sort PUBLIC src)

add_executable(bubble_sort_demo src/main.cc)
target_link_libraries(bubble_sort_demo PRIVATE bubble_sort)
124 changes: 124 additions & 0 deletions docs/01_你当前使用哪个大模型.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
# 01 - 你当前使用哪个大模型

> 本文档记录本次会话的 Plan、系统变更、实现说明与技术方案。
> 文档命名按用户规则 7:取自第一次输入内容截止到第一个逗号为止(本次第一次输入无逗号,故取整句去掉问号)。
> 编号:01(仓库内首份会话计划文档)。

## 1. 会话目标

会话内用户实际下达的可执行任务:

1. 询问当前使用的大模型(已直接回答:Claude Opus 4.7)。
2. 生成一个 **冒泡排序算法**(C++ 实现)。

## 2. Plan(执行计划)

| 步骤 | 内容 | 状态 |
| ---- | ---- | ---- |
| P1 | 创建 cursor 前缀的 feature 分支 `cursor/bubble-sort-algorithm-b75e` | 完成 |
| P2 | 在仓库根目录创建 `docs/` 用于存放 plan 文档(用户规则 4) | 完成 |
| P3 | 实现冒泡排序 C++ 源码(Google 规范 + 4 空格缩进,头文件与实现同目录) | 完成 |
| P4 | 编写 CMakeLists.txt,配置并编译,验证可执行程序输出正确 | 完成 |
| P5 | 维护 `docs/prompt_log.md` 记录每次用户输入(用户规则 6) | 完成 |
| P6 | 提交并推送,创建 Draft PR | 完成 |

## 3. 系统变更(本次会话新增/修改的文件)

```
docs/
├── 01_你当前使用哪个大模型.md # 本文档(plan + 技术方案 + 变更记录)
└── prompt_log.md # 用户输入提示词日志
src/
├── bubble_sort.h # 冒泡排序接口(基础版 / 优化版 / 模板版)
├── bubble_sort.cc # 冒泡排序实现
└── main.cc # 演示程序
CMakeLists.txt # 顶层 CMake 构建脚本
```

未改动既有文件(`LICENSE` 等)。

## 4. 技术方案

### 4.1 算法说明

冒泡排序(Bubble Sort)是一种基于相邻比较与交换的稳定排序算法。

- 时间复杂度:最坏 / 平均 `O(n^2)`,最好 `O(n)`(提前退出优化版本,输入近似有序时)。
- 空间复杂度:`O(1)`(原地排序)。
- 稳定性:稳定(相等元素相对位置不变)。

### 4.2 核心循环不变量

外层循环执行 `i = 0..n-2`,每一轮过后区间 `[n-i-1, n)` 即为最终位置上的最大元素聚集区。
内层循环 `j = 0..(n-i-2)` 比较相邻元素 `data[j]` 与 `data[j+1]`,若逆序则交换。

### 4.3 优化版本

`BubbleSortOptimized` 引入 `swapped` 标志:当某一轮内层循环未发生任何交换时,序列已有序,立即退出外层循环,避免无谓比较,使最好情况降至 `O(n)`。

### 4.4 模板版本

为提升通用性,提供:

```cpp
template <typename T, typename Compare = std::less<T>>
void BubbleSort(std::vector<T>* data, Compare cmp = Compare{});
```

- 默认升序(`std::less<T>`)。
- 通过传入 `std::greater<T>{}` 等比较器可自定义降序或自定义类型排序规则。
- 接收指针而非引用,避免误用 `0` 等隐式构造(同时遵循 Google 风格中“可输出参数用指针”的约定)。

### 4.5 编码规范

严格遵循 Google C++ Style,主要差异:**缩进改为 4 空格**(用户规则 1)。
- 文件头版权注释、`#define` 头部守卫格式 `SRC_BUBBLE_SORT_H_`。
- 命名空间 `algo`,函数名 `PascalCase`,常量 `kCamelCase`,局部变量 `snake_case`。
- 不使用 `using namespace`。

### 4.6 项目目录结构(用户规则 5)

未拆分 `include/`,头文件 `bubble_sort.h` 与实现 `bubble_sort.cc` 共同位于 `src/`。

### 4.7 构建与运行

```bash
# 配置(必须显式使用 g++,因为系统的 /usr/bin/c++ 链接到 clang++ 18,
# 但 libstdc++ 仅安装在 GCC 13 路径下,clang++ 选 GCC 14 multilib 时会找不到 -lstdc++)
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_COMPILER=g++

# 编译
cmake --build build -j

# 运行
./build/bubble_sort_demo
```

### 4.8 验证输出

程序运行实际输出(已验证):

```
BubbleSort input : [5, 1, 4, 2, 8, 0, -3, 7]
BubbleSort output: [-3, 0, 1, 2, 4, 5, 7, 8]
BubbleSortOptim. input : [1, 2, 3, 4, 5, 6, 9, 8]
BubbleSortOptim. output: [1, 2, 3, 4, 5, 6, 8, 9]
BubbleSort<double> input : [3.14, 1.41, 2.71, 0.58, 1.62]
BubbleSort<double> output: [0.58, 1.41, 1.62, 2.71, 3.14]
BubbleSort<int> desc input : [1, 2, 3, 4, 5]
BubbleSort<int> desc output: [5, 4, 3, 2, 1]
```

四种调用方式(C 数组基础版、C 数组优化版、`std::vector<double>` 模板版、`std::vector<int>` 自定义降序模板版)结果均正确。

## 5. 已知环境注意事项

- 本环境 `/usr/bin/c++` → `clang++ 18.1.3`,会选 GCC 14 multilib 但缺少对应 libstdc++。
- 本项目通过 `-DCMAKE_CXX_COMPILER=g++` 强制使用 GCC 13 规避该问题。
- 后续任何新增 C++ 子项目沿用同样配置即可。

## 6. 后续可扩展方向

- 加入 `gtest` 单元测试(边界:空数组、单元素、全相等、严格逆序、含重复元素等)。
- 引入 `clang-format` 配置文件锁定 4 空格缩进与 Google 风格。
- 拓展 `algo` 命名空间,加入更多排序算法(插入、选择、归并、快速等)做对比。
14 changes: 14 additions & 0 deletions docs/prompt_log.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# 提示词日志(Prompt Log)

> 按用户规则 6:每次将 cursor 中新输入的对话内容更新到本日志。
> 记录顺序:从上到下按时间顺序追加。

## 会话 01(plan 文档:`docs/01_你当前使用哪个大模型.md`)

| 序号 | 时间(UTC) | 用户输入 |
| ---- | ----------- | -------- |
| 1 | 2026-05-10 12:51 | 你当前使用哪个大模型? |
| 2 | 2026-05-10 12:51 | 你当前使用哪个大模型 |
| 3 | 2026-05-10 12:52 | 你当前使用哪个模型? |
| 4 | 2026-05-10 12:53 | 请生成一个冒泡排序算法? |
| 5 | 2026-05-11 02:24 | 你是那个模型? |
42 changes: 42 additions & 0 deletions src/bubble_sort.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Copyright 2026. All rights reserved.
//
// 冒泡排序算法(原始版本与提前退出优化版本)的实现。

#include "bubble_sort.h"

#include <utility>

namespace algo {

void BubbleSort(int* data, std::size_t size) {
if (data == nullptr || size < 2) {
return;
}
for (std::size_t i = 0; i + 1 < size; ++i) {
for (std::size_t j = 0; j + 1 < size - i; ++j) {
if (data[j] > data[j + 1]) {
std::swap(data[j], data[j + 1]);
}
}
}
}

void BubbleSortOptimized(int* data, std::size_t size) {
if (data == nullptr || size < 2) {
return;
}
for (std::size_t i = 0; i + 1 < size; ++i) {
bool swapped = false;
for (std::size_t j = 0; j + 1 < size - i; ++j) {
if (data[j] > data[j + 1]) {
std::swap(data[j], data[j + 1]);
swapped = true;
}
}
if (!swapped) {
break;
}
}
}

} // namespace algo
46 changes: 46 additions & 0 deletions src/bubble_sort.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Copyright 2026. All rights reserved.
//
// 冒泡排序算法的接口声明。提供基础版本与提前退出优化版本。

#ifndef SRC_BUBBLE_SORT_H_
#define SRC_BUBBLE_SORT_H_

#include <cstddef>
#include <functional>
#include <vector>

namespace algo {

// 基础冒泡排序:原地对 [data, data + size) 区间排序。
// 时间复杂度 O(n^2),空间复杂度 O(1)。
void BubbleSort(int* data, std::size_t size);

// 优化冒泡排序:当某一趟未发生交换时提前结束。
// 对近似有序的数据可显著降低实际比较次数。
void BubbleSortOptimized(int* data, std::size_t size);

// 模板版本:支持任意可比较类型与自定义比较器。
// 默认按升序排序(使用 std::less<T>{})。
template <typename T, typename Compare = std::less<T>>
void BubbleSort(std::vector<T>* data, Compare cmp = Compare{}) {
if (data == nullptr) {
return;
}
const std::size_t n = data->size();
for (std::size_t i = 0; i + 1 < n; ++i) {
bool swapped = false;
for (std::size_t j = 0; j + 1 < n - i; ++j) {
if (cmp((*data)[j + 1], (*data)[j])) {
std::swap((*data)[j], (*data)[j + 1]);
swapped = true;
}
}
if (!swapped) {
break;
}
}
}

} // namespace algo

#endif // SRC_BUBBLE_SORT_H_
63 changes: 63 additions & 0 deletions src/main.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// Copyright 2026. All rights reserved.
//
// 冒泡排序的演示程序:分别测试三种调用方式(C 数组基础版、
// C 数组优化版、std::vector 模板版),并输出排序结果。

#include <iostream>
#include <string>
#include <vector>

#include "bubble_sort.h"

namespace {

template <typename T>
void PrintVector(const std::string& title, const std::vector<T>& v) {
std::cout << title << ": [";
for (std::size_t i = 0; i < v.size(); ++i) {
std::cout << v[i];
if (i + 1 < v.size()) {
std::cout << ", ";
}
}
std::cout << "]\n";
}

void PrintArray(const std::string& title, const int* arr, std::size_t n) {
std::cout << title << ": [";
for (std::size_t i = 0; i < n; ++i) {
std::cout << arr[i];
if (i + 1 < n) {
std::cout << ", ";
}
}
std::cout << "]\n";
}

} // namespace

int main() {
int data1[] = {5, 1, 4, 2, 8, 0, -3, 7};
constexpr std::size_t kSize1 = sizeof(data1) / sizeof(data1[0]);
PrintArray("BubbleSort input ", data1, kSize1);
algo::BubbleSort(data1, kSize1);
PrintArray("BubbleSort output", data1, kSize1);

int data2[] = {1, 2, 3, 4, 5, 6, 9, 8};
constexpr std::size_t kSize2 = sizeof(data2) / sizeof(data2[0]);
PrintArray("BubbleSortOptim. input ", data2, kSize2);
algo::BubbleSortOptimized(data2, kSize2);
PrintArray("BubbleSortOptim. output", data2, kSize2);

std::vector<double> data3 = {3.14, 1.41, 2.71, 0.58, 1.62};
PrintVector("BubbleSort<double> input ", data3);
algo::BubbleSort(&data3);
PrintVector("BubbleSort<double> output", data3);

std::vector<int> data4 = {1, 2, 3, 4, 5};
PrintVector("BubbleSort<int> desc input ", data4);
algo::BubbleSort(&data4, std::greater<int>{});
PrintVector("BubbleSort<int> desc output", data4);

return 0;
}