Upgrade to Pro — share decks privately, control downloads, hide ads and more …

師大資工系ACM-ICPC讀書會:參、堆疊與佇列

Cd57bf203d03722597a5c88007eb1c17?s=47 Maplewing
October 25, 2013

 師大資工系ACM-ICPC讀書會:參、堆疊與佇列

Cd57bf203d03722597a5c88007eb1c17?s=128

Maplewing

October 25, 2013
Tweet

Transcript

  1. 參、堆疊與佇列 師大資工系 灆洢 取自於<提升程式設計的邏輯思考力> 6.1

  2. 堆疊

  3. •先進後出(FILO、LIFO) •push 1: 1 •push 5: 1 5 •push 3:

    1 5 3 •push 4: 1 5 3 4 •pop: 1 5 3 // => 4 •push 6: 1 5 3 6 •pop: 1 5 3 // => 6 堆疊
  4. • ex. • stack<int> aStack; • aStack.empty() // =>判斷堆疊是否為空 •

    aStack.size() // =>目前堆疊大小 • aStack.push(2) // => 推入值進堆疊中 • aStack.pop() // => 移除堆疊最上方之值 (注意:不會回傳值) • aStack.top() // => 取得堆疊最上方之值 STL: stack<T>
  5. •中序: 5 * (3 + 2) / (8 - 6)

    //前中後 •前序: * 5 / + 3 2 - 8 6 // 中前後 •後序: 5 3 2 + * 8 6 - / // 前後中 前序、中序、後序 運算式
  6. • ( ( 9 + 8 ) * 8 +

    ( ( 8 + 6 ) * ( 2 + 6 ) ) ) // => O • ( ( 9 + 8 ) * 8 + ( ( 8 + 6 * ( 2 + 6 ) ) ) // => X • 運用堆疊 • 遇左括弧推入堆疊中 • 遇右括弧推出左括弧 括弧檢查
  7. • 中序: 5 * (3 + 2) / (8 -

    6) //前中後 • 後序: 5 3 2 + * 8 6 - / // 前後中 • 從左而右,遇值即輸出。 • 遇運算子則檢查堆疊最上層運算子運算優先度是否高於自己 • 同運算優先度則越左邊優先度應越高 • 左括弧必定推入堆疊中,並得等右括弧出現才可推掉 中序式轉後序式
  8. • 5 * (3 + 2) / (8 - 6)

    // => 12 (or 12.5) • 利用運算元和運算子兩個堆疊來實作 • 與中序式轉後序式差不多 • 遇到運算元直接推入堆疊中 • 遇到運算子,跟中序式轉後序式一樣的判斷 • 若要推出則拿出兩個運算元計算完後堆回運算元的堆疊中 運算式運算
  9. 範例:Rails (UVa 514)

  10. 佇列

  11. 佇列 •先進先出(FIFO、LILO) •enqueue 1: 1 •enqueue 5: 1 5 •enqueue

    3: 1 5 3 •enqueue 4: 1 5 3 4 •dequeue: 5 3 4 // => 1 •enqueue 6: 5 3 4 6 •dequeue: 3 4 6 // => 5
  12. STL: queue<T> • ex. • queue<int> aQueue; • aQueue.empty() //

    =>判斷佇列是否為空 • aQueue.size() // =>目前佇列大小 • aQueue.push(2) // => 推入值進佇列中 • aQueue.pop() // => 移除佇列最前方之值 (注意:不會回傳值) • aQueue.front() // => 取得佇列最前方之值 • aQueue.back() // => 取得佇列最後方之值
  13. 應用 • 最常被應用於BFS(廣度優先搜尋)當中 • 不過因為尚未講到樹與圖,所以先有印象就好 • 跟排隊有關的問題大抵上都要用到Queue • 作業系統的排程 •

    Queueing Model • 作業系統、無線通訊、資料通訊課會上到XD (全部都是賀老師的課XD!!) • Event-Driven Programming (事件處理型程式設計)
  14. 範例:Throwing cards away I (UVa 10935)

  15. 合併應用

  16. • 將佇列中的元素不再依照進入順序輸出,依照另外一種可計算之 順序重新輸出。 • enqueue 3: 3 • enqueue 1:

    1 3 • enqueue 5: 1 3 5 • dequeue: 3 5 // => 1 • dequeue: 5 // => 3 • dequeue: // => 5 • 基本做法:利用二分搜尋找到該值應該插入的位置後插入。 • 可用陣列或串列實作 排序搜索+佇列=優先佇列(Priority Queue)
  17. • ex. 預設是大值先出,可利用compare換 • priority_queue<int> pQueue; • pQueue.empty(); // =>

    判斷是否為空 • pQueue.size(); // => 取得優先佇列中的大小 • pQueue.push(30); // =>推值進優先佇列中 • pQueue.pop(); // => 取得優先佇列中最大的值 STL: priority_queue<T(, container, compare)>
  18. • 前後兩端皆可插入跟刪除 • Push Back 1: 1 • Push Back

    3: 1 3 • Push Front 5: 5 1 3 • Push Front: 7: 7 5 1 3 • Pop Back: 7 5 1 // => 3 • Pop Front: 5 1 // => 7 堆疊+佇列=雙向佇列(Double-Ended Queue)
  19. • ex. • deque<int> aDeque; • aDeque.empty(); // =>判斷是否為空 •

    aDeque.size(); // => 得到目前大小 • aDeque.front(); // => 拿到最前方的值 • aDeque.back(); // => 拿到最後方的值 • aDeque.push_back(10); // => 增加值於後方 • aDeque.push_front(10); // => 增加值於前方 • aDeque.pop_back(); // => 移除最後方的值 • aDeque.pop_front(); // => 移除最前方的值 STL: deque<T>
  20. •127 •101 •133 •10152 •673 作業 •442 •11111 •11234 •540

    •10050
  21. 謝謝聆聽 資料取自於<提升程式設計的邏輯思考力> 6.1