栈的排序算法:
第一种,类似于插入排序,(允许额外利用一个栈),每一步的循环不变式是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); }