剑指offer 编程题(5):两个栈实现队列,两个队列实现栈
2017-12-14 16:10
281 查看
问题1:用两个栈实现一个队列,实现队列的push和delete操作
栈的特性是先进后出(FILO),队列的特性是先进先出(FIFO),在实现delete时,我们的难点是如何将栈中最底层的数据拿出来,我们有两个栈,所以我们可以将一个栈中的数据依次拿出来压入到另一个为空的栈,另一个栈中数据的顺序恰好是先压入栈1的元素此时在栈2的上面,为了实现效率的提升,我们在delete时,判断栈2是否有数据,如果有的话,直接删除栈顶元素,在栈2为空时才将栈1的数据压入到栈2中,从而提高程序的运行效率,实现过程可以分为下面几个步骤:
1、push操作时,一直将数据压入到栈2中
2、delete操作时,首先判断栈2是否为空,不为空的情况直接删除栈2栈顶元素,为空的话将栈1的数据压入到栈2中,再将栈2栈顶元素删除。
实现代码如下:
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
运行结果如下:
问题2:用两个队列实现一个栈
因为队列是先进先出,所以要拿到队列中最后压入的数据,只能每次将队列中数据pop到只剩一个,此时这个数据为最后压入队列的数据,在每次pop时,将数据压入到另一个队列中。每次执行delete操作时,循环往复。(感觉效率低)每次删除时间复杂度O(N)
代码如下:
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
两
bf02
个问题解决思路类似,主要就是要合理使用队列和栈的特点,并注意程序的效率。
用两个栈实现一个队列的功能?要求给出算法和思路!
<分析>:
入队:将元素进栈A
出队:判断栈B是否为空,如果为空,则将栈A中所有元素pop,并push进栈B,栈B出栈;
如果不为空,栈B直接出栈。
用两个队列实现一个栈的功能?要求给出算法和思路!
<分析>:
入栈:将元素进队列A
出栈:判断队列A中元素的个数是否为1,如果等于1,则出队列,否则将队列A中的元素
以此出队列并放入队列B,直到队列A中的元素留下一个,然后队列A出队列,再把
队列B中的元素出队列以此放入队列A中。
栈的特性是先进后出(FILO),队列的特性是先进先出(FIFO),在实现delete时,我们的难点是如何将栈中最底层的数据拿出来,我们有两个栈,所以我们可以将一个栈中的数据依次拿出来压入到另一个为空的栈,另一个栈中数据的顺序恰好是先压入栈1的元素此时在栈2的上面,为了实现效率的提升,我们在delete时,判断栈2是否有数据,如果有的话,直接删除栈顶元素,在栈2为空时才将栈1的数据压入到栈2中,从而提高程序的运行效率,实现过程可以分为下面几个步骤:
1、push操作时,一直将数据压入到栈2中
2、delete操作时,首先判断栈2是否为空,不为空的情况直接删除栈2栈顶元素,为空的话将栈1的数据压入到栈2中,再将栈2栈顶元素删除。
实现代码如下:
template <typename T> class CQueue { public: CQueue(void) {} ~CQueue(void) {} void appendTail(const T& node); T deleteHead(); private: stack<T> stack1; stack<T> stack2; }; template<class T> void CQueue<T>::appendTail(const T& node)//在队列尾部添加数据 { stack1.push(node); } template<class T> T CQueue<T>::deleteHead() { T tmp = 0; if (stack2.empty()) //若栈2为空 { while (!stack1.empty()) { tmp = stack1.top(); stack2.push(tmp); stack1.pop(); } } tmp = stack2.top(); stack2.pop(); return tmp; }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
运行结果如下:
问题2:用两个队列实现一个栈
因为队列是先进先出,所以要拿到队列中最后压入的数据,只能每次将队列中数据pop到只剩一个,此时这个数据为最后压入队列的数据,在每次pop时,将数据压入到另一个队列中。每次执行delete操作时,循环往复。(感觉效率低)每次删除时间复杂度O(N)
代码如下:
template <typename T> class CStack { public: CStack(void) {} ~CStack(void) {} void appendTail(const T& node); T deleteHead(); private: queue<T> q1; queue<T> q2; }; template<class T> void CStack<T>::appendTail(const T& node)//在栈尾部添加数据 { if (!q1.empty())//不为空的执行push操作 { q1.push(node); } else { q2.push(node); } } template<class T> T CStack<T>::deleteHead() { int ret = 0; if (q1.empty()) { int i = q2.size(); while (i > 1 )//将q2队列中的数据pop到只剩一个 { q1.push(q2.front()); q2.pop(); --i; } ret = q2.front(); q2.pop(); } else { int i = q1.size(); while (i > 1) { q2.push(q1.front()); q1.pop(); --i; } ret = q1.front(); q1.pop(); } return ret;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
两
bf02
个问题解决思路类似,主要就是要合理使用队列和栈的特点,并注意程序的效率。
用两个栈实现一个队列的功能?要求给出算法和思路!
<分析>:
入队:将元素进栈A
出队:判断栈B是否为空,如果为空,则将栈A中所有元素pop,并push进栈B,栈B出栈;
如果不为空,栈B直接出栈。
用两个队列实现一个栈的功能?要求给出算法和思路!
<分析>:
入栈:将元素进队列A
出栈:判断队列A中元素的个数是否为1,如果等于1,则出队列,否则将队列A中的元素
以此出队列并放入队列B,直到队列A中的元素留下一个,然后队列A出队列,再把
队列B中的元素出队列以此放入队列A中。
相关文章推荐
- 《剑指offer》编程题java实现(十六):用两个栈实现队列
- 剑指Offer_编程题 用两个栈实现队列
- 剑指offer面试题7:用两个栈实现队列
- 剑指offer 面试题7 两个栈实现队列 java版答案
- 《剑指offer》(面试题7):用两个栈实现队列
- 牛客《剑指Offer》 用两个栈实现队列
- 剑指offer(java代码)——用两个栈实现队列
- 《剑指offer》——用两个栈实现队列
- JAVA实现用两个栈来实现一个队列,完成队列的Push和Pop操作(《剑指offer》)
- 剑指offer——面试题7:用两个栈实现队列
- 剑指offer(二)之用两个栈实现队列
- 剑指offer-Java-用两个栈实现队列
- 《剑指offer》9.用两个栈实现队列
- 剑指offer 07 用两个栈实现队列
- 《剑指Offer》面试题七之用两个栈实现队列
- 《剑指offer》面试题七 用两个栈实现队列
- 剑指offer两个栈实现队列的c++写法(九度1512)
- 《剑指offer》——用两个栈实现队列
- 剑指offer :07 用两个栈实现队列
- 《剑指offer》用两个栈实现队列