当前位置:   article > 正文

堆栈相关面试题(详解)_c语言面试 堆栈

c语言面试 堆栈

1. 实现一个栈,要求实现Push(出栈)、Pop(入栈)、Min(返回最小值的操作)时间复杂度为O(1)。

分析:设计两个栈,一个栈用来push 、pop操作,另一个栈用来保存当前最小值Min。当push元素小于等于Min栈顶元素时,将其压入Min栈顶,当pop元素等于Min栈顶元素时,两个栈均要pop出栈顶元素。下图为各种情况的优缺点分析。

  1. class StackWithMin
  2. {
  3. public:
  4. StackWithMin()
  5. {}
  6. ~StackWithMin()
  7. {}
  8. void Push(const int& x)
  9. {
  10. s1.push(x);
  11. if(s2.empty() || x <= s2.top())
  12. {
  13. s2.push(x);
  14. }
  15. }
  16. void Pop()
  17. {
  18. assert(s1.size()>0 && s2.size()>0);
  19. if(s1.top() == s2.top())
  20. {
  21. s2.pop();
  22. }
  23. s1.pop();
  24. }
  25. int Min()
  26. {
  27. assert(s1.size()>0 && s2.size()>0);
  28. return s2.top();
  29. }
  30. private:
  31. stack<int> s1;
  32. stack<int> s2; //用于保存最下元素
  33. };

2. 使用两个栈实现一个队列。

分析:一个栈用来push数据,一个栈用来pop数据。

图解

实现

  1. //使用两个栈实现一个队列。
  2. class Queue
  3. {
  4. public:
  5. void push(int node) {
  6. stack1.push(node);
  7. }
  8. int pop() {
  9. if(stack2.empty())
  10. {
  11. while(!stack1.empty())
  12. {
  13. stack2.push(stack1.top());
  14. stack1.pop();
  15. }
  16. }
  17. int top = stack2.top();
  18. stack2.pop();
  19. return top;
  20. }
  21. private:
  22. stack<int> stack1;
  23. stack<int> stack2;
  24. };

 

3. 使用两个队列实现一个栈。

分析:使用两个队列不断的倒换元素,实现一个栈。下面为图解,以及代码的实现过程。

图解

  1. #include<iostream>
  2. #include<queue>
  3. using namespace std;
  4. template <class T>
  5. class QueueToStack
  6. {
  7. public:
  8. QueueToStack()
  9. {}
  10. ~QueueToStack()
  11. {}
  12. void Push(T x)
  13. {
  14. if(q1.size()>0)//若q1不为NULL时,在q1中插入
  15. {
  16. q1.push(x);
  17. }
  18. else if(q2.size()>0)//若q2不为NULL时,在q1中插入
  19. {
  20. q2.push(x);
  21. }
  22. else
  23. {
  24. q1.push(x);//两者均为NULL时,插入到q1
  25. }
  26. }
  27. void Pop()
  28. {
  29. if(q1.size()==0)//如果queue1为空
  30. {
  31. while(q2.size()>1)//保证queue2中有一个元素,将其余元素保存到queue1中
  32. {
  33. q1.push(q2.front());
  34. q2.pop();
  35. }
  36. q2.pop();
  37. }
  38. else//如果queue2为空
  39. {
  40. while(q1.size()>1)//保证queue2中有一个元素,将其余元素保存到queue1中
  41. {
  42. q2.push(q1.front());
  43. q1.pop();
  44. }
  45. q1.pop();
  46. }
  47. }
  48. T Top()
  49. {
  50. if(q1.size()==0)//如果queue1为空
  51. {
  52. while(q2.size()>1)//保证queue2中有一个元素,将其余元素保存到queue1中
  53. {
  54. q1.push(q2.front());
  55. q2.pop();
  56. }
  57. T& data=q2.front();
  58. q1.push(q2.front());
  59. q2.pop();
  60. return data;
  61. }
  62. else//如果queue2为空
  63. {
  64. while(q1.size()>1)//保证queue2中有一个元素,将其余元素保存到queue1中
  65. {
  66. q2.push(q1.front());
  67. q1.pop();
  68. }
  69. T& data=q1.front();
  70. q2.push(q1.front());
  71. q1.pop();
  72. return data;
  73. }
  74. }
  75. bool Empty()
  76. {
  77. return (q1.empty() && q2.empty());
  78. }
  79. private:
  80. queue<T> q1;
  81. queue<T> q2;
  82. };

4. 元素出栈、入栈顺序的合法性。如入栈的序列(1,2,3,4,5),出栈序列为(4,5,3,2,1)。

