双栈排序

题目描述

请编写一个程序,按升序对栈进行排序(即最大元素位于栈顶),要求最多只能使用一个额外的栈存放临时数据,但不得将元素复制到别的数据结构中。
给定一个int[] numbers(C++中为vector&ltint>),其中第一个元素为栈顶,请返回排序后的栈。请注意这是一个栈,意味着排序过程中你只能访问到第一个元素。
测试样例:
[1,2,3,4,5]
返回:[5,4,3,2,1]

思路:迫于题目要求,只能使用两个栈,可以想到一个栈存放有序数列,另一个栈buffer存放无序的其它数列,,可以另外定义一个整形变量tmp,用排序时的数据交换,
排序:
》》1 ,从buffer中取出(pop)一个元素,放到tmp,和有序栈栈顶的元素比较(每次只能访问栈的栈顶元素);若小于栈顶元素,则有序栈栈顶元素出栈 到 buffer,同时记下出栈元素个数,依次继续比较,直到小于不成立,
》》2,根据出栈元素个数,将buffer中元素 返回到有序栈,一次循环结束

Java

import java.util.*;

public class TwoStacks {
    public ArrayList<Integer> twoStacksSort(int[] numbers) {
        // write code here
        if(numbers == null && numbers.length==0)return null;
        ArrayList<Integer> arrlist=new ArrayList<Integer>(numbers.length); 
        Stack<Integer> sta = new Stack<Integer>();
        Stack<Integer> buffer = new Stack<Integer>();
        int  i=0,tmp=0; 
        while( i < numbers.length )
            {
            buffer.push(numbers[i]);
            i++; 
        } 
        while(buffer.isEmpty()!=true){

            tmp = buffer.pop();//一定要pop 不能peek()
            int count=0; 
 //while(tmp < sta.peek()&&sta.isEmpty()!=true)//这样会出异常,一定要判断在前,比较在后
             while(sta.isEmpty() != true && tmp < sta.peek())
              { 
                buffer.push(sta.peek());
                sta.pop();
                count++;//出栈元素数 统计,,然后依此数逐个返回原栈
              } 
               sta.push(tmp);

             for(i = 0;i < count;i++) { 
                sta.push(buffer.pop());

                } 
        }
        for( i = 0;i < numbers.length;i++){
            arrlist.add(sta.pop());
           // sta.pop();
        }
        return arrlist;
    }
}

C/C++
思路一样,,只是采取了vector 容器的方式,vector顺序容器的基本操作,访问、添加、删除等。push_back(t) ,push_front(t) , back(),pop_back(),,等
说明
  vector是一种动态数组,是基本数组的类模板。其内部定义了很多基本操作。
  #include 注意:头文件没有“.h”
构造:
  这个构造函数还有一个可选的参数,这是一个类型为T的实例,描述了各个向量种各成员的初始值;
  如:vectorv2(init_size,0); 如果预先定义了:intinit_size;他的成员值都被初始化为0;
  · 复制构造函数,构造一个新的向量,作为已存在的向量的完全复制;
  如:vectorv3(v2);
  · 带两个常量参数的构造函数,产生初始值为一个区间的向量。区间由一个半开区间first,last来指定。
  如:vectorv4(first,last) vector v1;
  vectorv2(init_size,0);
  vectorv3(v2);
