顺序容器与容器适配器

顺序容器

vector

vector底层是一个可以动态扩容的数组
提供的方法有

push_back() 尾部插入
pop_back() 尾部删除

insert() 插入一个元素
erase() 删除一个元素
begin() 返回第一个元素的迭代器
end() 返回最末元素的迭代器( )
swap() 交换两个Vector
resize() 改变Vector元素数量的大小
reserve() 设置Vector最小的元素容纳数量

#include <iostream>

using namespace std;

template<typename T>
class Vector
{
public:
	~Vector()
	{
		delete []mpVec;
	}
	// 按指定size进行构造,size个空间,没有元素
	Vector(int size = 0):mSize(size),mCur(0)
	{
		if(size != 0)
		{
			mpVec = new T[size];
		}
	}
	// 按指定size进行构造,添加size个元素,元素值是val
	Vector(int size, const T &val = T()):mSize(size),mCur(size)
	{
		mpVec = new T[size];
		for(int i = 0; i < size; i++)
		{
			mpVec[i] = val;
		}
	}
	// 按[first, last)区间的元素来构造Vector
	Vector(T *first, T *last)
	{
		mCur = 0;
		mpVec = new T[last-first];
		mSize = last-first;
		T *p = first;
		for(; p != last; p++)
		{
			mpVec[mCur++] = *p;
		}
	}
	// 从末尾添加元素
	void push_back(const T &val)
	{
		if(full())
		{
			resize();
		}
		mpVec[mCur++] = val;
	}
	// 从末尾删除元素
	void pop_back()
	{
		if(empty())
		{
			return ;
		}
		--mCur;
	}
	bool full()const
	{
		return mCur == mSize;
	}
	bool empty()const
	{
		return mCur == 0;
	}
	// 返回容器元素的个数
	int size()const
	{
		return mCur;
	}
	// Vector的迭代器
	class iterator
	{
	public:
		iterator(T *p):_iter(p){}
		bool operator != (const iterator &val)
		{
			return _iter != val._iter;
		}

		T& operator *()
		{
			return *_iter;
		}

		void operator++ ()
		{
			++_iter;
		}
	private:
		T *_iter;
	};
	iterator begin()
	{
		return iterator(mpVec);
	}
	iterator end()
	{
		return iterator(mpVec+mCur);
	}
	
private:
	T *mpVec;
	int mCur;
	int mSize;
	// 容器内存2倍扩容
	void resize()
	{
		if(mSize != 0)
		{
			T *newdata = new T[mSize*2];
			for(int i = 0; i < mCur; i++)
			{
				newdata[i] = mpVec[i];
			}
			delete []mpVec;
			mpVec = newdata;
			mSize *= 2;
		}
		else
		{
			mpVec = new T[1];
			mSize = 1;
		}
	}
};

list

list 链式容器
内部数据结构是一个双向链表,不考虑查找的情况下,插入和删除一个元素的时间复杂度都是O(1),查找的时间复杂度为O(n),我们在代码中看一下list 提供的各个方法

#include <iostream>
#include <list>

using namespace std;
int main()
{
	list<int> li;

	for(int i = 0; i < 10; i++)
	{
		//list 中 头插法的时间复杂度为O(1)
		li.push_front(i);
	}
	//如果采用push_back() 时间复杂度为O(n)
	li.push_back(10);

	//在进行两个list 合并的时候,将两个list 内的数据拷贝一份
	//然后放到新的list中的过程效率较低,如果合并后两个list 不再使用,
	//可以 将两个list中的节点摘下来放到新的list中,这样就少去了大量的
	//拷贝构造的过程,list 中提供了splice 方法
	list<int> li2;
	/*
	void splice( iterator pos, list &lst );
	void splice( iterator pos, list &lst, iterator del );
	void splice( iterator pos, list &lst, iterator start, iterator end );
	*/
	li2.splice(li2.begin(),li,li.begin(),li.end);

	/*
	merge()函数把自己和lst链表连接在一起,
	产生一个整齐排列的组合链表。如果指定compfunction,则将指定函数作为比较的依据。
	void merge( list &lst );
	void merge( list &lst, Comp compfunction );
	*/
	li2.merge(li);

	return 0;
}

其余方法与vector 这里不多做介绍

deque

deque的底层数据结构
在这里插入图片描述
first 与last 的初始位置在其中一个数组的中间位置,这样,不管在头部还是尾部的的插入与删除的时间复杂度都是O(1)
deque开始的数组的长度4096/sizeof(T)。
双端队列扩容方式,先扩容一维数组MAP_SIZE 扩容后的将现在的数组放在扩容后数组的中间,如下图所示
在这里插入图片描述
vector 与 deque 的insert 谁的效率高?
vector 内存是连续的,deque 内存是不连续的, insert的移动元素的过程连续的内存较快。所以vector 效率高

容器适配器

容器适配器的底层都是用的已知的容器,它没有自己的数据结构和迭代器

stack

底层通过一个deque容器实现
stack为什么不采用vector作为底层数据结构?
deque 的底层内存空间不连续,内存的空间利用率高。Vector 初始值为0,开始的开始时扩容的次数较大 deque开始的数组的长度4096/sizeof(T);所以开始时deque 的效率较高
提供的方法
empty() 堆栈为空则返回真
pop() 移除栈顶元素
push() 在栈顶增加元素
size() 返回栈中元素数目
top() 返回栈顶元素

queue

queue的底层容器的实现也是deque
queue不采用vector作为底层结构的原因?
queue的出队操作若采用vector的删除第一个元素的话时间复杂度为O(n),采用deque 的时间复杂度为O(1),
queue头文件中可以看出queue 的底层默认使用的容器

template<class _Ty,
	class _Container = deque<_Ty> >

常用的方法有:
back() 返回最后一个元素
empty() 如果队列空则返回真
front() 返回第一个元素
pop() 删除第一个元素
push() 在末尾加入一个元素
size() 返回队列中元素的个数

priority_queue

优先级队列,先来看一下他的头文件

template<class _Ty,
	class _Container = vector<_Ty>,
	class _Pr = less<typename _Container::value_type> >

Priority_queue底层采用的是vector数据结构,默认情况下,priority_queue内部采用大根堆存储,构建根堆的过程使用了大量的下标访问,vector 数据结构使用是最方便使用下标访问的。
优先级队列在容器的内部并不是有序的,而是通过大根堆(小根堆),在用户访问数据的时候,显示出有序的状态,因为每出队一个(入队)一个元素,都会将优先级最高的放到堆顶,这样,我们一个个访问的时候看到的数据就是有序的。
priority_queue的第三个参数是函数对象,所谓函数对象是指一个类中,提供小括号运算符重载函数,这样的类构造的一个对象

class comp
{
public:
	bool operator()(int a,int b)
	{
		return a > b;
	}
};

这样一个类构成的对象就是函数对象

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值