【C++ 中级】 算法 题目记录

热度数据: 188

本文章记录了有关 C++ 数据处理 题目 和 案例 的汇总。

 中国 天津

【C++ 中级】 算法 题目记录

C++ 技术栏

本文章记录了有关 C++ 数据处理 题目 和 案例 的汇总。

目录

文章的封面

排序操作

冒泡排序

  1. #include <vector>
  2. #include "iostream"
  3. using namespace std;
  4. ostream &operator<<(ostream &ostream1, vector<int> &v) {
  5. auto it1 = v.begin(), it2 = v.end();
  6. while (it1 != it2) {
  7. cout << *it1++ << ' ';
  8. }
  9. return ostream1;
  10. }
  11. void swap(vector<int> &v, int index1, int index2) {
  12. int t = v[index1];
  13. v[index1] = v[index2];
  14. v[index2] = t;
  15. }
  16. void sort(vector<int> &v) {
  17. // 冒泡排序的操作其实就是双循环,内循环中用来将一个元素调整到合适的位置
  18. // 且因为有 v.size() 个元素 所以我们要调整 v.size() 次 也就是 v.size() 轮
  19. // 大概逻辑就是 第1次将第0索引的元素找到合适位置 第2次将第1索引的元素找到合适位置
  20. for (int i1 = 0; i1 < v.size(); ++i1) {
  21. cout << v << endl;
  22. // 这里代表每一轮迭代 值得注意的是 冒泡排序每轮都是当前索引值和下一索引值比较
  23. // 因此在这里我们循环限制条件里要减 1 避免出现越界
  24. // 其次 因为迭代几轮,就代表后几个元素排序完毕,且 i1 代表轮数,因此这里我们为了快速,要减 i1(当然 可以不减)
  25. for (int i = 0; i < v.size() - i1 - 1; ++i) {
  26. // 在这里我们将当前索引的元素和下一个索引的元素进行比较,如果发现大/小就交换位置
  27. // 这里也就是我们所说的排序的核心操作,在这里进行的位置交换!
  28. if (v[i] > v[i + 1]) {
  29. swap(v, i, i + 1);
  30. }
  31. }
  32. }
  33. }
  34. int main() {
  35. vector<int> v{10, 3, 4, 1, 60, 7};
  36. sort(v);
  37. cout << v << endl;
  38. }

选择排序

这个就类似人类的排序操作,不断的寻找最值,然后追加到新容器或者旧容器中,下面就是一个示例。

  1. #include <vector>
  2. #include "iostream"
  3. using namespace std;
  4. ostream &operator<<(ostream &ostream1, vector<int> &v) {
  5. auto it1 = v.begin(), it2 = v.end();
  6. while (it1 != it2) {
  7. cout << *it1++ << ' ';
  8. }
  9. return ostream1;
  10. }
  11. void swap(vector<int> &v, int index1, int index2) {
  12. int t = v[index1];
  13. v[index1] = v[index2];
  14. v[index2] = t;
  15. }
  16. void sort(vector<int> &v) {
  17. // 在这里我们还是需要迭代,这里的 i1 代表的就是当前正在排序的位置
  18. // 如果 i1 迭代结束 排序就结束了
  19. for (int i1 = 0; i1 < v.size(); ++i1) {
  20. // 在这里,我们需要找到从 i1 之后
  21. // 向量中最小值/最大值(根据需求哦)对应的索引!和 i1 的位置做交换
  22. // 这样就实现了排序咯
  23. int minIndex = i1;
  24. int minValue = v[i1];
  25. for (int i = i1 + 1; i < v.size(); ++i){
  26. if (minValue > v[i]){
  27. // 如果有一个数值 v[i] 比目前选中的最小值还小,则代表 v[i] 是最小值
  28. minValue = v[i], minIndex = i;
  29. }
  30. }
  31. // 到这里找到最小值了 直接进行交换 把最小值堆积到前面去
  32. swap(v, i1, minIndex);
  33. }
  34. }
  35. int main() {
  36. vector<int> v{10, 3, 4, 1, 60, 7};
  37. sort(v);
  38. cout << v << endl;
  39. }

快速排序

它的步骤如下
① 从数列中挑出一个元素,称为 “基准”(pivot);
② 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作;
③ 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序;

简单来说,就是每次递归中都会找到一个基准,然后进行分区,分区之后,基准左右各自再次调用递归操作,直到左右指向同一个位置,代表结束排序!

