程序员面试金典: 9.3栈与队列 3.6编写程序,按升序对栈进行排序(即最大元素位于栈顶)
2016-12-24 10:23
357 查看
#include <iostream> #include <stdio.h> #include <string> #include <stack> using namespace std; /* 问题:编写程序,按升序对栈进行排序(即最大元素位于栈顶)。最多只能使用一个额外的栈存放临时数据,但不得将 元素赋值到别的数据结构中(如数组)。该栈支持如下操作: push、pop、peek和isEmpty。 分析:栈后进先出,但是需要对栈排序,而且允许使用一个额外的栈。可以在每次压入时,如果当前元素大于临时栈中元素 时,就将当前元素压入栈中;弹出元素时,获取栈顶元素如果和临时栈中元素相同,说明是最大元素,就弹出临时栈和 栈本身中元素。 那么这道题目本质和之前实现min函数为O(1)是相同的 输入: 3(栈中存放的元素个数) 3 6 5 3(指令个数) push 8 push 2 pop 1 7 1 3 8 12 7 10 5 0 输出: 2 3 5 6(栈中元素按从小到大排序) 1 3 5 7 8 10 12 书上解法: 题目意思理解错了,题目是一定需要你排序的。 一个例子 S1 5 10 7 S2 12 8 3 1 将栈S2用于最终排序后结果存放。S1中弹出5,需要存放到S2中元素3的上面。 步骤: 1先保存5 2必须将S2中大于S1栈顶元素的所有元素,先保存到S1中,以便在S2中留下待插入位置。 3将S1中待插入元素插入S2中 4继续将S1中栈顶元素重复上述过程,直到S1为空,此时S2已经排好序 关键: 1 用两个栈,栈1用于存放原始输入元素,栈2用于保存排序后结果 2 将栈1的元素要移动到已经有序的栈2中(插入排序,在已经排好序的序列中插入一个新的元素), 将栈2中所有大于栈1栈顶的元素全部移动到栈1中,栈1中栈顶元素移动到栈2中 只要栈1不空,重复对栈1的栈顶元素执行上述操作就能排好序 */ class SortStack : public stack<int> { public: //压入元素时,除了正常的栈压入外,额外成员最大栈判定如果待压入元素>=临时栈栈顶元素,就压入,导致里面都是拍好序的元素 void push(int value) { stack<int>::push(value); //应该是一边插入一边排序,如果结果栈(排好序的栈中为空,说明这是首次有元素插入,应该将该元素插入到结果栈) if(resultStack.empty()) { resultStack.push(value); stack<int>::pop(); } //如果结果栈中已经有元素了,那么现在,比较栈与结果栈栈顶,如果栈顶元素<结果栈栈顶元素,说明应该将栈顶元素插入到结果栈中 //因此将结果栈中凡是大于栈顶元素的元素都转移到栈中,然后将原栈顶元素插入到结果栈栈顶元素, else { //只要原先栈中元素不空,就一直直接这个操作 while( !isEmpty() ) { int temp = stack<int>::top(); stack<int>::pop(); //这边必须确保resultStack不为空,否则为空top会有问题 while(!resultStack.empty() && temp < resultStack.top() ) // 将栈2中所有大于栈1栈顶元素的元素,转移到栈1中 { int value = resultStack.top(); resultStack.pop(); stack<int>::push(value); } //全部转移完成后,是否需要直接继续把S1中所有元素拷贝过来,还是不弄,不做的话需要放在另外函数中做,所以还是要做一下 resultStack.push(temp); } } } //弹出时,栈本身正常弹出,如果栈的栈顶元素=最大栈的栈顶元素,说明待弹出的元素是最大值,则最大栈也弹出。 //由于每次压入的结果都会在结果栈中拍好序,每次弹出,肯定都是弹出排好序的结果栈中最大元素 void pop() { //最大栈为空,直接弹出正常栈的元素 if(resultStack.empty()) { return; } resultStack.pop(); } //弄清楚这里是要返回最大元素,因此,需要返回maxStack的元素 int top() { if( resultStack.empty() ) { return -1; } else { return resultStack.top(); } } bool isEmpty() { return stack<int>::empty(); } void print() { stack<int> stackTemp(resultStack); stack<int> stackData; while(!stackTemp.empty()) { stackData.push( stackTemp.top() ); stackTemp.pop(); } while(!stackData.empty()) { cout << stackData.top() << " "; stackData.pop(); } cout << endl; } private: stack<int> resultStack; }; int main(int argc, char* argv[]) { int n; int commandNum; string command; int value; while(cin >> n) { SortStack maxStack; int* pArr = new int ; for(int i = 0 ; i < n ; i++) { cin >> *(pArr + i); maxStack.push( *(pArr + i) ); } cin >> commandNum; for(int j = 0 ; j < commandNum ; j++) { cin >> command >> value; if(command == "pop") { for(int k = 0 ; k < value ; k++) { maxStack.pop(); } } else if(command == "push") { maxStack.push(value); } } //输出栈中元素 maxStack.print(); delete[] pArr; } getchar(); return 0; }
相关文章推荐
- 队列和栈面试题(一)— 请编写一个程序,按升序对栈进行排序,要求最多只能使用一个额外的栈存放临时数据
- 编写一个使用数组类模板Array对数组进行排序、求最大值和求元素和的程序,并采用相关数据进行测试。
- 编写一个使用数组类模板Array对数组进行排序、求最大值和求元素和的程序,并采用相关数据进行测试。
- 编写一个程序,输入两个包含 5 个元素的数组,先将两个数组升序排序,然 后将这两个数组合并成一个升序数组(合并排序)。
- 对数组进行排序、求最大值和求元素和的算法都编写为函数模板,采用相关数据进行测试
- 编写程序对N个元素数组,用冒泡排序法进行排序
- 用sort()方法对数组的元素进行排序(可按字母升序降序与获得最大最小值)
- 编写程序实现以下功能: 随机产生20个正整数存入数组a中,且每个数均在1000-9999之间(包含1000和9999)。对数组进行排序,要求按每个数的后三位的大小进行升序排列,然后取出满足此条
- 对数组进行排序、求最大值和求元素和的算法都编写为函数模板,采用相关数据进行测试。
- 程序员面试金典: 9.11 排序与查找 11.6给定M*N矩阵,每一行、每一列都按升序排列,请编写代码找出某元素。
- 9.3栈和队列(八)——按升序对栈进行排序
- 对数组进行排序、求最大值和求元素和的算法都编写为函数模板,采用相关数据进行测试。
- 3. 编写一个C程序,实现对10个整数进行升序排序输出。
- php数组函数序列之ksort()对数组的元素键名进行升序排序,保持索引关系
- 编写一个通用的求三个元素中最大值得类模版并进行测试
- 输入整型数组和排序标识,对其元素按照升序或降序进行排序
- 44.从键盘输入12个数存入二维数组a[3][4]中,编写程序求出最大元素的值及它所在的行号和列号
- 【php数组函数序列】之ksort()- 对数组的元素键名进行升序排序,保持索引关系
- 【php数组函数序列】之ksort()- 对数组的元素键名进行升序排序,保持索引关系
- 在程序中对ArrayList进行排序,并剔除重复元素