面試題——棧與隊列的應用(下)

棧與隊列的應用

       在“棧與隊列的應用(上)”中,通過討論兩個隊列實現一個棧和兩個棧實現一個隊列這兩個問題,我們對棧和隊列也有了更深的瞭解,下面我們主要來討論以下兩個面試中常常會遇到的問題:

1)一個數組實現兩個棧

2)實現一個棧,能夠push、pop、min(求棧中最小的數據)


問題一:

      對於一個數組,我們如何能夠使其成爲兩個棧?根據數組和棧的特點,我們不難發現可以將數組的兩端作爲棧的棧底,使用兩個指針分別指向數組的開始位置和末尾位置,假設將數組的左邊作爲棧s1,數組的右邊作爲棧s2,若s1中的棧頂指針向後在偏移一個位置與另一個指針同時指向一塊空間,此時就稱爲“棧滿”,不能進行插入操作。如果想要對棧進行操作,就必須要指定對哪個棧操作。這裏使用了兩個整形變量用來記錄棧s1和棧s2的棧頂的位置下標,對其進行操作。


下面爲簡單的圖示:

650) this.width=650;" width="469" height="152" title="無標題.png" style="width:468px;height:127px;" src="http://s2.51cto.com/wyfs02/M01/7F/25/wKiom1cUyGeDapT8AAAOQWIGo3o224.png" alt="wKiom1cUyGeDapT8AAAOQWIGo3o224.png" />


下面是具體的程序代碼:


//一個數組實現兩個棧
//方法一:(靜態數組)
#include <iostream>
using namespace std;
#include <stdlib.h>
#define MAX 100

template <class T>
class TwoStack
{
public:
     TwoStack()     //構造函數
          :_array(new T[MAX])
          , lefttop0(-1)
          , righttop1(MAX)
     { }

public:
     void Push(T x, int i)     //壓棧,將數據壓入i號棧中
     {
          if (lefttop0 + 1 == righttop1)
          {
               cout << "棧已滿,不能壓棧!";
               return;
          }
          else
          {
               switch (i)
               {
                   case 0:                       //壓入0號棧中
                        lefttop0++;
                        _array[lefttop0] = x;
                        break;
                   case 1:               //壓入1號棧中
                        righttop1--;
                        _array[righttop1] = x;
                        break;
                   default:
                        break;
               }
          }
     }
     
     void Pop(int i)     //i號棧、元素出棧
     {
          switch (i)
          {
              case 0:
                   if (lefttop0 == -1)
                   {
                        cout << "The Stack is Empty!" << endl;
                   }
                   lefttop0--;
                   break;
              case 1:
                   if (righttop1 == MAX)
                   {
                        cout << "The Stack is Empty!" << endl;
                   }
                   righttop1++;
                   break;
              default:
                   break;
          }
     }
     
     T& top(int i)          //讀取i號棧中元素
     {
          if (i == 0)
          {
               return _array[lefttop0];
          }
          else
          {
               return _array[righttop1];
          }
     }
     
     void Display(int i)      //打印i號棧的元素
     {
          if (i == 0)
          {
               cout << "打印0號棧中的元素:" << endl;
               while (lefttop0 != -1)
               {
                    cout << _array[lefttop0] << " ";
                    lefttop0--;
               }
               cout << endl;
          }
          else if (i == 1)
          {
               cout << "打印1號棧中的元素:" << endl;
               while (righttop1 != MAX)
               {
                    cout << _array[righttop1] << " ";
                    righttop1++;
               }
               cout << endl;
          }
     }
     
private:
     T* _array;
     int lefttop0;
     int righttop1;
};


問題二:

       這個問題主要是要實現求棧中最小數據,完成這個功能,就需要藉助另一個棧對最小數據進行保存,假設現有棧s1和棧s2,當向s1中插入第一個數據時,同時也向s2中插入相同的數據,下來在向s1中插入第二個數據,此時若第二個數據小於s2的棧頂數據,此時也將與之相同的數據插入s2中,若第二個數據小於s2的棧頂數據,則不用向s2中插入數據,按照這樣的方式插入數據。現在就能夠顯而易見的知道s2中的棧頂數據就是棧s1中的最小數據。

       如果需要對s1中數據進行刪除,如若s1中要刪除的數據與s2中要刪除的數據相同,則棧s2中同樣刪除棧頂元素,若不等,則將s1中棧頂元素刪除就行,不需要刪除s2中的數據。這樣就能夠始終保持s2中棧頂數據爲棧s1中的最小數據。


下面是簡單的圖示:

650) this.width=650;" width="417" height="271" title="無標題.png" style="width:417px;height:199px;" src="http://s4.51cto.com/wyfs02/M02/7F/25/wKiom1cUza2hBQvPAAAWHmLQRYg900.png" alt="wKiom1cUza2hBQvPAAAWHmLQRYg900.png" />

下面爲具體的程序代碼:


//判斷出對序列中的最小數據
//實現一個棧,要求實現Push、pop、min(返回棧中最小值)的時間複雜度爲o(1)。
#include <iostream>
using namespace std;
#include <stdlib.h>
#include <stack>

template <class T>
class Stack
{
public:
     void Push(const T& x)
     {
          if (s1.empty() && s2.empty())
          {
               s1.push(x);
               s2.push(x);
          }
          else if (!s1.empty())
          {
               if (x < s2.top())
               {
                    s1.push(x);
                    s2.push(x);
               }
               else
               {
                    s1.push(x);
               }
          }
     }
     
     void Pop()
     {
          if (!s1.empty() && !s2.empty())
          {
               if (s1.top() == s2.top())
               {
                    s1.pop();
                    s2.pop();
               }
               else
               {
                    s1.pop();
               }
          }
     }
     
     T minNumber()
     {
          return s2.top();
     }
private:
     stack<T> s1;
     stack<T> s2;
};




本文出自 “無心的執着” 博客,謝絕轉載!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章