STL中常见容器排序接口详解

一、sort算法

面试题:sort算法使用的是什么排序算法?稳定吗?

如果回答是快速排序,答案不完整,而且还会引来一下问题:

  1. 数据量大和数据量小都适合用快速排序吗?
  2. 快速排序的时间复杂度不是稳定的nlogn,最坏情况会变成n^2,怎么解决复杂度恶化问题?
  3. 快速排序递归实现时,怎么解决递归层次过深的问题?
  4. 递归过深会引发什么问题?
  5. 怎么控制递归深度?如果达到递归深度了还没排完序怎么办?

快速排序适合场景:数据越无序并且数据量越大,越能体现快速排序,而且如果数据是接近有序,快速排序会退化为冒泡排序。

问题解决:如果数据量小,那么sort怎么应对?考虑到直接插入排序主要适用于数据量小和数据接近有序,所以sort算法内部除了快速排序,还嵌套了直接插入排序。

另外,数据量特别大,因为快速排序是递归版本,所以采用堆排序,防止递归路径过深,导致栈溢出。

综上所述,sort算法内部包括快速排序,直接插入排序和堆排序。执行步骤:先对数据分段,如果数据量过大,会调用堆排序。如果数据量小,会调用直接插入排序。并且sort排序是不稳定的,stable_sort是1稳定的排序。

sort函数内部默认是排升序,如下接口:

bool cmp(const int &left, const int &right)
{
	return left > right;//此处是大于号
}
int main()
{
	vector<int> v{ 3, 2, 5, 7, 1, 2, 9, 0, 4 };
	sort(v.begin(), v.end());//默认升序
	for (auto &e : v)
		cout << e << " ";
	cout << endl;
	sort(v.begin(), v.end(), cmp);//自定义比较方式
	for (auto &e : v)
		cout << e << " ";
	cout << endl;
	return 0;
}

技巧:如果不知道降序,可以先排升序,然后reverse翻转。

二、list中sort

sort算法只能排序列式容器,所以list内部自己实现了sort排序。 

struct cmp
{
	bool operator()(const int &left, const int &right)
	{
		return left > right;//此处是大于
	}
};

int main()
{
	list<int> l{ 1, 2, 3, 6, 4, 2, 9, 9, 6, 2, 3, 0, 1 };
	l.sort();//默认升序
	for (auto&e : l)
		cout << e << " ";
	cout << endl;

	l.sort(cmp());//调用自定义结构体实现降序,也可以reverse
	for (auto&e : l)
		cout << e << " ";
	cout << endl;
	return 0;
}

三、priority_queue

优先级队列内部实现是由vector和堆算法。堆的定义已经决定一系列关键码存储在数组当中,所以优先级队列底层容器采用vector。所以优先级队列默认实现大堆。我们需要调整为小堆,方法如下:

#include<functional>
struct cmp
{
	bool operator()(const int& left, const int& right)
	{
		return left > right;//优先级队列大堆默认是小于,所以修改为大于
	}
};
int main()
{
	vector<int> v{ 2, 4, 1, 2, 7, 6, 9, 0 };
	priority_queue<int> q(v.begin(), v.end());//默认小堆
	//调整小堆方式
	//方法一:greater,需要包含头文件#include<functional>
	priority_queue<int, vector<int>, greater<int>> q1(v.begin(), v.end());
	//方法二:仿函数:重载()
	priority_queue<int, vector<int>, cmp> q2(v.begin(), v.end());

	return 0;
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
C++ STL(Standard Template Library)是C++标准库的一个重要组成部分,提供了一组数据结构和算法的模板类,可以大大简化C++程序的开发过程。STL包含了多个容器类,每个容器类都有其特定的特性和用途。 STL容器类主要分为序列容器和关联容器两大类。序列容器包括vector、list、deque和array,它们按照元素在容器的位置进行存储和访问。关联容器包括set、multiset、map、multimap和unordered系列容器,它们按照键值进行存储和访问。 序列容器具有以下特性: 1. 动态大小:序列容器可以根据需要动态调整大小,可以在任意位置插入和删除元素。 2. 快速随机访问:序列容器的元素可以通过索引快速访问,时间复杂度为O(1)。 3. 按顺序存储:序列容器的元素按照插入的顺序存储,并保持元素的相对位置不变。 4. 支持迭代器:序列容器提供了迭代器,可以通过迭代器遍历容器的元素。 关联容器具有以下特性: 1. 自动排序:关联容器的元素按照键值自动排序,并且可以根据自定义的比较函数进行排序。 2. 快速查找:关联容器支持快速的查找操作,时间复杂度为O(log n)。 3. 不允许重复键值:set和map容器的键值是唯一的,而multiset和multimap容器允许重复的键值。 4. 无序容器:unordered系列容器是C++11引入的,它们使用哈希函数来存储和访问元素,查找操作的平均时间复杂度为O(1)。 总而言之,C++ STL提供了丰富的容器类,每个容器类都有其独特的特性和适用场景,可以根据具体需求选择合适的容器来存储和操作数据。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [C++——STL容器](https://blog.csdn.net/JAN6055/article/details/122758690)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [C++的STL容器详解](https://blog.csdn.net/Jinyizhi2233/article/details/131640448)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

weixin_41318405

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

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

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

打赏作者

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

抵扣说明:

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

余额充值