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

栈和队列 相关 面试题

2016-10-25 14:01 218 查看



// 1、实现一个栈,要求实现Push(出栈)、 Pop(入栈)、Min(返回最小值的操作) 的时间复杂度为O(1)
 
// 【剑指offer 面试题21】
template<class T>
class StackWithMin
{
public:
    void push(const T& value);
    void pop();
    const T& min() const;
protected:
    stack<T> _min; //  记录每次出栈压栈 最小值
    stack<T> _data; //  存数据
};
 
template<class T>
void StackWithMin<T>::push(const T& value)
{
    _data.push(value);
 
    if (_min.size() == 0 || value < _min.top())
    {
        _min.push(value);
    }
    else
    {
        _min.push(_min.top());
    }
}
 
template<class T>
 void StackWithMin<T>::pop()
 {
     assert(_data.size() > 0 && _min.size() > 0);
 
     _data.pop();
     _min.pop();
 }
 
 template<class T>
const T& StackWithMin<T>::min() const
 {
     assert(_data.size() > 0 && _min.size() > 0);
 
     return _min.top();
 }
 
 
 void test_StackWithMin()
 {
     StackWithMin<int> st;
     st.push(8);
     st.push(5);
     st.push(3);
     st.push(2);
     st.push(2);
 
     int min = st.min();
 
     st.pop();
     st.pop();
     st.pop();
     min = st.min();
 } 


 
