C++ 排序算法

本文详细介绍了C++STL中的四个关键算法:sort用于排序,random_shuffle用于随机打乱元素顺序,merge可将两个已排序的序列合并,reverse则用于反转序列。sort和merge都涉及到比较操作,可以自定义比较函数。random_shuffle使用时间戳生成伪随机数。文章通过代码示例展示了这些算法的使用方法及其效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

🤔排序算法:

📖1.sort   对容器内元素进行排序
 
📖2.random_shuffle    洗牌  指定范围内的元素随机调整次序
 
📖3.merge   容器元素合并,并整合到另一个容器中
 
📖4.reverse    反转指定容器元素

🤔逐一介绍:

🙂1.sort    排序

📖在C++语言中,sort(排序)函数是STL(标准库)中的一个函数,它用于将一个数组或vector等STL容器中的元素进行排序。sort函数可以将元素以升序或降序的方式排序。sort函数的使用需要包含头文件<algorithm>。

void sort(RandomAccessIterator first, RandomAccessIterator last, Compare comp);

📖sort函数可以接受三个参数,第一个参数是排序的数组或STL容器的首地址,第二个参数是指定排序数据的大小,通常可以使用sizeof运算符来计算,第三个参数是一个函数指针,用于指定排序的规则,默认情况下,sort函数按照升序进行排序,而我们可以通过在第三个函数位引入不同的规则函数来确定排序条件。

📖第三个参数可以用我们之前介绍的关系仿函数代替,下面这个链接中介绍了仿函数

C++ 函数对象 详解_我是一盘牛肉的博客-CSDN博客

🔍代码示例:

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
void print(vector<int>d)
{
	for (auto a = d.begin(); a != d.end(); a++)
	{
		cout << *a<<"  ";
	}
	cout << endl;
}
int main()
{
	vector<int>d1;
	d1.push_back(20);
	d1.push_back(23);
	d1.push_back(10);
	d1.push_back(22);
	d1.push_back(34);
	d1.push_back(28);
	cout << "反转前";
	print(d1);
	cout << "反转后";
	sort(d1.begin(), d1.end(), less<int>());
	print(d1);

	
}

🔍运行结果:

🙂 2.random_shuffle  随机排序

📖在C++中,random_shuffle 是STL提供的一个函数,用于对一个序列或容器中的元素进行乱序排列,即将其中的元素随机打乱。它头文件为<algorithm>。

📖random_shuffle 函数不需要我们自己编写乱序算法,只需要将待打乱的序列或容器的首地址和尾地址传入函数即可。它的函数原型如下:

template <class RandomAccessIterator>
void random_shuffle(RandomAccessIterator first, RandomAccessIterator last);

📖其中,firstlast分别为待打乱的序列(或容器)的首尾元素的迭代器。

📖需要注意的是它也是伪随机,需要利用时间戳改变随机规则。

include<ctime>
strand((unsigned int)time(NULL));

关于时间戳的介绍,我们放在了这篇文章里:

C语言 rand函数_我是一盘牛肉的博客-CSDN博客

我们这里利用随机排序的特点实现一个比较好玩的排序:猴子排序

猴子排序(也常被称为猴子补丁或瞎子排序)是一种思路简单但并不实用的乱序算法。它没有太大的用处,仅仅作为一种娱乐性质的算法而被提及。

猴子排序的思路是,根据“猴子定理”来猜测正确的排序位置。该定理指出,如果无限次地随机打乱一个序列,那么该序列最终也会被排成有序列。

具体来说,猴子排序的流程如下 :

1. 随机打乱待排序的序列。
2. 判断序列是否已经排好序,如果是,算法结束;否则,继续第3步。
3. 再次随机打乱序列并回到第2步。

需要注意的是,猴子排序的时间复杂度是非常高的,尤其是在待排序的序列长度较长的情况下,它的时间复杂度接近于无穷大,因此在实际应用中不宜使用。

🔍代码运行:

#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

void print(vector<int> d)
{
    for (auto a = d.begin(); a != d.end(); a++)
    {
        cout << *a << "  ";
    }
    cout << endl;
}