接下来是具体的实现操作!

  1. #include <vector>
  2. #include "iostream"
  3. using namespace std;
  4. ostream &operator<<(ostream &ostream1, vector<int> &v) {
  5. auto it1 = v.begin(), it2 = v.end();
  6. while (it1 != it2) {
  7. cout << *it1++ << ' ';
  8. }
  9. return ostream1;
  10. }
  11. // 分区函数,参数为待分区的数组arr,以及数组的起始和结束索引low和high
  12. // 先选基准值
  13. // 将小于的放基准值左边 大于的放基准值右边
  14. // 然后将基准值的索引返回出去
  15. int partition(vector<int> &arr, int low, int high) {
  16. // 选择数组的最后一个元素作为pivot
  17. int pivot = arr[high];
  18. // 初始化一个指针i,用于记录小于pivot的元素的个数
  19. int i = (low - 1);
  20. // 遍历数组中的每一个元素
  21. for (int j = low; j <= high - 1; j++) {
  22. // 如果当前元素小于pivot
  23. if (arr[j] < pivot) {
  24. // 将当前元素与指针i指向的元素交换,即将小于pivot的元素放到数组的左侧
  25. i++; // 增加指针i的值,表示又找到了一个小于pivot的元素
  26. swap(arr[i], arr[j]); // 交换元素
  27. }
  28. }
  29. // 将pivot元素放到其正确的位置上,即与指针i+1指向的元素交换
  30. swap(arr[i + 1], arr[high]);
  31. // 返回pivot元素的最终位置
  32. return (i + 1);
  33. }
  34. void sort_fun(vector<int> &arr, int low, int high) {
  35. // 当起始索引小于结束索引时,表示数组中还有未排序的部分
  36. if (low < high) {
  37. // 调用partition函数,返回pivot元素的正确位置,并使得pivot左侧的所有元素都小于它,右侧的所有元素都大于它
  38. int pi = partition(arr, low, high);
  39. // 递归地对pivot左侧的子数组进行快速排序
  40. sort_fun(arr, low, pi - 1);
  41. // 递归地对pivot右侧的子数组进行快速排序
  42. sort_fun(arr, pi + 1, high);
  43. }
  44. }
  45. void sort(vector<int> &v) {
  46. sort_fun(v, 0, v.size());
  47. }
  48. int main() {
  49. vector<int> v{10, 3, 4, 1, 60, 7};
  50. sort(v);
  51. cout << v << endl;
  52. }

归并排序

Article/Image/-1018504/1720096342148.jpg

  1. #include <iostream>
  2. #include <vector>
  3. #include <algorithm>
  4. using namespace std;
  5. vector<int> result;
  6. ostream &operator<<(ostream &ostream1, vector<int> &v) {
  7. auto it1 = v.begin(), it2 = v.end();
  8. while (it1 != it2) {
  9. ostream1 << *it1++ << ' ';
  10. }
  11. return ostream1;
  12. }
  13. void merge(vector<int> &arr, int low, int midIndex, int high) {
  14. // 准备两个指针 分别指向 左边有序区域和右边有序区域 这里我们将中间值分配给左边
  15. int l = low, r = midIndex + 1;
  16. // 准备存储新数据
  17. result.clear();
  18. while (l <= midIndex && r <= high) {
  19. // 获取到左边和右边的值 如果左边小就追加左边的到结果中,反之追加右边
  20. result.push_back(arr[l] > arr[r] ? arr[r++] : arr[l++]);
  21. }
  22. // 追加完毕 避免左边或右边有剩余
  23. while (l <= midIndex)
  24. result.push_back(arr[l++]);
  25. while (r <= high)
  26. result.push_back(arr[r++]);
  27. // 最后将结果写到 arr 里
  28. copy(result.begin(), result.end(), arr.begin() + low);
  29. }
  30. void sort_fun(vector<int> &arr, int low, int high) {
  31. // 计算出长度
  32. int le = high - low;
  33. if (le <= 0) {
  34. return;
  35. }
  36. // 首先我们需要找到中间元素
  37. int midIndex = low + ((high - low) >> 1);
  38. // 左边右边各排序 这里会不断递归 最后会出现很多小排序 里面应该是很多小排序合并好的大排序 左边和右边是两个有序的
  39. sort_fun(arr, low, midIndex);
  40. sort_fun(arr, midIndex + 1, high);
  41. // 合并
  42. merge(arr, low, midIndex, high);
  43. }
  44. void sort(vector<int> &v) {
  45. if (v.empty()) {
  46. return;
  47. }
  48. sort_fun(v, 0, ((int) v.size()) - 1);
  49. }
  50. int main() {
  51. vector<int> v{10, 3, 4, 1, 60, 7, -1};
  52. sort(v);
  53. cout << v << endl;
  54. }

查找操作

二分查找

  1. #include <iostream>
  2. #include <vector>
  3. using namespace std;
  4. int search(const vector<int>& arr, int target) {
  5. // 准备两个指针 代表 查找范围的索引区间
  6. int l = 0, r = ((int) arr.size()) - 1;
  7. // 开始进行迭代和循环 在循环中缩小区间
  8. while (l <= r){
  9. // 计算中间索引和中间数值
  10. int midIndex = l + ((r - l) >> 1), midValue = arr[midIndex];
  11. // 开始进行对比 决定要抛弃的区间
  12. if (target < midValue) {
  13. // 目标值比中间小,代表目标在左区间 舍弃右区间
  14. r = midIndex - 1;
  15. } else if (target > midValue){
  16. // 目标值比中间大 代表目录在右区间 舍弃左区间
  17. l = midIndex + 1;
  18. } else {
  19. // 这个情况代表 tar 和 基准值一样 找到索引了
  20. return midIndex;
  21. }
  22. }
  23. // 到这里代表没找到
  24. return -1;
  25. }
  26. int main() {
  27. vector<int> v{1, 2, 3, 4, 5, 6 ,7};
  28. cout << search(v, 6) << endl;
  29. cout << search(v, 4) << endl;
  30. cout << search(v, 2) << endl;
  31. cout << search(v, -2) << endl;
  32. }

操作记录
作者:zhao
操作时间:2024-07-04 16:29:54 星期四
事件描述备注:保存/发布
 中国 天津

想了解更多? 前往中心站点可以查看评论等数据~~

 回到顶部 前往作者主页 点击访问此文章的中心站页面