方法:
  c.assign(beg,end)c.assign(n,elem) 将(beg; end)区间中的数据赋值给c。将n个elem的拷贝赋值给c。
  c. at(idx) 传回索引idx所指的数据,如果idx越界,抛出out_of_range。
  c.back() 传回最后一个数据,不检查这个数据是否存在。
  c.begin() 传回迭代器中的第一个数据地址。
  c.capacity() 返回容器中数据个数。
  c.clear() 移除容器中所有数据。
  c.empty() 判断容器是否为空。
  c.end() // 指向迭代器中末端元素的下一个,指向一个不存在元素。
  c.erase(pos)// 删除pos位置的数据,传回下一个数据的位置。
  c.erase(beg,end) 删除[beg,end)区间的数据,传回下一个数据的位置。
  c.front() 传回第一个数据。
  get_allocator 使用构造函数返回一个拷贝。
  c.insert(pos,elem)// 在pos位置插入一个elem拷贝,传回新数据位置 
  c.insert(pos,n,elem)// 在pos位置插入n个elem数据,无返回值 
  c.insert(pos,beg,end)// 在pos位置插入在[beg,end)区间的数据。无返回值 
  c.max_size() 返回容器中最大数据的数量。 
  c.pop_back() 删除最后一个数据。 
  c.push_back(elem) 在尾部加入一个数据。 
  c.rbegin() 传回一个逆向队列的第一个数据。 
  c.rend() 传回一个逆向队列的最后一个数据的下一个位置。 
  c.resize(num) 重新指定队列的长度。 
  c.reserve() 保留适当的容量。 
  c.size() 返回容器中实际数据的个数。 
  c1.swap(c2)// 将c1和c2元素互换
  参考链接

class TwoStacks {
public:
    vector<int> twoStacksSort(vector<int> numbers) {
        // write code here
           vector<int> forSort;
            if(numbers.size() <= 1) return numbers;
            forSort.push_back(numbers.back());
            numbers.pop_back();
            while(numbers.size() > 0)
            {
                int temp = numbers.back();
                numbers.pop_back();
                int count = 0;  // 出栈元素的数量
                while(!forSort.empty() && temp < forSort.back()){
                    numbers.push_back(forSort.back());
                    forSort.pop_back();
                    count++;
                }
                forSort.push_back(temp);
                for(int i = 0 ; i < count ;i ++ ){

                    forSort.push_back(numbers.back());//不可以直接pop_back(),,类似于C里面的pop()

                    numbers.pop_back();

                }
            }
            reverse(forSort.begin(),forSort.end());
            return forSort;
    }
};

这个是网上的另外一种解法,,可以减少循环次数,,

public ArrayList<Integer> twoStacksSort(int[] numbers) {
    /*
     * 思路:
     * 只用两个栈排序,一个是有序的asc,另一个是无序的buffer就可以实现对一个栈的排序。如何有序,当原始栈只有一个时就有序了
     * numbers中第一个为栈顶
     * 主要是解决buffer栈顶元素放在asc的位置
     * 1. buffer栈顶大于等于asc栈顶或asc空
     *  直接放
     * 2. buffer栈顶小于asc栈顶
     *  buffer栈顶值出栈,临时变量存放buffer栈顶值
     *  循环从asc中拿出值放到buffer直至asc空或满足1条件
     */
    if(numbers == null || numbers.length == 0){
        return null;
    }
    int length = numbers.length;
    ArrayList<Integer> res = new ArrayList<Integer>(length);
    Stack<Integer> buffer = new Stack<Integer>();
    Stack<Integer> ascStack = new Stack<Integer>();
    //初始状态,buffer中放了length-1个与numbers逆序的数串,asc只剩栈底元素
    for(int i = 0; i < length-1; i++){
        buffer.push(numbers[i]);
    }
    ascStack.push(numbers[length-1]);
    //排序
    int bufTop = 0;
    while(buffer.size() > 0){
        if(ascStack.isEmpty() || buffer.peek() >= ascStack.peek()){
            ascStack.push(buffer.pop());
        }
        else{//这里一定要加else ,
            bufTop = buffer.pop();
            int count_curBuffer = buffer.size();
            while(!ascStack.isEmpty() && bufTop < ascStack.peek()){
                buffer.push(ascStack.pop());
            }
            ascStack.push(bufTop);
            int count_numsFromAsc = buffer.size()-count_curBuffer;

            for(int i = 0; i < count_numsFromAsc; i++){
                ascStack.push(buffer.pop());
            }
        }
    }
    for(int i = 0; i < length; i++){
        res.add(ascStack.pop());
    }
    return res;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值