C++复习笔记15

stack--容器适配器

1. stack 是一种容器适配器,专门用在具有后进先出操作的上下文环境中,其删除只能从容器的一端进行元素的插入与提取操作。
2. stack 是作为容器适配器被实现的,容器适配器即是对特定类封装作为其底层的容器,并提供一组特定的成员函数来访问其元素,将特定类作为其底层的,元素特定容器的尾部 ( 即栈顶 ) 被压入和弹出。
3. stack 的底层容器可以是任何标准的容器类模板或者一些其他特定的容器类,这些容器类应该支持以下操作: empty :判空操作 back :获取尾部元素操作 push_back :尾部插入元素操作
pop_back :尾部删除元素操作。
4. 标准容器 vector deque list 均符合这些需求,默认情况下,如果没有为 stack 指定特定的底层容器, 默认情况下使用 deque

注意容器适配器本身是没有迭代器的,所以也不支持C11中的基于范围的for循环。

stack容器接口测试:

#include<iostream>
#include<stack>
using namespace std;

void test01()
{
	stack<int> st;
	for (int i = 0; i < 10; ++i)
		st.push(i);

	cout << st.size() << endl;

	//for (auto& e : st)//栈没有办法通过迭代器访问
	//{
	//	cout << e << endl;
	//}

	//stack<int>::iterator;//stack是容器适配器,不包含迭代器,所以不支持c11基于范围的for循环

	while (!st.empty())
	{
		cout << st.top() << " ";
		st.pop();
	}
	cout << endl;

	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	for (const auto& e : arr)//内置类型底层指针可以充当迭代器所以,所以可以使用基于范围的for循环
	{
		cout << e << " ";
	}
	cout << endl;
}

void main()
{
	test01();
	system("pause");
}

stack模拟实现

#include<iostream>
#include<list>
#include<vector>
#include<assert.h>
#include<deque>
using namespace std;

namespace hym
{
	template<class T,class cont=deque<T>>//默认的类型参数-底层适配器是双端队列
	class stack
	{
	public:
		stack()
		{
			/*capacity = STACK_DEFAULT_SIZE;
			tp = 0;
			base = new T[capacity];*/
		}

		size_t size() const
		{//return tp;
			return _C.size();
		}

		bool empty() const 
		{//return tp == 0;
			return _C.empty();
		}

	    T& top()  
		{
			/*assert(tp != 0);
			return base[tp - 1];*/
			return _C.back();
		}

	    const T& top() const
		{
			/*assert(tp != 0);
			return base[tp - 1];*/
			return _C.back();
		}

		void push(const T& x)
		{
			//if (tp >= capacity)
			//{
			//	//扩容;
			//}
			//base[tp] = x;
			//tp++;
			_C.push_back(x);
		}

		void pop()
		{
			/*assert(base != NULL);
			tp--;*/
			_C.pop_back();
		}

		~stack()
		{
			/*delete[] base;
			capacity = 0;
			tp = 0;*/
		}


	private:
		/*enum {STACK_DEFAULT_SIZE=8};
		T* base;
		size_t capacity;
		size_t tp;*///原生态写法
		//list<T> _C;
		cont _C;
	};

