按升序对栈进行排序

题目:编写程序,按升序对栈进行排序(即最大元素位于栈顶)。最多只能使用一个额外的栈存放临时数据,但不得将元素复制到别的数据结构(如数组)。

    思路:假设数据保存在原栈s1中,另设辅助栈s2。数据进行一系列处理后以升序排在栈s1中,那么s1中的数据一定是由s2栈倾倒出的。所以在完成所有数据在s1中升序排列之前数据应该在s2中降序排列,即大元素位于栈底。所以问题转化为从s1中弹出元素输入到s2中并使这些元素降序排列。考虑这一操作的中间过程,假设已经弹出s1的部分元素压入s2中,数据在s2中已排序,s2从栈底到栈顶有5,3,2,1这4个元素,假设当前s1的栈顶元素是4,现在要将4入栈s2,为了保持s2栈中元素的顺序,4应该放入3的下面。这时候s2中的1,2,3都需要弹出给4让出位置,1,2,3只能临时存放在s1中,为了避免s1原先的栈顶元素4被覆盖,可以设临时变量保存栈顶4,然后弹出4.再将s2中小于的4的元素全部弹出到s1中,原先s1的栈顶4先入栈s2,再将1,2,3从s1中还原到s2,这时候s2中的元素还是排好序的,为5,4,3,2,1。

    所以算法应该包括以下几个步骤:

    (1)原栈s1中的第一个栈顶元素直接弹出到辅助栈s2中,因为一个元素不需要考虑顺序问题。

    (2)当s1非空时,每次弹出栈顶元素并保存在临时变量中,将s2中小于s1栈顶的元素全部弹出到s1中;

    (3)临时变量入栈s2;

    (4)第(2)步中从s2弹出到s1中的所有元素再返回到s2,实际上这一步可以省略,因为s2新的栈顶比这几个元素都要大,因此s1现在的栈顶至少包括这几个元素比新栈顶小,根据第(2)步的判断也会弹回s2中。

    (5)s1为空时,所有元素在s2中已经完成了降序排列,弹回s1即完成了升序排列。

void StackSort(stack<int>& s)
{
	if(s.empty() || s.size() == 1)
		return;
	stack<int> tmpStack;
	int first = s.top();
	tmpStack.push(first);
	s.pop();
 
	while(!s.empty())
	{
		int top = s.top();
		s.pop();
		while(!tmpStack.empty() && top > tmpStack.top())
		{
			int tmp1 = tmpStack.top();
			tmpStack.pop();
			s.push(tmp1);
		}
		tmpStack.push(top);
	}
 
	while(!tmpStack.empty())
	{
		int tmp2 = tmpStack.top();
		tmpStack.pop();
		s.push(tmp2);
	}
}


发布了147 篇原创文章 · 获赞 18 · 访问量 20万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章