🎩 欢迎来到技术探索的奇幻世界👨💻
📜 个人主页:@一伦明悦-CSDN博客
✍🏻 作者简介: C++软件开发、Python机器学习爱好者
🗣️ 互动与支持:💬评论 👍🏻点赞 📂收藏 👀关注+
如果文章有所帮助,欢迎留下您宝贵的评论,
点赞加收藏支持我,点击关注,一起进步!
前言
STL(Standard Template Library)是C++标准库的一部分,提供了丰富的数据结构和算法,用于处理数据和实现常见的计算任务。STL中的算法分为几类,包括遍历算法、修改算法、排序算法、查找算法、数值算法等,每类算法都有其特定的应用场景和功能。
正文
01-排序算法之sort用法
sort
算法详解语法
template <class RandomAccessIterator> void sort (RandomAccessIterator first, RandomAccessIterator last); template <class RandomAccessIterator, class Compare> void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp);
RandomAccessIterator
:表示随机访问迭代器类型,用于指定排序范围。first
:表示排序范围的起始位置。last
:表示排序范围的结束位置,不包含在范围内。comp
:可选参数,用于指定排序的比较函数对象。参数
first
:排序范围的起始位置。last
:排序范围的结束位置,不包含在范围内。comp
:可选参数,用于指定排序的比较函数对象。如果不提供此参数,默认使用<
运算符进行比较。功能
sort
算法用于对范围[first, last)
内的元素进行排序,默认以升序方式排列。返回值
sort
函数没有返回值,直接在原始范围上进行排序操作。示例
以下是使用
sort
算法对整数向量进行排序的示例:#include <iostream> #include <vector> #include <algorithm> // 包含 sort 函数 int main() { std::vector<int> numbers = {5, 2, 8, 3, 1, 4}; // 使用 sort 对向量进行升序排序 std::sort(numbers.begin(), numbers.end()); std::cout << "升序排序后的结果为: "; for (int num : numbers) { std::cout << num << " "; } std::cout << std::endl; return 0; }
输出结果将是 “升序排序后的结果为: 1 2 3 4 5 8”。在这个例子中,
sort
函数对向量numbers
中的元素进行了升序排序,并输出排序后的结果。注意事项
sort
算法默认使用<
运算符进行比较,可通过提供自定义的比较函数对象comp
进行特定排序。- 对于自定义数据类型,确保比较函数对象
comp
或重载<
运算符,以确保算法能正确比较对象。通过
sort
算法,可以方便地对容器内的元素进行排序操作,适用于各种数据结构和排序需求。
这段代码演示了C++中对vector容器内元素进行排序的基本用法,并展示了如何使用自定义的比较函数来实现不同的排序顺序。
-
包含头文件和定义函数
#include <algorithm>
:包含了标准库中的排序算法sort
和greater
。#include <vector>
:包含了使用的容器vector
。void myPrint(int val)
:定义了一个简单的函数myPrint
,用于输出整数值。
-
定义测试函数
test01()
- 创建了一个整数类型的 vector
v
,并向其中添加了几个整数元素。 - 使用
sort(v.begin(), v.end())
对 vectorv
进行升序排序(默认情况下)。 - 使用
for_each(v.begin(), v.end(), myPrint)
遍历输出排序后的元素,函数myPrint
负责打印每个元素。 - 执行
cout << endl;
输出换行。
- 创建了一个整数类型的 vector
-
反向排序示例
- 使用
sort(v.begin(), v.end(), greater<int>())
对 vectorv
进行降序排序。greater<int>()
是一个函数对象,表示按照大于号 (>
) 的方式进行比较。 - 再次使用
for_each(v.begin(), v.end(), myPrint)
输出降序排序后的元素。 - 执行
cout << endl;
输出换行。
- 使用
-
主函数
main()
- 调用
test01()
函数来执行上述排序和输出操作。 - 最后使用
system("pause");
在控制台暂停程序的执行,等待用户按下任意键结束程序。
- 调用
这段代码通过展示 sort
函数的基本使用,演示了如何实现升序和降序排序,以及如何自定义比较函数来满足不同的排序需求。
#include <algorithm>
#include <vector>
void myPrint(int val)
{
cout << val << " ";
}
void test01() {
vector<int> v;
v.push_back(10);
v.push_back(30);
v.push_back(50);
v.push_back(20);
v.push_back(40);
//sort默认从小到大排序
sort(v.begin(), v.end());
for_each(v.begin(), v.end(), myPrint);
cout << endl;
//从大到小排序
sort(v.begin(), v.end(), greater<int>());
for_each(v.begin(), v.end(), myPrint);
cout << endl;
}
int main() {
test01();
system("pause");
return 0;
}
02-排序算法之random_shuffle用法
random_shuffle
算法详解语法
template <class RandomAccessIterator> void random_shuffle (RandomAccessIterator first, RandomAccessIterator last); template <class RandomAccessIterator, class RandomNumberGenerator> void random_shuffle (RandomAccessIterator first, RandomAccessIterator last, RandomNumberGenerator&& rand);
RandomAccessIterator
:表示随机访问迭代器类型,用于指定要打乱的范围。first
:表示打乱范围的起始位置。last
:表示打乱范围的结束位置,不包含在范围内。rand
:可选参数,表示用于生成随机数的随机数生成器对象。参数
first
:打乱范围的起始位置。last
:打乱范围的结束位置,不包含在范围内。rand
:可选参数,用于指定随机数生成器对象。如果不提供此参数,默认使用std::default_random_engine
生成随机数。功能
random_shuffle
算法用于对范围[first, last)
内的元素进行随机打乱。返回值
random_shuffle
函数没有返回值,直接在原始范围上进行元素打乱操作。示例
以下是使用
random_shuffle
算法对整数向量进行随机打乱的示例:#include <iostream> #include <vector> #include <algorithm> // 包含 random_shuffle 函数 #include <random> // 包含随机数生成器 int main() { std::vector<int> numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; // 使用 random_shuffle 对向量进行随机打乱 std::random_shuffle(numbers.begin(), numbers.end()); std::cout << "随机打乱后的结果为: "; for (int num : numbers) { std::cout << num << " "; } std::cout << std::endl; return 0; }
输出结果将是随机的顺序,例如 “随机打乱后的结果为: 5 7 1 4 3 2 8 9 10 6”。在这个例子中,
random_shuffle
函数对向量numbers
中的元素进行了随机打乱,并输出打乱后的结果。注意事项
random_shuffle
算法使用默认的随机数生成器来生成随机数。如果需要定制化的随机数生成器,可以提供自定义的随机数生成器对象。- 对于自定义数据类型,确保实现了迭代器的随机访问能力,以便算法能正确操作范围内的元素。
通过
random_shuffle
算法,可以方便地对容器内的元素进行随机打乱操作,适用于各种需要随机顺序的场景。
这段代码展示了如何使用 C++ 的 random_shuffle
算法对 vector 容器内的元素进行随机打乱,并输出打乱后的结果。
-
包含头文件和定义类
#include <algorithm>
:包含了标准库中的random_shuffle
算法。#include <vector>
:包含了使用的容器vector
。#include <ctime>
:包含了time
函数,用于获取当前时间。#include <cstdlib>
:包含了srand
和rand
函数,用于设置和获取随机数种子。
-
定义类
myPrint
class myPrint
:定义了一个仿函数 (function object),其中重载了operator()
,用于输出整数值。
-
定义测试函数
test01()
srand((unsigned int)time(NULL));
:通过调用srand
函数设置随机数种子,使用当前时间作为种子,确保每次运行得到不同的随机结果。- 创建了一个整数类型的 vector
v
,并使用for
循环向其中添加了整数元素 0 到 9。 - 使用
for_each(v.begin(), v.end(), myPrint())
遍历输出 vector 中的元素,函数对象myPrint
负责打印每个元素。 - 执行
cout << endl;
输出换行。
-
随机打乱示例
- 使用
random_shuffle(v.begin(), v.end())
对 vectorv
中的元素进行随机打乱。 - 再次使用
for_each(v.begin(), v.end(), myPrint())
输出打乱后的元素。 - 执行
cout << endl;
输出换行。
- 使用
-
主函数
main()
- 调用
test01()
函数来执行上述随机打乱和输出操作。 - 使用
system("pause");
在控制台暂停程序的执行,等待用户按下任意键结束程序。
- 调用
这段代码通过调用 random_shuffle
函数实现了对 vector 容器内元素的随机打乱,展示了如何利用随机数种子确保每次打乱结果的随机性。
#include <algorithm>
#include <vector>
#include <ctime>
class myPrint
{
public:
void operator()(int val)
{
cout << val << " ";
}
};
void test01()
{
srand((unsigned int)time(NULL));
vector<int> v;
for (int i = 0; i < 10; i++)
{
v.push_back(i);
}
for_each(v.begin(), v.end(), myPrint());
cout << endl;
//打乱顺序
random_shuffle(v.begin(), v.end());
for_each(v.begin(), v.end(), myPrint());
cout << endl;
}
int main() {
test01();
system("pause");
return 0;
}
03-排序算法之merge用法
merge
算法详解语法
template <class InputIterator1, class InputIterator2, class OutputIterator> OutputIterator merge (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result);
InputIterator1
:表示第一个有序序列的迭代器类型。InputIterator2
:表示第二个有序序列的迭代器类型。OutputIterator
:表示目标序列的迭代器类型。参数
first1
:第一个有序序列的起始位置。last1
:第一个有序序列的结束位置(不包含在范围内)。first2
:第二个有序序列的起始位置。last2
:第二个有序序列的结束位置(不包含在范围内)。result
:目标序列的起始位置,用于存储合并后的有序序列。功能
merge
算法用于将两个已排序的序列合并为一个新的有序序列,并存储到目标序列中。返回值
merge
函数返回一个迭代器,指向目标序列中的末尾位置(合并后序列的下一个位置)。示例
以下是使用
merge
算法将两个已排序的向量合并为一个新的有序向量的示例:#include <iostream> #include <vector> #include <algorithm> // 包含 merge 函数 int main() { std::vector<int> v1 = {1, 3, 5, 7, 9}; std::vector<int> v2 = {2, 4, 6, 8, 10}; std::vector<int> merged(v1.size() + v2.size()); // 使用 merge 将 v1 和 v2 合并为 merged std::merge(v1.begin(), v1.end(), v2.begin(), v2.end(), merged.begin()); std::cout << "合并后的有序序列为: "; for (int num : merged) { std::cout << num << " "; } std::cout << std::endl; return 0; }
输出结果将是合并后的有序序列,例如 “合并后的有序序列为: 1 2 3 4 5 6 7 8 9 10”。在这个例子中,
merge
函数将两个已排序的向量v1
和v2
合并为一个新的有序向量merged
。注意事项
merge
算法要求输入序列必须是已排序的,否则结果将不符合预期。- 如果输入序列有重复元素,
merge
算法会保持这些重复元素的顺序。- 目标序列
result
的长度必须足够大,能够容纳合并后的所有元素,否则可能导致未定义行为。通过
merge
算法,可以方便地将两个已排序的序列合并为一个新的有序序列,适用于各种需要合并排序结果的场景。
这段代码展示了如何使用 C++ 的 merge
算法将两个已排序的 vector
合并到一个新的目标 vector
中,并通过自定义的 myPrint
函数对象输出合并后的结果。
代码解释
-
包含头文件和定义类
#include <algorithm> // 包含 merge 算法 #include <vector> #include <iostream> // 包含 cout 和 endl using namespace std; // 使用标准命名空间
#include <algorithm>
:包含了标准库中的merge
算法。#include <vector>
:包含了使用的容器vector
。#include <iostream>
:用于标准输出cout
和换行endl
。using namespace std;
:使用标准库的命名空间,避免每次使用标准库中的元素时都需要加上std::
前缀。
-
定义类
myPrint
class myPrint { public: void operator()(int val) { cout << val << " "; } };
myPrint
类是一个函数对象,重载了operator()
,用于输出整数值val
,并在每个值后面添加空格。
-
定义测试函数
test01()
void test01() { vector<int> v1; vector<int> v2; // 向 v1 和 v2 中添加元素 for (int i = 0; i < 10; i++) { v1.push_back(i); v2.push_back(i + 1); } vector<int> vtarget; // 目标容器 vtarget 需要提前开辟空间 vtarget.resize(v1.size() + v2.size()); // 合并两个有序序列 v1 和 v2 到 vtarget 中 merge(v1.begin(), v1.end(), v2.begin(), v2.end(), vtarget.begin()); // 使用 for_each 和 myPrint 输出合并后的结果 for_each(vtarget.begin(), vtarget.end(), myPrint()); cout << endl; }
- 创建了两个
vector
容器v1
和v2
,分别存储整数序列{0, 1, 2, ..., 9}
和{1, 2, 3, ..., 10}
。 - 创建了一个目标容器
vtarget
,使用resize
函数提前为其分配了足够的空间,以便存储合并后的结果。 - 调用
merge
函数,将v1
和v2
中的元素合并到vtarget
中。 - 使用
for_each
算法遍历vtarget
,并利用myPrint
函数对象输出每个元素。
- 创建了两个
-
主函数
main()
int main() { test01(); system("pause"); return 0; }
- 在
main
函数中调用test01()
来执行上述合并和输出操作。 - 使用
system("pause")
让程序在控制台暂停,等待用户按任意键结束程序的执行。
- 在
总结
这段代码展示了如何利用 merge
算法将两个已排序的 vector
合并成一个新的有序 vector
,并通过自定义的函数对象 myPrint
输出合并后的结果。使用 resize
来提前分配空间,确保目标容器能够容纳所有合并后的元素,是 merge
算法使用的必要步骤之一。
#include <algorithm>
#include <vector>
class myPrint
{
public:
void operator()(int val)
{
cout << val << " ";
}
};
void test01()
{
vector<int> v1;
vector<int> v2;
for (int i = 0; i < 10; i++)
{
v1.push_back(i);
v2.push_back(i + 1);
}
vector<int> vtarget;
//目标容器需要提前开辟空间
vtarget.resize(v1.size() + v2.size());
//合并 需要两个有序序列
merge(v1.begin(), v1.end(), v2.begin(), v2.end(), vtarget.begin());
for_each(vtarget.begin(), vtarget.end(), myPrint());
cout << endl;
}
int main() {
test01();
system("pause");
return 0;
}
04-排序算法之reverse用法
排序算法之reverse用法详细解释一下
reverse
算法详解语法
template <class BidirectionalIterator> void reverse (BidirectionalIterator first, BidirectionalIterator last);
BidirectionalIterator
:表示一个能够向前和向后遍历的迭代器类型。参数
first
:要反转的序列的起始位置。last
:要反转的序列的结束位置(不包含在范围内)。功能
reverse
算法用于将指定范围内的元素顺序完全反转。示例
以下是使用
reverse
算法反转一个vector
的示例:#include <iostream> #include <vector> #include <algorithm> // 包含 reverse 函数 int main() { std::vector<int> v = {1, 2, 3, 4, 5}; // 使用 reverse 将 vector 反转 std::reverse(v.begin(), v.end()); std::cout << "反转后的 vector: "; for (int num : v) { std::cout << num << " "; } std::cout << std::endl; return 0; }
输出结果将是反转后的 vector,例如 “反转后的 vector: 5 4 3 2 1”。在这个例子中,
reverse
函数将v
中的元素顺序完全反转。注意事项
reverse
算法会直接修改原始序列,而不是返回新的序列。- 序列中的元素顺序完全反转,即第一个元素变成最后一个,最后一个变成第一个,依此类推。
- 如果
first == last
,或者序列中只有一个元素,则不会进行任何操作。通过
reverse
算法,可以方便地对容器或者数组中的元素顺序进行反转操作,适用于各种需要逆序处理的场景。
这段代码展示了如何使用 C++ 标准库中的 reverse
算法来反转一个 vector
中的元素,并通过自定义的 myPrint
函数对象输出反转前后的结果。
-
包含头文件和定义类
#include <algorithm> // 包含 reverse 算法 #include <vector> #include <iostream> // 包含 cout 和 endl using namespace std; // 使用标准命名空间
#include <algorithm>
:包含了标准库中的reverse
算法。#include <vector>
:包含了使用的容器vector
。#include <iostream>
:用于标准输出cout
和换行endl
。using namespace std;
:使用标准库的命名空间,避免每次使用标准库中的元素时都需要加上std::
前缀。
-
定义类
myPrint
class myPrint { public: void operator()(int val) { cout << val << " "; } };
myPrint
类是一个函数对象,重载了operator()
,用于输出整数值val
,并在每个值后面添加空格。
-
定义测试函数
test01()
void test01() { vector<int> v = {10, 30, 50, 20, 40}; cout << "反转前: " << endl; for_each(v.begin(), v.end(), myPrint()); cout << endl; // 使用 reverse 函数反转 vector v 中的元素 reverse(v.begin(), v.end()); cout << "反转后: " << endl; for_each(v.begin(), v.end(), myPrint()); cout << endl; }
-
创建了一个
vector
容器v
,并向其中添加了整数元素{10, 30, 50, 20, 40}
。 -
使用
for_each
算法和自定义的myPrint
函数对象输出vector
中的元素,展示了反转前的顺序。 -
调用
reverse(v.begin(), v.end())
将vector v
中的元素顺序完全反转。 -
再次使用
for_each
和myPrint
输出反转后的vector
元素顺序。
-
-
主函数
main()
int main() { test01(); system("pause"); return 0; }
- 在
main
函数中调用test01()
来执行上述反转和输出操作。 - 使用
system("pause")
让程序在控制台暂停,等待用户按任意键结束程序的执行。
- 在
总结
这段代码演示了如何使用 C++ 标准库的 reverse
算法来反转 vector
容器中的元素。通过 reverse
函数可以快速、方便地修改容器中元素的顺序,适用于需要倒序处理数据的各种场景。
#include <algorithm>
#include <vector>
class myPrint
{
public:
void operator()(int val)
{
cout << val << " ";
}
};
void test01()
{
vector<int> v;
v.push_back(10);
v.push_back(30);
v.push_back(50);
v.push_back(20);
v.push_back(40);
cout << "反转前: " << endl;
for_each(v.begin(), v.end(), myPrint());
cout << endl;
cout << "反转后: " << endl;
reverse(v.begin(), v.end());
for_each(v.begin(), v.end(), myPrint());
cout << endl;
}
int main() {
test01();
system("pause");
return 0;
}
总结
STL(Standard Template Library)提供了多种排序算法,每种算法都有其特定的优势和适用场景。