1. 程式人生 > >C++ STL stack介紹與使用方法

C++ STL stack介紹與使用方法

stack(棧)

在學習資料結構中我們知道,棧是一種邏輯資料結構,其具有後進先出的特性。同時,我們也可以把它想象成一個容器,一個真實容器,新增與刪除只能在容器頂部完成。棧的應用非常廣,我們知道任何程式從記憶體進入CPU執行,系統為了保證程式正確的執行,將程式二進位制程式碼存放在一個系統執行棧上面。呼叫函式A,則A的程式碼入棧,函式A中呼叫了函式B,則B入棧,B執行結束後,先出棧,這時再繼續執行函式A。因此這種後進先出的工作方式在很多地方都非常有用。

stack內部資料結構可以是其它容器,因此可以看成是容器的容器。stack內部實現預設使用雙端佇列(deque)來實現,當然你也可以主動指定儲存內省,如vector與list

標頭檔案: #include
建構函式

deque<int> mydeque(3, 100);
vector<int> myvector(2, 200);

stack<int> first;       //申明一個棧物件
stack<int> second(mydeque);    //用一個雙端佇列初始化一個棧物件,預設內部容器為deque
stack<int, vector<int> > third;   //表明third物件內部資料結構為vector
stack<int, vector<int
>
>
fourth(myvector); //用vector初始化fourth物件,必須要主動指定內部容器型別
常用函式
  • 由於stack是一種操作受限制的線性結構,所有的操作只能是在棧頂,因此其內部函式也比較少。
deque<int> mydeque(3, 100);

stack<int> first(mydeque);

first.empty();   //判斷是否為空
int size = first.size();  //返回棧內元素個數
int n;
n = first.top();   //返回棧頂元素
first.pop();   //彈出棧頂元素
first.push(20); //向棧內新增元素
棧的應用
  • 棧的應用非常廣,常見的的圖深度優先搜尋、表示式求職、走迷宮的,下面是利用棧來完成走迷宮的原始碼。

//走迷宮求解
#include <iostream>
#include <stack>

using namespace std;


class Position
{
public:
    int row;   //行
    int col;   //列
    int dir;   //預設為0。 1~4:該點到下一點的方向,分別為右上左下
};

//迷宮大小
#define MAZE_ROWS    3   
#define MAZE_COLS    4

//在迷宮外部加一堵牆
#define NEW_MAZE_ROWS (MAZE_ROWS + 2)
#define NEW_MAZE_COLS (MAZE_COLS + 2)

//起點
#define ENTER_ROW 1
#define ENTER_COL 1

//終點
#define EXIT_ROW    3
#define EXIT_COL    4

//儲存路徑的棧
stack<Position> mazeStack;   

//迷宮地圖
int maze[NEW_MAZE_ROWS][NEW_MAZE_COLS]
= {
    1, 1, 1, 1, 1, 1,
    1, 0, 1, 0, 0, 1,
    1, 0, 0, 0, 1, 1,
    1, 0, 1, 0, 0, 1,
    1, 1, 1, 1, 1, 1
};

//記錄地圖上的某個位置是否已經被訪問過,為1表示訪問過
int mazeFlag[NEW_MAZE_ROWS][NEW_MAZE_COLS];  

//判斷某個點是否被訪問過以及是否可通過
bool pass(Position pos)
{
    if (maze[pos.row][pos.col] == 0 &&
        mazeFlag[pos.row][pos.col] == 0)
    {
        return true;
    }

    return false;
}


//當前點cur的下一個點pos,同時更新當前點到下一個點的方向
//按照上、右、下、左的順序依次獲取當前點的下一個點
bool next_position(Position & cur, Position & nextpos)
{
    nextpos = cur;
    nextpos.dir = 0;    

    //根據當前點到下一個點的方向(目前的方向)
    //來確定下一個點的方向,如果當前點到下一個點的方向已經是4(左)
    //則表明當前點沒有路徑,不應該選擇
    switch (cur.dir)
    {
        case 0:
            nextpos.row -= 1;
            cur.dir = 1;
            break;
        case 1:
            nextpos.col += 1;
            cur.dir = 2;
            break;
        case 2:
            nextpos.row += 1;
            cur.dir = 3;
            break;
        case 3:
            nextpos.col -= 1;
            cur.dir = 4;
            break;
        case 4:
            cur.dir = -1;
            return false;
            break;
        case -1:
            return false;
            break;
    }

    return true;
}


//判斷是否
int maze_solution()
{
    //起點座標為(1, 1)


    Position pos;
    pos.row = 1;
    pos.col = 1;
    pos.dir = 0;
    mazeStack.push(pos);   //起點如棧

    int totalSteps = 0;    //總共走的步數
    while (!mazeStack.empty())  //只要棧不為空,則繼續尋找
    {

        Position curPos = mazeStack.top();   
        Position nextPos;

        //尋找下一個可達的點,同時更新當前位置的方向
        if (next_position(curPos, nextPos))
        {
            //更新當前位置方向
            mazeStack.pop();
            mazeStack.push(curPos);

            if (pass(nextPos))
            {
                mazeFlag[curPos.row][curPos.col] = 1;    //入棧之前標記為已訪問
                mazeStack.push(nextPos);
                totalSteps++;

                if (nextPos.row == EXIT_ROW && nextPos.col == EXIT_COL)
                {
                    //成功找到出口,返回
                    return totalSteps;
                }
            }
        }
        else
        {
            mazeStack.pop();
            totalSteps--;
        }
    }

    return totalSteps;

}


int main()
{

    memset(mazeFlag, 0, sizeof(mazeFlag));

    stack<Position> tmpStack;
    int steps = maze_solution();
    if (steps > 0)
    {
        while (!mazeStack.empty())
        {
            tmpStack.push(mazeStack.top());
            mazeStack.pop();
        }

        cout << "the total steps: " << steps << endl;
        while (!tmpStack.empty())
        {
            cout << tmpStack.top().row << " " << tmpStack.top().col << endl;
            tmpStack.pop();
        }

    }
    else
    {
        cout << "can not find the path.." << endl;
    }



    return 0;
}