棧與隊(duì)列

  • 特性: LIFO, 后進(jìn)先出。比較形象點(diǎn)的比喻就是:洗盤(pán)子。你會(huì)將洗干凈的盤(pán)子放在最上面,而你需要用盤(pán)子的時(shí)候,也是拿最上面的。
  • 實(shí)現(xiàn):可以用數(shù)組,向量,鏈表等方式實(shí)現(xiàn)
  • 操作:
    1. push: 將元素X放入棧頂
    2. pop: 將棧頂元素移除棧
    3. top: 獲取棧頂元素

用數(shù)組實(shí)現(xiàn)棧

數(shù)組S,top為數(shù)組最后一個(gè)元素的下標(biāo)。

  • push操作: ++top; S[top] = X;
  • pop操作: --p; (每次進(jìn)行pop操作之前,必須判斷數(shù)組是否為空,則:top == -1)

swift 用數(shù)組實(shí)現(xiàn)棧

struct Stack<T> {
    // 對(duì)數(shù)組進(jìn)行初始化
    fileprivate var array = [T]()
    
    public var isEmpty: Bool {
        return array.isEmpty
    }
    
    public var count: Int {
        return array.count
    }
    
    public mutating func push(_ element: T) {
        array.append(element)
    }
    
    public mutating func pop() -> T? {
        // 數(shù)組不為空時(shí),返回并移除最后一個(gè)元素;空時(shí),返回nil
        return array.popLast()
    }
    
    public var top: T? {
        //數(shù)組不為空時(shí),返回最后一個(gè)元素;空時(shí),返回nil
        return array.last
    }
}

// 使用時(shí),指定 T 的類(lèi)型
var stackStr = Stack<Character>()
let stackInt = Stack<Int>()

隊(duì)列

  • 特性:FIFO,先進(jìn)先出。

  • 實(shí)現(xiàn): 可以用數(shù)組,向量,鏈表,雙編隊(duì)列等實(shí)現(xiàn)。但是難度比較大,還是推薦用語(yǔ)言現(xiàn)有的隊(duì)列。

  • 操作:

    1. push: 在隊(duì)尾添加一個(gè)元素。
    2. pop: 彈出隊(duì)首元素。
    3. empty: 空隊(duì)列
    4. full: 滿隊(duì)列

用數(shù)組實(shí)現(xiàn)隊(duì)列

用有限大小的緩沖區(qū)來(lái)做例子,用Q數(shù)組實(shí)現(xiàn)緩沖區(qū)。隊(duì)首front, 隊(duì)尾nail(指向最后一個(gè)元素的下一個(gè)位置)

  • push操作:將元素X放到隊(duì)尾, nail 指向下一個(gè)位置。如果說(shuō)原本nail就指向數(shù)組最后一個(gè)位置,添加了元素后,則應(yīng)該指向數(shù)組第一個(gè)位置,用來(lái)實(shí)現(xiàn)循環(huán)隊(duì)列。
Q[nail] = X;

// 用判斷比取模運(yùn)行更快,nail = (nail + 1) % Q.size()
++nail; 
if (nail == Q.size())  nail = 0;  
  • pop操作: 彈出隊(duì)首元素
// 用判斷比取模運(yùn)行更快,front = (front + 1) % Q.size()
++front; 
if (front == Q.size())  front = 0;
  • empty判斷:如果數(shù)組中只剩下一個(gè)元素,然后執(zhí)行pop操作,就是空隊(duì)列了,也就是說(shuō)front 與nail 指向同一個(gè)位置。
