按升序對棧進行排序

題目:編寫程序,按升序對棧進行排序(即最大元素位於棧頂)。最多隻能使用一個額外的棧存放臨時數據,但不得將元素複製到別的數據結構(如數組)。

    思路:假設數據保存在原棧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萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章