 queue-容器适配器

队列是一种容器适配器,专门用于在 FIFO 上下文 ( 先进先出 ) 中操作,其中从容器一端插入元素,另一端提取元素。
2. 队列作为容器适配器实现,容器适配器即将特定容器类封装作为其底层容器类, queue 提供一组特定的 成员函数来访问其元素。元素从队尾入队列,从队头出队列。
3. 底层容器可以是标准容器类模板之一,也可以是其他专门设计的容器类。该底层容器应至少支持以下操作 : empty :检测队列是否为空 size :返回队列中有效元素的个数 front :返回队头元素的引用 back :返回队尾元素的引用 push_back :在队列尾部入队列 pop_front :在队列头部出队列
4. 标准容器类 deque list 满足了这些要求。默认情况下,如果没有为 queue 实例化指定容器类,则使用标 准容器 deque

 

queue接口测试

队列不包含迭代器,所以也就不能使用基于范围的for循环。

#include<iostream>
#include<stack>
#include<queue>
using namespace std;

void test01()
{
	queue<int> st;
	for (int i = 0; i < 10; ++i)
		st.push(i);

	cout << st.size() << endl;

	//for (auto& e : st)//队列没有办法通过迭代器访问
	//{
	//	cout << e << endl;
	//}

	//queue<int>::iterator;//queue是容器适配器,不包含迭代器,所以不支持c11基于范围的for循环

	while (!st.empty())
	{
		cout << st.front() << " ";//注意队列没有top只有front
		st.pop();
	}
	cout << endl;

	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	for (const auto& e : arr)//内置类型底层指针可以充当迭代器所以,所以可以使用基于范围的for循环
	{
		cout << e << " ";
	}
	cout << endl;
}

void main()
{
	test01();
	system("pause");
}

 queue的模拟实现:stl的注意vector没有头删所以不容易适配queue,但是vector可以适配stack

 template<typename T, typename con=deque<T>>
	class queue
	{
	public:
		queue() {}
		~queue(){}
		
		size_t size() const
		{//return tp;
			return _C.size();
		}

		bool empty() const
		{//return tp == 0;
			return _C.empty();
		}

		T& front()
		{
			return _C.front();
		}

		T& back()
		{
			return _C.back();
		}

		void push(const T& x)
		{
			_C.push_back(x);
		}

		void pop()
		{
			_C.pop_front();
		}

	private:
		con _C;
	};
}

void test01()
{
	//hym::stack<int,vector<int>> st;//可以指定配接到vector容器
	hym::stack<int> st;//使用默认的双端队列
	for (int i = 0; i < 10; ++i)
		st.push(i);

	cout << st.size() << endl;

	//for (auto& e : st)//栈没有办法通过迭代器访问
	//{
	//	cout << e << endl;
	//}

	//stack<int>::iterator;//stack是容器适配器,不包含迭代器,所以不支持c11基于范围的for循环

	while (!st.empty())
	{
		cout << st.top() << " ";
		st.pop();
	}
	cout << endl;

	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	for (const auto& e : arr)//内置类型底层指针可以充当迭代器所以,所以可以使用基于范围的for循环
	{
		cout << e << " ";
	}
	cout << endl;
}

void test02()
{
	hym::queue<int,list<int>>q;
	q.push(1);
	q.push(2);
	q.push(3);
	q.pop();//vector没有头删,不能作为底层适配器
	cout << q.front() << endl;
	cout << q.back() << endl;
}

void main()
{
	test02();
	system("pause");
}

容器适配器:

       适配器是一种设计模式(设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结)该种模式是将一个类的接口转换成客户希望的另外一个接口

虽然 stack queue 中也可以存放元素,但在 STL 中并没有将其划分在容器的行列,而是将其称为 容器适配器 ,这是因为 stack 和队列只是对其他容器的接口进行了包装, STL stack queue 默认使用 deque
       deque( 双端队列 ) :是一种双开口的 " 连续 " 空间的数据结构 ,双开口的含义是:可以在头尾两端进行插入和删除操作,且时间复杂度为 O(1) ,与 vector 比较,头插效率高,不需要搬移元素;与 list 比较,空间利用率比 较高。
      
       deque 并不是真正连续的空间,而是由一段段连续的小空间拼接而成的,实际 deque 类似于一个动态的二维
数组 ,其底层结构如下图所示:

      

        双端队列底层是一段假象的连续空间,实际是分段连续的,为了维护其 整体连续 以及随机访问的假象,落在了 deque 的迭代器身上, 因此 deque 的迭代器设计就比较复杂。