//   2、使用两个栈实现一个队列
 // 【剑指offer 面试题7】
 template<class T>
 class CQueue
 {
 public:
     void appendTail(const T& node);
     T deleteHead();
 protected:
     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()
 {
     if (_stack2.size() <= 0)
     {
         while (_stack1.size() > 0)
         {
             T& data = _stack1.top();
             _stack2.push(data);
             _stack1.pop();
         }
     }
 
     if (_stack2.size() == 0)
     {
         throw exception("queue is empty");
     }
 
     T head = _stack2.top();
     _stack2.pop();
 
     return head;
 }
 
 
 void test_CQueue()
 {
     CQueue<int> q;
     q.appendTail(1);
     q.appendTail(2);
     q.appendTail(3);
 
     q.deleteHead();
     q.deleteHead();
     q.deleteHead();
     try
     {
         q.deleteHead();
     }
     catch (const exception& e)
     {
         cout<<e.what();
     }
 
 
 }
 
////3、使用两个队列实现一个栈
 // 【剑指offer 面试题 7 扩展】
 //题目:用两个队列实现一个栈。队列的声明如下,请实现它的pop和push函数。
 
//思路:入栈动作时,如果内部两个队列都为空的话,将数据压入其中一个队列(代码中为m_queue1)。如果其中一个队列已经有数据了,则将数据压入已经有数据的那个队列。出栈动作时,先将有数据的那个队列,除了最后一个入队的数据之外的所有数据输出到另外一个空的队列,然后最后那个数据也出队。
 
#include <queue>
 
 template<class T>
 class CStack
 {
 public:
     void push(const T& node);
     T pop();
 private:
     queue<T> _queue1;
     queue<T> _queue2;
 };
 
 template <class T>
 void CStack<T>::push(const T& node)
 {
     if ((_queue1.empty() && _queue2.empty()) || _queue1.size())
     {
         _queue1.push(node);
     }
     else
     {
         _queue2.push(node);
     }
 }
 
 template<class T>
 T CStack<T>::pop()
 {
     assert(!(_queue1.empty() && _queue2.empty()));
     T node;
     if (_queue1.size())
     {
         while (_queue1.size() > 1)
         {
             node = _queue1.front();
             _queue1.pop();
             _queue2.push(node);
         }
 
         node = _queue1.front();
         _queue1.pop();
     }
     else // _queue2 有数据 _queue1 空
     {
         while (_queue2.size() > 1)
         {
             node = _queue2.front();
             _queue2.pop();
             _queue1.push(node);
         }
 
         node = _queue2.front();
         _queue2.pop();
 
     }
 
     return node;
 }
 
 void test_CStack()
 {
     CStack<char> testStack ;  
    testStack.push('a')  ;  
    testStack.push('b') ;  
    testStack.push('c') ;  
  
    char ch = testStack.pop() ;  
    printf("%c\n",ch) ;  
  
    ch = testStack.pop() ;  
    printf("%c\n",ch) ;  
  
    testStack.push('d') ;  
    ch = testStack.pop() ;  
    printf("%c\n",ch) ;  
  
 }
 
 
 


 
// 4、元素出栈、入栈顺序的合法性。如入栈的序列(1,2,3,4,5),出栈序列为(4,5,3,2,1)
 
 //  【剑指offer 面试题22】
 
 bool IsPopOrder(const int* pPush, const int* pPop, int nLength)
 {
     bool bPossible = false;
 
     if (pPush != NULL && pPop != NULL && nLength > 0)
     {
         const int* pNextPush = pPush;
         const int* pNextPop = pPop;
 
         stack<int> stackData;
 
         while (pNextPop - pPop < nLength)
         {
             while (stackData.empty() || stackData.top() != *pNextPop)
             {
                 if (pNextPush - pPush == nLength)
                 {
                     break;
                 }
 
                 stackData.push(*pNextPush);
 
                 pNextPush++;
             }
 
             if (stackData.top() != *pNextPop)  //  if (pNextPush - pPush == nLength) 跳出的
             {
                 break; //  不匹配
             }
 
             stackData.pop();
 
             pNextPop++;
         }
 
         if (stackData.empty() && pNextPop - pPop == nLength)
         {
             bPossible = true;
         }
     }
 
     return bPossible;
 }
 
 void test_IsPopOrder()
 {
     int PushArry[] = {1,2,3,4,5};
     int PopArray1[] = {3,2,5,4,1};
     int PopArray2[] = {3,2,5,1,4};
     int PopArray3[] = {3,2,5,1,1};
     bool ret1 = IsPopOrder(PushArry, PopArray1,5);
     bool ret2 = IsPopOrder(PushArry, PopArray2,5);
     bool ret3 = IsPopOrder(PushArry, PopArray3,5);
 
 }
 
 
//    5、一个数组实现两个栈
 //  https://code.csdn.net/mishifangxiangdefeng/exerciseforalgorithmsecond/tree/master/src/chapter10/Exercise10_1_2.cpp
 class arrayWithTwoStack
 {
 public:
     arrayWithTwoStack(int size)
         :_top1(0)
         ,_top2(size - 1)
         ,_len(size)
     {
        _s = new int[size];
     }
 
     bool isEmpty(int index);// index指定哪个栈
     void push(int index, int data);
     int pop(int index);
 private:
     int _top1;
     int _top2;  // 两个栈顶坐标
     int _len ;  //  数组长度
     int* _s;    //
 };
 
 bool arrayWithTwoStack::isEmpty(int index)
 {
     if (index == 0 && _top1 == 0)
     {
         return true;
     }
 
     if (index == 1 && _top2 == _len - 1)
     {
         return true;
     }
 
     return false;
 }
 
 void arrayWithTwoStack::push(int index, int data)
 {
     // 已满
     if (_top1 >= _top2)
     {
         throw exception("error: overflow");
     }
 
     // 对栈1操作
     if (index == 0)
     {  
         _s[_top1] =data;
         _top1++;
     }
     else if (index == 1)
     {
         _s[_top2] = data;
                  _top2--;
     }
 }
 
 
 //出栈 
 int arrayWithTwoStack::pop(int index)
 {
     int ret;
 
     if (index == 0)
     {
         //栈1空
         if (_top1 == 0)
         {
             throw exception("error: stack 0 is empty");
         }
         else
         {
             ret = _s[--_top1];
         }
     }
     else if (index == 1)
     {
         //栈 2 空
         if (_top2 == _len - 1)
         {
             throw exception("error: stack 1 is empty");
         }
         else
         {
             ret = _s[++_top2];
         }
     }
 
     return ret;
 }
 
 
 void test_arrayWithTwoStack()
 {
     arrayWithTwoStack S(6);
     // s0 123  54 s1 
     S.push(0,1);
     S.push(0,2);
     S.push(0,3);
 
     try{
     S.push(1,4);
     S.push(1,5);
     }
     catch(exception e)
     {
         cout<<e.what()<<endl;
     }
 
 
     S.pop(0);
     S.pop(1);
     S.pop(1);
     bool em = S.isEmpty(1);
 }
 
 
 
 

本文出自 “城市猎人” 博客,请务必保留此出处http://alick.blog.51cto.com/10786574/1767118
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: