<<大話數據結構>>第4章-棧與隊列

本文原創文章,轉載註明出處,博客地址 https://segmentfault.com/u/to... 第一時間看後續精彩文章。以爲好的話,順手分享到朋友圈吧,感謝支持。segmentfault

棧的應用-遞歸

遞歸函數定義

咱們把一個直接調用本身或經過一系列的調用語句間接地調用本身的函數,稱作遞歸函數數組

迭代和遞歸的區別

迭代代碼,實現斐波那契額數列

//版本1:迭代版本
func Fbi1(i int) int {

    switch i {
    case 0:
        return 0
    case 1:
        return 1
    default:
        arr := make([]int, i+1, i+1)
        arr[0] = 0
        arr[1] = 1
        for j := 2; j <= i; j++ {
            arr[j] = arr[j-1] + arr[j-2]
        }
        return arr[i]
    }
}

遞歸代碼

//版本2:遞歸版本
func Fbi2(i int) int {
    switch i {
    case 0:
        return 0
    case 1:
        return 1
    default:
        //遞歸調用
        return Fbi2(i-1) + Fbi2(i-2)
    }
}
  1. 迭代使用的是循環結構,遞歸使用的是選擇結構
  2. 遞歸使程序的結構更清晰、更簡潔、更容易理解,從而減小讀懂代碼的時間
  3. 可是大量的遞歸調用會創建函數的副本,會耗費大量的時間和內存,迭代則不須要反覆調用函數和佔用額外的內存

視不一樣狀況選擇不一樣的代碼實現方式函數

編譯器使用棧實現遞歸

遞歸過程分爲前行和退回階段,編譯器使用棧實現遞歸;前行階段,每一層遞歸,函數的局部變量、參數值以及返回地址都被壓入棧,在退回階段,位於棧頂的局部變量、參數值和返回地址被彈出,恢復了調用的狀態code

隊列的定義

  1. 隊列(Queue)是隻容許在一端進行插入操做,而在另外一端進行刪除操做的線性表
  2. 先進先出(First In First Out),簡稱FIFO

循環隊列

咱們把隊列的這種頭尾相接的順序存儲結構稱爲循環隊列遞歸

鏈隊列

隊列的鏈式存儲結構,就是線性表的單鏈表,只能尾進頭出隊列

循環隊列與鏈隊列比較

  1. 循環隊列是事先申請好空間,使用期間不釋放;鏈隊列,每次申請和釋放階段存在一些時間開銷
  2. 循環隊列必須有一個固定長度,有存儲元素個數和空間浪費的問題;空間上,鏈隊列更加靈活

總結:能夠肯定隊列長度最大值的狀況下,建議用循環隊列,若是沒法預估隊列長度,則用鏈隊列內存

總結回顧

  • 對於棧來講,若是兩個相同數據類型的棧,則能夠用數組的兩端做棧底來讓兩個棧共享數據,能夠最大化利用數組的空間
  • 循環隊列使得隊頭和隊尾能夠在數組中循環變化,避免數組插入數據和刪除時須要移動數據的時間損耗,使得原本插入和刪除是O(n)的時間複雜度變成O(1)
相關文章
相關標籤/搜索