您的位置:首页 > 职场人生

程序员面试金典: 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