STL库看这一篇就够了:STL库总结

在这篇文章我们不介绍容器是怎样使用的,因为STL容器的使用还是比较简单的。我们着重讲一下容器的底层实现。同时我整理了一些文章,供参阅。

1.顺序容器

1.vector

底层是可以两倍动态扩容的数组 0->1->2->4...

常用的方法有:reserve /resize /size /empty /push_back  /pop_back /insert /erase等

2.deque:双端队列

底层是通过一小块内存map,map里面存储着指针,每个指针指向一个更大dequeue块,每个dequeque的大小一般为512B,由于dequeque是采取多个连续的内存块存储,而不是像vector一样采取一个连续的内存块,因此dequeue在头部或者尾部插入或删除元素的时候是不需要进行元素的移动的。

常用的方法有:push_back /pop_back /push_front  /pop_front /insert  /erase等

关于dequeque可以看下这一篇文章:https://blog.csdn.net/Lison_Zhu/article/details/80030711

3.list链表

底层是带头节点的双向链表。

_list_node的定义如下:

template<typename T,...>
struct __List_node{
    //...
    __list_node<T>* prev;
    __list_node<T>* next;
    T myval;
    //...
}

常用的方法有:push_back /pop_back /push_front  /pop_front /insert /erase/merge等.

关于STL::list可以参阅这篇文章:https://www.cnblogs.com/aiguona/p/7231609.html

2.关联容器

1.set和multiset、unordered_set和unordered_multiset

set和multiset一样,存储的是有序的元素,两者不同的一个允许重复,一个不允许重复,set和multiset的底层实现为红黑树。unordered_set和unordered_multiset存储的无序的元素,底层实现是hash_table.

2.map和multimap、unordered_和unordered_ultimap

map和set的区别是map存储的是键值对,而set存储的只是元素值。map和multimap的底层实现也是红黑树,unordered_和unordered_ultimap的底层实现是hash_table。

关于关联容器的知识点和操作可以参考下面这两篇博文:

https://blog.csdn.net/xiajun07061225/article/details/7459206

https://blog.csdn.net/qq_18539301/article/details/81780194

3.器适配器(没有自己的数据结构,因此没有迭代器)

1.stack

底层是deque

常用的方法有:

1.empty()  堆栈为空则返回真
2.pop()  移除栈顶元素
3.push()  在栈顶增加元素
4.size()  返回栈中元素数目
5.top()  返回栈顶元素

2.queue

底层是deque

常用的方法有:

1.back()  返回一个引用,指向最后一个元素
2.empty()  如果队列空则返回真
3.front()  返回第一个元素
4.pop()  删除第一个元素
5.push()  在末尾加入一个元素
6.size()  返回队列中元素的个数

3.priority_queue

底层是vector

priority_queue<int> maxHeap;  //大根堆
maxHeap.push(10);
maxHeap.pop();
maxHeap.top();
maxHeap.empty();
maxHeap.size();

//小根堆
priority_queue<int, vector<int>, greater<int>> minHeap;

用priority_queue可以实现top k 问题

srand((unsigned)time(NULL));

vector<uint>vec;
for (int i = 0; i < 2000000; ++i)
{
	vec.push_back(rand()+i);
		
}
priority_queue<uint> vec1;
priority_queue<uint,vector<uint>,greater<uint>> vec2;
	//求最小的
for (int i = 0; i < 10; ++i)
{
	vec1.push(vec[i]);
}
for (int i = 10; i < 2000000; ++i)
{
	if (vec[i] < vec1.top())
	{
		vec1.pop();
		vec1.push(vec[i]);
	}
}
for (int i = 0; i < 10; ++i)
{
	const int& iv = vec1.top();

	cout << iv << ends;
	vec1.pop();
}
cout << endl;
//海量数据问题:请在最短的时间内,找到所有整数中,最大/最小的10个元素,并且打印
//找top k大的用小根堆,  top k小的用大根堆
for (int i = 0; i < 10; ++i)
{
	vec2.push(vec[i]);
}
for (int i = 10; i < 2000000; ++i)
{
	if (vec[i] > vec2.top())
	{
		vec2.pop();
		vec2.push(vec[i]);
	}
}
for (int i = 0; i < 10; ++i)
{
	cout << vec2.top() << ends;
	vec2.pop();
}
	

解决查重和top k的复合问题

int main()
{
	srand(time(NULL));
	//查重复和top k 结合的问题
	vector<int> vec;
	for (int i = 0; i < 200000; ++i)
	{
		vec.push_back(rand());
	}
	//在这组数字中,找重复次数最大的前10个数并进行打印
	//无序容器+优先级队列
	//1.统计所有数字重复次数
	unordered_map<int, int> _map;
	for (int val : vec)
	{
		auto it = _map.find(val);
		if (it == _map.end())
		{
			_map.insert(make_pair(val, 1));
		}
		else
		{
			it->second++;
		}
	}
	struct Node
	{
		Node(int v, int c) :val(v), count(c)
		{}
		
		bool operator>( const Node &src) const
		{
			return count > src.count;

		}
		int val;
		int count;
	};
	priority_queue <Node,vector<Node>,greater<Node>> que;
	int k = 0;
	unordered_map<int, int>::iterator  it = _map.begin() ;
	for (pair<int, int> item : _map)
	{
		que.push(Node(item.first,item.second));
		++it;
		if (++k == 10)
		{
			break;
		}
	}
	//将k+1到末尾的元素和堆顶的元素进行比较
	while (it != _map.end())
	{
		if (it->second > que.top().count)
		{
			que.pop();
			que.push(Node(it->first,it->second));
		}
		++it;
	}

	for (int i = 0; i < 10; ++i)
	{
		cout << que.top().val << "重复" << que.top().count << "次" << endl;
		que.pop();
	}
	system("pause");
	return 0;
}

4.其他容器:STL::bitset

很明显bitset就是位图容器,相信大家对位图法都不陌生,位图法在大量元素求重复的问题中非常有用,依稀记得当初采取的位图法都是通过左移右移来完成的,那么现在可以使用bistset来替代了,bistset可以让程序员们像使用数组一样去使用类。

bitset继承自_Base_bitse。_Base_bitse包含了一个unsigned long的数组,一般地,一个unsigned long有32位,可以表示32个数,最低位的数最小,最高位的数最大。

关于bistset的底层详细介绍和使用方法,可以参考下面两篇文章。

https://blog.csdn.net/u012069890/article/details/59108840

https://blog.csdn.net/shudaqi2010/article/details/23406063

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 1
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值