deque容器的缺点:
        与 vector 比较 deque 的优势是:头部插入和删除时, 不需要搬移元素,效率特别高 ,而且在 扩容时,也不需要搬移大量的元素 ,因此其效率是必 vector 高的。 list 比较 ,其底层是连续空间, 空间利用率比较高 ,不需要存储额外字段。
      但是, deque 有一个致命缺陷:不适合遍历,因为在遍历时, deque 的迭代器要频繁的去检测其是否移动到 某段小空间的边界,导致效率低下 ,而序列式场景中,可能需要经常遍历,因此 在实际中,需要线性结构 时,大多数情况下优先考虑 vector list deque 的应用并不多,而 目前能看到的一个应用就是, STL 用其作 stack queue 的底层数据结构。
为什么使用deque作为stack和queue的底层默认容器
        stack 是一种后进先出的特殊线性数据结构,因此只要具有 push_back() pop_back() 操作的线性结构,都可以作为 stack 的底层容器,比如 vector list 都可以; queue 是先进先出的特殊线性数据结构,只要具有 push_back pop_front 操作的线性结构,都可以作为 queue 的底层容器,比如 list 。但是 STL 中对 stack queue 默认选择 deque 作为其底层容器,主要是因为:
        1. stack queue 不需要遍历 ( 因此 stack queue 没有迭代器 ) ,只需要在固定的一端或者两端进行操作。
        2. stack 中元素增长时, deque vector 的效率高 ( 扩容时不需要搬移大量数据 ) queue 中的元素增长时, deque 不仅效率高,而且内存使用率高。 结合了 deque 的优点,而完美的避开了其缺陷。
双端队列示例代码:
#include<iostream>
#include<stack>
#include<deque>
using namespace std;

/*但是,deque有一个致命缺陷:不适合遍历,因为在遍历时,deque的迭代器要频繁的去检测其是否移动到
某段小空间的边界,导致效率低下,而序列式场景中,可能需要经常遍历,因此在实际中,需要线性结构
时,大多数情况下优先考虑vector和list,deque的应用并不多,而目前能看到的一个应用就是,STL用其作
为stack和queue的底层数据结构。*/

void test01()
{
	deque<int>dq;
	dq.push_back(1);
	dq.push_back(2);
	dq.push_back(3);
	dq.push_front(10);
	dq.push_front(20);
	dq.push_front(30);
	
	for (const auto& e : dq)
	{
		cout << e << " ";
	}
	cout << endl;

	for (deque<int>::iterator it = dq.begin(); it != dq.end(); ++it)
	{
		cout << *it << " ";
	}
	cout << endl;

	while (!dq.empty())
	{
		int value = dq.front();
		dq.pop_front();
		cout << value << " ";
	}
	cout << endl;
}

void main()
{
	test01();
	system("pause");
}

堆操作的四个函数,标准容器适配器priority_queue自动调用make_heap、push_heap和pop_heap来维护容器的堆属性。
make_heap()

 这个函数用于建堆操作, 这个函数用于建立堆。前两个参数为迭代器类型,最后一个为仿函数,用于确定建堆方式。默认使用大堆排序。可以调用官方仿函数greater<T>,构建小堆排序,也可以自定义仿函数给参数comp

push_heap()

       这个用于将堆底数据加入堆结构中。因为make_heap只能建堆,如果当前堆数据发生改变,就需要使用push_heap重回大堆/小堆。值得注意:first 到 last-1 之间的元素必须满足堆结构。它仅仅是将last之前元素插入堆中。意思就是,如果一次性插入多个元素,它只会把最后一个元素(堆底)加入堆结构中。参数与make_heap相同。

pop_heap()

       用于删除堆顶元素,但不是真的删除,堆顶元素被移至last-1的位置(堆底),移走之后系统会重新将剩余的size()-1个元素组织为大根堆。即数组最大值被放在了最后。

sort_heap()

该函数就是堆排序。但前提是该结构在调用sort_heap前已经是堆结构。sort_heap内部只是把堆顶放堆底,然后再排堆,再取堆顶到新堆底,...直到排完

代码示例:

