棧的排序算法:
第一種,類似於插入排序,(允許額外利用一個棧),每一步的循環不變式是temp中的元素是有序的。直接上代碼:
void sortStack(stack& s)
{
if(s.empty()) return;
stack temp; //輔助棧
while(!s.empty())
{
int cur = s.top();
s.pop();
//每一次將s的棧頂的元素取出,插入到temp的合適的位置上,插入位置之上的元素彈回s。
if(temp.empty())
{
temp.push(cur);
continue;
}
while(!temp.empty())
{
if(temp.top() < cur)
{
s.push(temp.top());
temp.pop();
}
else
{
temp.push(cur);
break;
}
}
if(temp.empty()) temp.push(cur); //如果將temp站內的元素全部彈完了,那麼將當前元素放在棧底
}
s.swap(temp); //交換兩者
}
第二種排序:快速排序,快速排序每次根據一個partition將棧分爲兩個部分,於是下面的代碼中使用了兩個棧來作爲輔助棧。
void quickSortStack(stack &s)
{
if(s.empty()) return;
int pivot = s.top();s.pop(); //直接取棧頂元素作爲pivot
if(s.empty()) //如果當前只有一個元素。那麼直接返回,不用再排序了
{
s.push(pivot);
return;
}
stack less, grt; //記錄比當前元素大的和小的的數字的棧
while(!s.empty())
{
int cur = s.top();s.pop();
if(cur <= pivot)
{
less.push(cur);
}
else
{
grt.push(cur);
}
}
if(less.empty()) less.push(pivot);
else grt.push(pivot);
//遞歸調用
quickSortStack(less);
quickSortStack(grt);
//將調用的結果Merge到s中歐,先將grt的部分壓入棧底。再壓入less的部分,
//此處爲了減少入棧與出棧的次數,直接使用less來作爲中轉
while(!grt.empty())
{
s.push(grt.top());
grt.pop();
}
while(!s.empty())
{
less.push(s.top());
s.pop();
}
s.swap(less);
}
第三種排序:歸併排序。直接上代碼,比較簡單:
void merge(stack &s, stack &left, stack &right)
{
assert(s.empty());
if(left.empty() && right.empty())
{
return ;
}
if(left.empty())
{
s.swap(right);
return;
}
if(right.empty())
{
s.swap(left);
return;
}
int l = left.top(); left.pop();
int r = right.top(); right.pop();
while(1)
{
if(l < r)
{
s.push(r);
if(right.empty())
{
s.push(l);
break;
}
r = right.top();right.pop();
}
else
{
s.push(l);
if(left.empty())
{
s.push(r);
break;
}
l = left.top(); left.pop();
}
}
while(!left.empty())
{
l = left.top(); left.pop();
s.push(l);
}
while(!right.empty())
{
r = right.top(); right.pop();
s.push(r);
}
while(!s.empty()) {
right.push(s.top()); s.pop();
}
right.swap(s);
}
void mergeSortStack(stack &s)
{
//empty
if(s.empty()) return;
//single element
//maybe a little weird
int temp = s.top(); s.pop();
if(s.empty()) {
s.push(temp);
return;
}
s.push(temp);
stack left, right;
while(!s.empty())
{
int cur = s.top();s.pop();
left.push(cur);
if(s.empty()) break;
cur = s.top(); s.pop();
right.push(cur);
}
mergeSortStack(left);
mergeSortStack(right);
merge(s,left,right);
}