bool operator==(vector<int> d1, vector<int> d2)
{
    auto a1 = d1.begin();
    auto a2 = d2.begin();
    int count = 0;
    int size = d1.size();
    while (a1 != d1.end())
    {
        if (*a1 != *a2)
        {
            return false;
        }
        a1++;
        a2++;
        count++;
    }
    return count == size;
}

int main()
{
    vector<int> d1;
    d1.push_back(20);
    d1.push_back(23);
    d1.push_back(10);
    d1.push_back(22);
    d1.push_back(34);
    d1.push_back(28);
    vector<int> d2;
    d2 = d1;
    sort(d2.begin(), d2.end());
    for (int i = 0; i < 1000; i++)
    {
        random_shuffle(d1.begin(), d1.end());
        print(d1);

        if (d1 == d2)
        {
            print(d1);
            return 0;
        }
    }
    return 0;
}

🔍运行结果:

我们通过不断的随机排序最终找到了符合要求的排序。

🙂3.merge  合并排序

📖在 C++ 的 STL 库中,merge 是一个用于让两个已经排好序的数组合并成一个有序数组的算法,它支持常规数组和 STL 容器。

📖merge 的函数原型为:

template<class InputIt1, class InputIt2, class OutputIt>
OutputIt merge(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, OutputIt d_first);

📖其中,参数 first1 和 last1 是第一个已排序区间的首迭代器和尾部后继迭代器,first2 和 last2 是第二个已排序区间的首迭代器和尾部后继迭代器,d_first 是新的有序序列起始位置的迭代器。

📖merge() 函数从两个已排序序列中取出较小的值并放入目标序列中,直到其中一个序列已经没有元素为止。如果两个序列中有相等的元素,则将第一个序列的元素放在前面。最后,merge() 返回值为新序列的最后一个后置迭代器。

🔍代码示例:

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
void ptint(int val)
{
	cout << val<<" ";
}
int main()
{
	vector<int>d1;
	for (int i = 0; i < 10; i++)
	{
		d1.push_back(i);
	}
	vector<int>d2;
	for (int i = 0; i < 10; i++)
	{
		d2.push_back(i);
	}
	cout << "合并前" << endl;
	cout << "d1   ";
	for_each(d1.begin(), d1.end(), ptint);
	cout << endl;
	cout << "d2   ";
	for_each(d2.begin(), d2.end(), ptint);
	vector<int>d3;
	//创建自定义变量并不会自动分配内存,需要我们自己主动分配
	d3.resize(20);
	cout << endl;
	cout << "合并到d3后";
	merge(d1.begin(), d1.end(), d2.begin(), d2.end(), d3.begin());
	for_each(d3.begin(), d3.end(), ptint);
}

🔍运行结果:

🙂 4.reverse  反转排序

📖在 C++ STL 中,reverse()是一种简单且常用的算法,用于将数组或容器中所有元素顺序颠倒,即实现序列的翻转。

📖reverse()的函数原型为:

template<class BidirIt>
void reverse(BidirIt first, BidirIt last);

📖 其中,first 和 last 分别表示需要翻转的区间的首迭代器和尾部后继迭代器。

      reverse进行的是原地反转,不需要占用多余的空间。

🔍代码示例:

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
void ptint(int val)
{
	cout << val<<" ";
}
int main()
{
	vector<int>d1;
	for (int i = 0; i < 10; i++)
	{
		d1.push_back(i);
	}
	vector<int>d2;
	for (int i = 0; i < 10; i++)
	{
		d2.push_back(i);
	}
	cout << "合并前" << endl;
	cout << "d1   ";
	for_each(d1.begin(), d1.end(), ptint);
	cout << endl;
	cout << "d2   ";
	for_each(d2.begin(), d2.end(), ptint);
	vector<int>d3;
	//创建自定义变量并不会自动分配内存,需要我们自己主动分配
	d3.resize(20);
	cout << endl;
	cout << "合并到d3后";
	merge(d1.begin(), d1.end(), d2.begin(), d2.end(), d3.begin());
	for_each(d3.begin(), d3.end(), ptint);
}

🔍运行结果:

 

🤔结束!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我是一盘牛肉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值