#include<iostream>
#include<queue>
#include<functional>
using namespace std;

//全局函数,排序接口
//qsort()

//make_heap()
//push_heap()
//pop_heap()
//sort_heap()

void test01()
{
	vector<int> iv{ 5,8,30,2,1,4,9,7 };
	priority_queue<int>pq;
	for (int i = 0; i < iv.size(); ++i)
		pq.push(iv[i]);

	cout << pq.size() << endl;

	pq.pop();
	cout << pq.top() << endl;

	for (const auto& e : iv)
	{
		cout << e << " ";
	}
	cout << endl;
}

void test02()
{
	int arr[] = { 10 };
	vector<int> iv{ 5,8,30,2,1,4,9,7 };
	for (const auto& e : iv)
	{
		cout << e << " ";
	}
	cout << endl;
	make_heap(iv.begin(), iv.end());//对原有结构的数据调整为大堆结构
	for (const auto& e : iv)
	{
		cout << e << " ";
	}
	cout << endl;

	vector<int>::iterator it = iv.end();
	for (int i = 0; i < iv.size(); ++i)//堆顶的元素出堆,寻找新的堆顶,即每次把最大的值放在数组尾部,这样可以实现排序
	{
		pop_heap(iv.begin(), it);
		it--;
	}
	for (const auto& e : iv)
	{
		cout << e << " ";
	}
	cout << endl;

	/*push_heap(arr, arr+1);
	for (const auto& e : iv)
	{
		cout << e << " ";
	}
	cout << endl;*/
}

void test04()
{

	int arr[] = { 10 };
	vector<int> iv{ 5,8,30,2,1,4,9,7 };
	for (const auto& e : iv)
	{
		cout << e << " ";
	}
	cout << endl;
	make_heap(iv.begin(), iv.end(), greater<int>());//对原有结构的数据调整为大堆结构 默认生成大根堆,为了排序完得到升序
	for (const auto& e : iv)
	{
		cout << e << " ";
	}
	cout << endl;

	//iv.push_back(10);
	//push_heap(iv.begin(), iv.end());//进行堆的调整

	//for (const auto& e : iv)
	//{
	//	cout << e << " ";
	//}
	//cout << endl;

	//sort_heap(iv.begin(), iv.end());
	//for (const auto& e : iv)
	//{
	//	cout << e << " ";
	//}
	//cout << endl;
}

//class mysort
//{
//public:
//	bool operator()(int val1,int val2)
//	{
//		return val1 > val2;
//	}
//};

void test03()
{
	int arr[] = { 10 };
	vector<int> iv{ 5,8,30,2,1,4,9,7 };
	for (const auto& e : iv)
	{
		cout << e << " ";
	}
	cout << endl;
	make_heap(iv.begin(), iv.end());//对原有结构的数据调整为大堆结构 默认生成大根堆,为了排序完得到升序
	for (const auto& e : iv)
	{
		cout << e << " ";
	}
	cout << endl;

	iv.push_back(10);
	push_heap(iv.begin(), iv.end());//进行堆的调整

	for (const auto& e : iv)
	{
		cout << e << " ";
	}
	cout << endl;

	sort_heap(iv.begin(), iv.end());
	for (const auto& e : iv)
	{
		cout << e << " ";
	}
	cout << endl;
}

void main()
{
	test01();
	system("pause");
}

仿函数的使用:重载了小括号的类或者结构体,使用对象调用这个成员函数时就叫做仿函数,仿函数分为一元仿函数和二元仿函数。返回值为bool值的仿函数叫做谓词。

仿函数例子:

#include<iostream>
using namespace std;

template <class _Ty = void>
struct my_plus {
  
  _Ty operator()(const _Ty& _Left, const _Ty& _Right) const {
        return _Left + _Right;
    }
};


void main()
{
	my_plus<int>pl;//对象
	pl.operator()(10, 20);
	
	pl(10, 20);//仿函数
	system("pause");
}

