双栈排序

来源:互联网 发布:linux安全维护 编辑:程序博客网 时间:2024/06/15 13:31

题目描述

请编写一个程序,按升序对栈进行排序(即最大元素位于栈顶),要求最多只能使用一个额外的栈存放临时数据,但不得将元素复制到别的数据结构中。
给定一个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;}
0 0
原创粉丝点击