【算法编程】用栈实现另一个栈的排序

【算法编程】用栈实现另一个栈的排序

  给定一个栈,对其进行排序,使得栈顶至栈底的为降序,只能申请一个栈和变量,不能使用数组或多余的栈等数据结构.
  试题来源:Coding Interviewing Guided (Page 12)
  难度:★★★☆☆


思路一

C++源码:

//用一个栈实现另一个栈的排序
//给定一个栈,对这个栈进行排序,使得栈顶至栈底的元素为降序排列,注意,只允许创建另一个栈,或相关的变量,不能使用数组等数据结构
#include <iostream>
#include <stack>
using namespace std;

void sort_stack_by_stack(stack<int> &s){
    stack<int> s2;
    int ans = s.size();//表示栈s从栈顶到栈底第ans元素之后都是有序的
    while(ans>0){
        int min = s.top();//用于记录当前无序部分最小的值
        int min_num = 1;//用于记录最小值的个数
        //先对栈s进行出栈,且每次出栈时将元素入栈s2,并记录最小值
        for(int i=0;i<ans;++i){
            int top = s.top();
            s.pop();
            s2.push(top);
            if(top<min){
                min = top;
                min_num = 1;
            }else if(top==min) min_num++;
        }
        for(int i=0;i<min_num;i++) s.push(min);//将最小值先入栈s
        while(!s2.empty()){//将剩余的值入栈s,
            if(s2.top()!=min) s.push(s2.top());
            s2.pop();
        }
        ans-=min_num;//且更新有序的范围
    }
}

int main(){
    int v[9] = {6,3,7,2,4,6,0,9,5};
    stack<int> s;
    for(int i=0;i<9;i++){//初始化一个栈
        s.push(v[i]);
    }
    sort_stack_by_stack(s);
    cout<<"\nsorted stack pop order:\n";
    while(!s.empty()){
        int top = s.top();
        s.pop();
        cout<<top<<' ';
    }
    system("pause");
    return 0;

}

原理讲解:

  假设给定的栈为s,另一个开辟的栈为s2,s2可以作为临时存放s元素的位置,设定一个阈值ans,初始化为元素的个数,其表示在栈s中,从栈顶到底ans个元素是无序的,而第ans个元素一直到栈底是有序的,因此我们只需要不断地将ans减少到0,每次减少时将无序中的最小值如栈s中即可。整个过程可以分为下面几步:

  • step1:先将给定栈s中所有元素出栈并入栈到s2中,并统计最小值及出现的次数;
  • step2:s为空时,此时所有元素已转移到s2中,且获得了当前最小值min及其个数min_num;
  • step3:将这个最小值按照其个数重复入栈s中,即将最小值先入栈s;
  • step4:再次将s2中的元素出栈并入栈到s中,其中在s2出栈时,如果当前元素是最小值,则忽略;
  • step5:ans-=min_num,重复执行上面步骤,知道ans==0。

思路二

  上面的方法有一个问题,就是入栈出栈次数太多,因此还有一种思路,即每次从栈s中出栈一个元素a,并判断其与s2的栈顶元素b的大小,如果a小于等于b,则入栈到s2,否则对s2进行出栈并入栈到s中,直到s2的栈顶元素恰巧比a小时,将a入栈s2,重复上述步骤直到s为空,此时s2由栈顶至栈底是升序的,将s2依次出栈入栈到s中即可。

将上述的代码中函数sort_stack_by_stack进行修改:

void sort_stack_by_stack(stack<int> &s){
    stack<int> s2;
    while(!s.empty()){
    	int top = s.top();
    	s.pop();
    	if(s2.empty() || top <= s2.top()) s2.push(top);
		else {
			while(!top.empty() && top<=s2.top()){
				s.push(s2.top());
				s2.pop();
			}
			s2.push(top);
		}
    }
    while(!s2.empty()){
    	s.push(s2.top());
		s2.pop();
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

华师数据学院·王嘉宁

$感谢支持$

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值