仿函数影响排序方法的原理理解:

       在使用qsort()函数进行排序时,最后一个参数实际上是一个函数指针,我们可以按照这个函数指针的返回值以及参数类型,提供不同的函数(函数名和函数实现都可以不同)从而形成不同的比较规则,这些比较规则体现在底层就是对于是否需要交换元素会有不同的判断逻辑。注意这里qsort()就可以内部就可以传入int_less或者int_greater函数名 (函数指针)来实现对应的升序或者降序排列。

         理解了这一原理后,仿函数的工作机制其实完全一致,就是将仿函数对象作为参数传入到排序方法中,底层会调用这个对象所对应的仿函数(谓词)来实现比较或者判断逻辑,所以传入不同的谓词会有不同的数据组织规则。

         注意下面代码其实是不合理的,因为已经将仿函数的类类型写死了,没有办法传入int_greater()这个仿函数,因为类型不匹配。具体的做法是将谓词类型当作一个模板参数,并且将这个类型的的实例化对象当作一个成员变量。这样在使用时就可以传入不同类型的谓词了。

#include<iostream>
using namespace std;

int int_less(const void* elem1, const void* elem2)
{
	return  (*(int*)elem1 - *(int*)elem2);
}

int int_greater(const void* elem1, const void* elem2)
{
	return  (*(int*)elem2 - *(int*)elem1);
}

struct int_less1
{
	bool operator()(void* elem1, void* elem2)
	{
		return  *(int*)elem1 < *(int*)elem2;
	}
};

struct int_greater1
{
	bool operator()(void* elem1, void* elem2)
	{
		return  *(int*)elem1 > *(int*)elem2;
	}
};

//void qsort(void* base, size_t num, size_t width, int(__cdecl* compare)(const void* elem1, const void* elem2));

void myqsort(void* base, size_t num, size_t width, int_less1 Pr = int_less1())
{
	void* tmp = malloc(width);
	for (int i = 0; i < num - 1; ++i)
	{
		for (int j = 0; j < num - i - 1; ++j)
		{
			if (Pr(((char*)base) + j * width, ((char*)base) + (j + 1) * width))
			{
				//交换
				memcpy(tmp, ((char*)base) + j * width, width);
				memcpy(((char*)base) + j * width, ((char*)base) + (j + 1) * width, width);
				memcpy(((char*)base) + (j + 1) * width, tmp, width);
			}
		}
	}
}

void main()
{
	int ar[] = { 5,8,30,2,1,4,9,7 };
	int n = sizeof(ar) / sizeof(ar[0]);

	for (int i = 0; i < n; i++)
	{
		cout << ar[i] << " ";
	}
	cout << endl;
	myqsort(ar,n,sizeof(int),int_less1());
	//qsort(ar, n, sizeof(int), int_greater);
	for (int i = 0; i < n; i++)
	{
		cout << ar[i] << " ";
	}
	system("pause");
}

 priority_queue--容器适配器

1. 优先队列是一种容器适配器,根据严格的弱排序标准,它的第一个元素总是它所包含的元素中最大的。
2. 此上下文类似于堆,在堆中可以随时插入元素,并且只能检索最大堆元素 ( 优先队列中位于顶部的元 )
3. 优先队列被实现为容器适配器,容器适配器即将特定容器类封装作为其底层容器类, queue 提供一组特定的成员函数来访问其元素。元素从特定容器的 尾部 弹出,其称为优先队列的顶部。
4. 底层容器可以是任何标准容器类模板,也可以是其他特定设计的容器类。容器应该可以通过随机访问迭代器访问,并支持以下操作:
empty() :检测容器是否为空
size() :返回容器中有效元素个数
front() :返回容器中第一个元素的引用
push_back() :在容器尾部插入元素
pop_back() :删除容器尾部元素
5. 标准容器类 vector deque 满足这些需求。默认情况下,如果没有为特定的 priority_queue 类实例化指定容器类,则使用 vector
6. 需要支持随机访问迭代器,以便始终在内部保持堆结构。容器适配器通过在需要时自动调用算法函数 make_heap push_heap pop_heap 来自动完成此操作。
优先级队列默认使用vector作为其底层存储数据的容器,在vector上又使用了堆算法将vector中元素构造成堆的结构,因此priority_queue就是堆,所有需要用到堆的位置,都可以考虑使用priority_queue。注意: 默认情况下priority_queue是大堆。
priority_queue接口测试:
#include<iostream>
#include<queue>
#include<functional>
using namespace std;

