棧排序(空間複雜度O(1))
如果要將空間複雜度為O(1),那麼就不能夠宣告陣列來申請空間了
只有兩個堆疊可以使用。
那麼我們該怎麼去實現排序了,因為堆疊是後進先出,只有一端能進入和出去,這就使得問題複雜了。
其實我們可以不再另申請空間也能完成排序。
比如,一個輸出棧S,輸入棧R,我們每次將輸入棧的元素push進入輸出棧S,但是因為我們的輸出棧元素需要排序,假定從棧底到棧頂按照從小到大的順序排列,那麼我們如果輸入的棧的元素比輸出棧中的棧頂元素小,按理說,應該排在這個棧頂元素的下面。所以,我們這時候需要先將輸出棧中的棧頂元素pop出來,然後再將輸入棧的棧頂元素push進入輸入棧,這時候我們在將之前pop出來的棧頂元素在按照原有的排序push進入輸出棧。
那麼,問題是我們將輸出棧中pop出去的那一部分元素怎麼儲存呢,當然,通常情況下我們可以使用陣列儲存啊,但是空間複雜度為O(1)的時候,很顯然我們不能在定義陣列申請空間,其實我們可以將pop出去的元素push進入輸入棧的棧頂,等之前輸入棧push進入輸出棧的元素找到位置後,再依次push到輸出棧,這樣既可以不開闢空間,也可以完成棧的排序。
例:
棧排序
時間限制:1 sec
空間限制:256 MB
問題描述
給定一個序列 A,請你將它升序排序。
輸入格式
第一行一個正整數 n,表示序列長度。
第二行 n 個用空格隔開的非負整數,描述這個序列。
輸出格式
n 行,每行一個非負整數,表示排序後的序列。
樣例輸入
4
1 3 2 10
樣例輸出
1
2
3
10
資料範圍
保證 n<=1000,保證序列中的數不超過 32767,以及時間複雜度為O(1)
我們其實就可以使用剛剛說的方法,藉助輸入棧存放一些元素的方法。
程式碼:因為輸出要求是升序輸出,我這裡用的棧排序是降序壓進棧中。所以我這裡使用的輸出方式是vector逆迭代器
#include<iostream> #include<stack> #include<vector> using namespace std; stack<int> Stack_Sort(stack<int> myStack) { stack<int> output; //最後需要輸出的堆疊 if(myStack.empty()) //輸入堆疊為空 ,若為空,就沒有元素壓入棧中 return output; int t = myStack.top(); //要壓入output的元素 myStack.pop(); //彈出元素 //! myStack.empty()這是一個邊界條件,意味著輸入棧的元素壓完後,就結束排序操作了 // (!output.empty() && output.top()>t) 這一個式子有一點複雜 // !output.empty()如果輸出棧為空或者是 output.top()>t輸出棧棧頂指標比最後的t(存放的是輸入棧所有元素壓完進入輸出棧,但是t變數還是存了一個元素) //然後我們必須把t在壓入輸出棧中,但是因為會考慮到亂序,那麼通過 output.top()>t考慮到是否再重新排序 while(!myStack.empty() || (!output.empty() && output.top()>t)) { if(output.empty() || output.top()<=t) { output.push(t); t = myStack.top(); //更新元素 myStack.pop(); } else { myStack.push(output.top()); output.pop(); } } output.push(t); return output; } int main() { stack<int> R; //亂序的堆疊,將從該堆疊一直pop元素到堆疊S int nums; int n; cin>>n; for(int i = 1;i<n;i++) { cin>>nums; R.push(nums); } stack<int> result = Stack_Sort(R); vector<int> answer; while(!result.empty()) { answer.push_back(result.top()); //將堆疊裡的內容從尾部一個一個新增到vector result.pop(); } //反向迭代器 ,因為我們需要輸出升序,就需要將容器逆序輸出 for(vector<int>::reverse_iterator i = answer.rbegin();i!=answer.rend();++i) { cout<<*i<<endl; } return 0; }
這裡的輸出邊pop()邊輸出,便於理解
#include<iostream>
#include<stack>
using namespace std;
stack<int> Stack_sorting(stack<int> input)
{
stack<int> output;
if(input.empty())
return output;
int temp = input.top();
input.pop();
while(!input.empty() || (!output.empty() && output.top()>temp))
{
if(output.empty() || output.top()<=temp)
{
output.push(temp);
temp = input.top();
input.pop();
}
else
{
input.push(output.top());
output.pop();
}
}
output.push(temp);
return output;
}
int main()
{
stack<int> R; //輸入棧
int n;
int nums;
cin>>n;
for(int i = 0;i<n;i++)
{
cin>>nums;
R.push(nums);
}
stack<int> reslut = Stack_sorting(R);
stack<int> fuzhu;
for(int j = 0;j<n;j++)
{
fuzhu.push(reslut.top());
reslut.pop();
}
for(int k = 0;k<n;k++)
{
cout<<fuzhu.top()<<endl;
fuzhu.pop();
}
return 0;
}