分析:借助辅助栈,如果下一个弹出的数字刚好是栈顶数字,那么直接弹出。如果下一个弹出的数字不在栈顶,把压栈序列中还没有入栈的数字压人辅助栈,直到把下一个需要弹出的数字压入栈顶为止。如果所有的数字都压入了仍然没有找到下一个弹出的数字,那么该序列不可能是一个弹出序列。

  1. class Solution {
  2. public:
  3. bool IsPopOrder(vector<int> pushV,vector<int> popV)
  4. {
  5. if(pushV.size() == 0 || popV.size() == 0)
  6. {
  7. return false;
  8. }
  9. if(pushV.size() != popV.size())
  10. {
  11. return false;
  12. }
  13. stack<int> s; //借助辅助栈
  14. int j=0;
  15. for(int i=0; i<popV.size(); ++i)
  16. {
  17. s.push(pushV[i]);
  18. //当栈顶元素和出栈序列元素相等时,出栈
  19. while(j<popV.size() && s.top() == popV[j])
  20. {
  21. s.pop();
  22. ++j;
  23. }
  24. }
  25. return s.empty();
  26. }
  27. };

5. 一个数组实现两个栈。

   分析:一个数组实现两个栈,分别从数据开始,和数组末端实现。当两个指针相当时,进行扩容。扩容时,需要将原数组的数据写入新数组。

  1. #include <iostream>
  2. #include<assert.h>
  3. using namespace std;
  4. template<class T>
  5. class TwoStack
  6. {
  7. public:
  8. //构造
  9. TwoStack()
  10. :_arr(NULL)
  11. ,_top1(0)
  12. ,_top2(0)
  13. ,_capacity(0)
  14. {
  15. CheckCapacity();
  16. }
  17. //析构
  18. ~TwoStack()
  19. {
  20. if(NULL != _arr) //_arr不为NULL时,释放_arr
  21. {
  22. delete[] _arr;
  23. }
  24. }
  25. //拷贝构造
  26. TwoStack(const TwoStack<T>& ts)
  27. :_arr(new T[ts._capacity-ts._top2+ts._top1])
  28. ,_top1(ts._top1)
  29. ,_top2(_top1)
  30. ,_capacity(ts._capacity-ts._top2+ts._top1)
  31. {
  32. //拷贝数据
  33. for(size_t i=0; i<_top1; i++)
  34. {
  35. _arr[i] = ts._arr[i];
  36. }
  37. size_t j = ts._capacity-1;
  38. for(size_t i=_capacity-1; i>_top2;i--,j--)
  39. {
  40. _arr[i] = ts._arr[j];
  41. }
  42. }
  43. //复制运算符重载
  44. TwoStack<T>& operator=(TwoStack<T> ts)
  45. {
  46. int * tmp = ts._arr;
  47. _top1 = ts._top1;
  48. _top2 = ts._top2;
  49. _capacity = ts._capacity;
  50. swap(_arr,tmp);
  51. return *this;
  52. }
  53. //push 、pop、top、size、empty
  54. void Push1(const int& x)
  55. {
  56. CheckCapacity();
  57. _arr[_top1++] = x;
  58. }
  59. void Push2(const int& x)
  60. {
  61. CheckCapacity();
  62. _arr[_top2--] = x;
  63. }
  64. void Pop1()
  65. {
  66. if(Size1() == 0)
  67. {
  68. return;
  69. }
  70. --_top1;
  71. }
  72. void Pop2()
  73. {
  74. if(Size2() == 0)
  75. {
  76. return;
  77. }
  78. --_top2;
  79. }
  80. int Top1()
  81. {
  82. assert(_top1 > 0);
  83. return _arr[_top1-1];
  84. }
  85. int Top2()
  86. {
  87. assert(_top2 < _capacity-1);
  88. return _arr[_top2+1];
  89. }
  90. size_t Size1()
  91. {
  92. return _top1;
  93. }
  94. size_t Size2()
  95. {
  96. return _capacity - _top2 - 1;
  97. }
  98. bool Empty1()
  99. {
  100. if(_top1 == 0)
  101. {
  102. return true;
  103. }
  104. return false;
  105. }
  106. bool Empty2()
  107. {
  108. if(_top2 == _capacity-1)
  109. {
  110. return true;
  111. }
  112. return false;
  113. }
  114. protected:
  115. void CheckCapacity()
  116. {
  117. //1.开始时扩容 2._top1 == _top2时,扩容
  118. if(NULL == _arr)//开始时,当数组为NULL时,给_arr分配空间
  119. {
  120. _capacity += 2;
  121. _arr = new int[_capacity];
  122. _top2 = _capacity - 1;
  123. return;
  124. }
  125. if(_top1 == _top2) //如果_top1==_top2时,应该进行扩容
  126. {
  127. size_t newcapacity = _capacity*2;
  128. int* tmp = new int[newcapacity];
  129. //拷贝数据
  130. for(size_t i=0; i<_top1; ++i)
  131. {
  132. tmp[i] = _arr[i];
  133. }
  134. size_t j = newcapacity - 1;
  135. for(size_t k=_capacity-1; k>_top2; --k)
  136. {
  137. tmp[j] = _arr[k];
  138. --j;
  139. }
  140. _top2 = j;
  141. _capacity = newcapacity;
  142. _arr = tmp;
  143. }
  144. }
  145. private:
  146. T * _arr; //析构时,应销毁数组中的内容
  147. size_t _top1; //top1、top2分别表示栈的下标
  148. size_t _top2;
  149. size_t _capacity;
  150. };

 

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/73591
推荐阅读
相关标签
  

闽ICP备14008679号