void test01()
{
	vector<int> v{ 3,2,7,6,0,4,1,9,8,5 };
	priority_queue<int>pq1;
	for (auto& e : v)
	{
		pq1.push(e);
	}

	cout << pq1.top() << endl;

	while (!pq1.empty())
	{
		cout << " " << pq1.top();
		pq1.pop();
	}
	cout << endl;
    
	priority_queue<int,vector<int>,greater<int>> pq2(v.begin(),v.end());
	if (pq2.empty())
	{
		cout << "empty" << endl;
	}
	else
	{
		cout << "not empty" << endl;
	}
    
	cout << pq2.top() << endl;

	while (!pq2.empty())
	{
		cout << " " << pq2.top();
		pq2.pop();
	}

}

void main()
{
	test01();
	system("pause");
}

priority_queue的使用:

#include<iostream>
#include<queue>
using namespace std;
class date
{
public:
	date(int year = 1900, int month = 1, int day = 1)
		: _year(year)
		, _month(month)
		, _day(day)
	{}
	bool operator<(const date& d)const
	{
		return (_year < d._year) ||
			(_year == d._year && _month < d._month) ||
			(_year == d._year && _month == d._month && _day < d._day);
	}
	bool operator>(const date& d)const
	{
		return (_year > d._year) ||
			(_year == d._year && _month > d._month) ||
			(_year == d._year && _month == d._month && _day > d._day);
	}
	friend ostream& operator<<(ostream& _cout, const date& d)
	{
		_cout << d._year << "-" << d._month << "-" << d._day;
		return _cout;
	}
private:
	int _year;
	int _month;
	int _day;
};
void testpriorityqueue()
{
	 大堆,需要用户在自定义类型中提供<的重载
	priority_queue<date> q1;
	q1.push(date(2018, 10, 29));
	q1.push(date(2018, 10, 28));
	q1.push(date(2018, 10, 30));
	cout << q1.top() << endl;
	 如果要创建小堆,需要用户提供>的重载
	priority_queue<date, vector<date>, greater<date>> q2;
	q2.push(date(2018, 10, 29));
	q2.push(date(2018, 10, 28));
	q2.push(date(2018, 10, 30));
	cout << q2.top() << endl;
}

void main()
{
	vector<date> v1{ date(2018, 10, 29), date(2018, 10, 28),  date(2018, 10, 30) };
	make_heap(v1.begin(),v1.end(),greater<date>());
	system("pause");
}

priority_queue的实现1

#include<iostream>
#include<vector>
#include<queue>
using namespace std;

namespace hym
{
    template<class T, class Cont = vector<T>, class Pred = less<T>>
    class priority_queue 
    {
     public:
        typedef T value_type;
        typedef size_t size_type;

        explicit priority_queue(const Pred& pr = Pred()) { sz = 0; }

        void push(const value_type& x)
        {
            c.push_back(x);
            push_heap(c.begin(), c.end());
            sz++;
        }

        size_type size()
        {
            return sz;
        }

        const value_type& top() const
        {
            return c.front();
        }

        void pop()
        {
            pop_heap(c.begin(), c.end());
            sz--;

        }

        void show()
        {
            for (const auto& e : c)
            {
                cout << e << " ";
            }
            cout << endl;
        }

        bool empty()
        {
            return sz == 0;
        }

        priority_queue(const value_type* first, const value_type* last,
        const Pred& pr = Pred()):c(first,last)
        {
            make_heap(c.begin(), c.end(),pr);
            sz = c.size();
        }
  
   
    protected:
        Cont c;
        Pred comp;
        size_t sz;
    };
}