bool func isEmpty {
    return front == nail;
}
  • full判斷:如果數(shù)組中還差一個(gè)元素就滿了,然后再執(zhí)行push操作,就是滿隊(duì)列了,也就是說(shuō)nail 與front指向同一個(gè)位置。但是,這個(gè)條件與空隊(duì)列的判斷條件一致。
    原因:
    出現(xiàn)這種情況可以用抽屜原理來(lái)解釋?zhuān)杭僭O(shè)確定了frant的值,而nail的取值情況有Q.size()種可能,而隊(duì)列有Q.size() + 1中狀態(tài)。將N+ 1種狀態(tài)放置在N種可能中,必然會(huì)造成有兩種狀態(tài)出現(xiàn)重復(fù)的情況。
    解決:
    1. 采用空一個(gè)元素的方式,也就是當(dāng)數(shù)組還有一個(gè)空置位置的時(shí)候,nail + 1 == front 就宣布隊(duì)列已經(jīng)滿了,讓隊(duì)列減少一個(gè)狀態(tài)。
bool func isFull {
    return front == (nail + 1 == Q.size() ? 0 : nail + 1);
}
  1. 設(shè)置計(jì)數(shù)器count, 計(jì)算隊(duì)列的元素個(gè)數(shù)。在push操作時(shí),++count; 在pop操作時(shí), --count。所以,count == 0時(shí),為空隊(duì)列。當(dāng)count == Q.size()時(shí),為滿隊(duì)列。
func push(int x) {
    Q[nail] = x;

    // 用判斷比取模運(yùn)行更快,nail = (nail + 1) % Q.size()
    ++nail; 
    if (nail == Q.size())  nail = 0;  
        ++count;
}

func  pop() {
    ++front; 
    if (front == Q.size())  front = 0;
        --count;
}

bool func isFull() {
    return (count == Q.size());
}

bool func isEmpty () {
    return (count == 0);
}

Swift 用數(shù)組實(shí)現(xiàn)隊(duì)列

struct Queue<T> {
    public var count: Int   // 計(jì)數(shù)器,用來(lái)判斷隊(duì)列是否已滿
    fileprivate var array = [T]()
    
    public var isEmpty: Bool {
        // 數(shù)組是空時(shí),隊(duì)列為空
        return array.count == 0
    }
    
    public var isFull: Bool {
        return count == array.count
    }

    public mutating func push(_ element: T) {
        if !isFull {
            // 數(shù)組沒(méi)有滿時(shí),可添加元素
            array.append(element)
        }
    }
    
    public mutating func pop() -> T? {
        if !isEmpty {
            //數(shù)組非空時(shí),可移除元素
            let first = array.first!
            array.removeFirst()
            
            return first
        }
        
        return nil
    }
    
    public var front: T? {
        return array.first
    }
    
    // 需要初始化 count 
    init(_ queueCount: Int) {
        self.count = queueCount
    }
}

// 使用queue 
var queueInt = Queue<Int>(10)
var queueStr = Queue<String>(20)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1.棧 1.1.棧的定義 棧(stack)是限定僅在表尾(棧頂 top)進(jìn)行插入和刪除操作的后進(jìn)先出的線性表。 p...
    JonyFang閱讀 1,592評(píng)論 0 21
  • 隊(duì)列的插入操作在表的一端進(jìn)行而其他操作在表的另一端進(jìn)行棧的操作只能在表的一端進(jìn)行棧和隊(duì)列成為操作受限的線性表?xiàng)#⊿...
    銀河的精神家園閱讀 627評(píng)論 0 0
  • 棧 棧是限定僅在表尾進(jìn)行插入和操作的線性表;允許插入和刪除的一端稱為棧頂,另一端稱為棧底,不含任何數(shù)據(jù)元素的棧稱為...
    Bangys閱讀 542評(píng)論 0 0
  • 棧 棧是限定僅在表尾進(jìn)行插入和刪除操作的線性表。 棧又稱為后進(jìn)先出(Last In First Out )的線性表...
    jtsky閱讀 739評(píng)論 0 0
  • 作者:任爭(zhēng)氣 西安的春天很短 短的似乎只有一夜 沒(méi)等回味 已經(jīng)流逝 昨天 還是雪壓迎春 今天 就是綠滿枝頭 年剛一...
    醉美長(zhǎng)安閱讀 559評(píng)論 17 68

友情鏈接更多精彩內(nèi)容