揹包 佇列和棧的實現(基於陣列)

2022-09-19 21:48:27 字數 3373 閱讀 3909

下面介紹揹包、佇列和棧(基於陣列)的實現,是對《演算法(第四版)》1.3 節的部分總結。

api 是開發的起點,所以先給出 api:

表 1 泛型可迭代的基礎集合資料型別的 api

總的思路是先給出乙個簡單而經典的實現,然後討論它的改進並得到表 1 中的 api 的所有實現。

從簡單的開始,我們先實現一種表示容量固定的字串棧的抽象資料型別,如表 2 所示。

它的 api 和 stack 的 api 有所不同:它只能處理 string 值,它要求用例指定乙個容量且不支援迭代。實現乙份 api 的第一步就是選擇資料的表示方式。對於 fixedcapacitystackofstrings,我們顯然可以選擇 string 陣列。由此我們可以得到表 2 中底部的實現。

表 2 一種表示定容字串棧的抽象資料型別

表 3 fixedcapacitystackofstrings 的測試用例的軌跡

這種實現的主要效能特點是 push 和 pop 操作所需的時間獨立於棧的長度。許多應用會因為這種簡潔性而選擇它。但幾個缺點限制了它作為通用工具的潛力,下面嘗試改進它。

fixedcapacitystackofstrings 的第乙個缺點是它只能處理 string 物件。對此,我們可在**中引入泛型(有關泛型的介紹見簡單了解一下 j**a 泛型)。表 4 中的**展示了實現的細節。

表 4 一種表示泛型定容棧的抽象資料型別

在 j**a 中,陣列一旦建立,其大小是無法改變的,因此棧使用的空間只能是這個最大容量的一部分。建立大容量的棧在棧為空或幾乎為空時會浪費大量的記憶體。而小容量的棧可能不滿足儲存大量資料的要求。

所以 fixedcapacitystack 最好能夠支援動態調整陣列大小,使得它既足以儲存所有元素,又不至於浪費過多的空間。

為此,我們可以新增乙個 resize(int) 方法。

private void resize(int max)

然後在 push() 中,檢查陣列是否太小,太小時增大陣列長度。

public void push(item item)

類似地,在 pop() 中,首先刪除棧頂的元素,之後如果陣列太大我們就將它的長度減半。

public item pop()

push() 和 pop() 操作中陣列大小調整的軌跡見表 5。

表 5 一系列 push() 和 pop() 操作中陣列大小調整的軌跡

集合類資料型別的基本操作之一就是,能夠使用 j**a 的 foreach 語句通過迭代遍歷並處理集合中的每個元素。有關在**中加入迭代的方法見 j**a 可迭代的資料型別。

有了前面的準備,我們能夠寫出下壓棧能動態調整陣列大小的實現。

棧的實現(基於陣列)

import j**a.util.iterator;

public class resizingarraystackimplements iterable

public int size()

private void resize(int max)

public void push(item item)

public item pop()

public iteratoriterator()

private class reversearrayiterator implements iterator

public item next()

public void remove()

}}

受上述棧的實現過程的啟發,我們可以類似寫出揹包和佇列的實現。

對於揹包,將棧實現中的 push(item) 方法的方法名改為 add 並刪除新增元素的方法即可。

揹包的實現(基於陣列)

import j**a.util.iterator;

public class resizingarraybagimplements iterable

public int size()

private void resize(int max)

public void add(item item)

public iteratoriterator()

private class reversearrayiterator implements iterator

public item next()

public void remove()

}}

對於佇列,可以使用兩個例項變數作為索引,乙個變數 head 指向佇列的開頭,乙個變數 tail 指向佇列的結尾,如表 6 所示。在刪除乙個元素時,使用 head 訪問它並將 head 加 1;在插入乙個元素時,使用 tail 儲存它並將 tail 加 1。如果某個索引在增加之後越過了陣列的邊界則將它重置為 0。

表 6 resizingarrayqueue 的測試用例的軌跡

下面是 resizingarrayqueue 的實現。

佇列的實現(基於陣列)

import j**a.util.iterator;

public class resizingarrayqueueimplements iterable

public int size()

private void resize(int max)

public void enqueue(item item)

public item dequeue()

public iteratoriterator()

private class resizingarrayqueueiterator

implements iterator

public item next()

}}

揹包 佇列和棧

揹包 public class bagimplements iterable bag 建立乙個空揹包 void add item item 新增乙個元素 boolean isempty 揹包是否為空 int size 揹包中的元素數量 先進先出 fifo 佇列 pubilc class queuei...

1 3揹包,佇列和棧

許多基礎資料型別都和物件的集合有關,具體來說,資料型別的值就是一組物件的集合,所有操作都是關於新增,刪除或是訪問集合中的物件。三種資料型別 揹包,佇列,棧。1.1泛型 集合類的抽象資料型別的乙個關鍵特性是我們應該可以用他們儲存任意型別的資料,它被稱為泛型,也叫做引數化型別。類名後的記號將item定義...

基於陣列實現的佇列

author qcg version 2019 5 13.description 基於陣列實現的佇列 佇列的型別 順序佇列 鏈式佇列 迴圈佇列 阻塞佇列 併發佇列 public class myarrayqueue 入隊 param item 入隊元素 return 是否成功 public bool...