void test01()
{
    hym::priority_queue<int>pq;
    pq.push(5);
    pq.push(9);
    pq.push(2);
    pq.push(4);
    pq.push(1);

    pq.show();
    cout << pq.size() << endl;
    pq.pop();
    cout << pq.top() << endl;
    cout << pq.size() << endl;
}

void test02()
{
    int ar[] = { 5,9,2,4,1 };
    hym::priority_queue<int,vector<int>,greater<int>>pq(ar, ar + 5,greater<int>());//小堆
    //hym::priority_queue<int>pq(ar, ar + 5);//大堆
    pq.show();
}

void main()
{
    test02();
    system("pause");
}

 priority_queue的实现2

#include<iostream>
#include<vector>
using namespace std;

namespace hym
{
	template<class T, class Container = std::vector<T>, class Compare = less<T>>
	class priority_queue
	{
	public:
		priority_queue() {}
		priority_queue(const T* first, const T* last,
			const Compare& pr = Compare()) :c(first, last),comp(pr)
		{
			int curpos = c.size() / 2 - 1;
			while (curpos >= 0)
			{
				_adjustdown(curpos);
				curpos--;
			}
		}

		bool empty()
		{
			return c.empty();
		}

		size_t size() const
		{
			return c.size();
		}

		const T& top()const
		{
			return c.front();
		}

		T& top()
		{
			return c.front();
		}

		void push(const T& x)
		{
			c.push_back(x);
			adjust_up(c.size() - 1);

		}

		void pop()
		{
			std::swap(*c.begin(),*--c.end());
			c.pop_back();
			_adjustdown(0);
		}

	    void show()
        {
            for (const auto& e : c)
            {
                cout << e << " ";
            }
            cout << endl;
        }

	protected:
		void _adjustdown(int start)
		{
			int n = c.size();
			int i = start;
			int j = 2 * i + 1;
			while (j < n)
			{
				//c[j]<c[j+1]
				if (j + 1 < n &&comp( c[j] ,c[j + 1]))
					j++;
				if (comp(c[i],c[j]))
				{
					T tmp = c[i];
					c[i] = c[j];
					c[j] = tmp;

					i = j;
					j = 2 * i + 1;
				}
				else
					break;
			}
		}

		void adjust_up(int start)
		{
			int j = start;
			int i = (j-1)/2;

			while (i >= 0)
			{
				if (comp(c[i], c[j]))
				{
					T tmp = c[i];
					c[i] = c[j];
					c[j] = tmp;

					j = i;
					i = (j - 1) / 2;
				}
				else
					break;

			}
		}

	private:
		Container c;
		Compare comp;
	};
}

void test01()
{
	int ar[] = { 53,17,78,9,45,65,87,23 };
	int n = sizeof(ar) / sizeof(ar[0]);
	hym::priority_queue<int>pq(ar,ar+8);
	pq.show();
}

void test02()
{
	int ar[] = { 53,17,78,9,45,65,87,23 };
	int n = sizeof(ar) / sizeof(ar[0]);
	hym::priority_queue<int>pq(ar, ar + 8);
	pq.push(50);
	pq.show();
}

void test03()
{
	int ar[] = { 53,17,78,9,45,65,87,23 };
	int n = sizeof(ar) / sizeof(ar[0]);
	hym::priority_queue<int>pq(ar, ar + 8);
	pq.push(50);
	pq.pop();
	pq.show();
}

void test04()
{
	int ar[] = { 53,17,78,9,45,65,87,23 };
	int n = sizeof(ar) / sizeof(ar[0]);
	//hym::priority_queue<int>pq(ar, ar + 8);
	hym::priority_queue<int,vector<int>,greater<int>>pq(ar, ar + 8,greater<int>());
	pq.show();
}

void main()
{
	test04();
	system("pause");
}

    

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值