斐波那契數列 堆

2021-07-04 12:42:24 字數 2711 閱讀 1196

斐波那契數列指的是這樣乙個數列 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144

第0項是0,第1項是第乙個1。

這個數列從第二項開始,每一項都等於前兩項之和。

在數學上,斐波納契數列被以遞迴的方法定義:f0=0,f1=1,fn=f(n-1)+f(n-2)(n>=2,n∈n*)

性質: 1、

斐波那契數列又稱**分割數列,原因是當n趨於無窮大時,後一項與前一項的比值接近1.618,也就是小數部分等於0.618,或者前一項與後一項的比值接近0.618。

2、從第二項開始,每個奇數項的平方都比前後兩項之積多1,每個偶數項的平方都比前後兩項之積少1。

求斐波那契數列演算法可看筆記「遞迴與迴圈」,盡量用迴圈來實現(效率高)!!!

應用例子:

1、有一根長為l的鐵絲截成k段,每段長度不小於1(可以為小數),並且任意三段都不能拼成三角形,求k最大值。

先把截斷的鐵絲排序:n1<=n2<=n3<=....<=nk,

能拼成三角形等價於3條鐵絲中任2條的和大於第3條,也就是兩條小的邊的和要大於第3條邊,所以,不能拼成三角形,意味著任2條小邊的和不能大於比它們大的邊,也就是ni+n(i+1)<=n(i+2),因為如果ni+n(i+1)比n(i+2)小,那ni+n(i+1)肯定比n(i+2)後面的邊要小,同樣如果n(i+2)比

ni+n(i+1)大,那一定前面任兩條邊的和要大。

所以題目中的條件轉化為:

n1+n2<=n3;n2+n3<=n4;....;n(k-2)+n(k-1)<=nk,且n1+n2+n3+...+nk=l,

要想分成更多段,那n1首先要盡量小,取1,n2也取1,n3也盡量小,取2,以此類推,化成了

n1=1,n2=1,n(i+2)=n(i+1)+ni

也就是按照斐波那契數列關係分割鐵絲

2、有乙個n級台階,每步可以走1級或2級,求走完這n級台階一共有多少種走法。

n=1:1種走法;

n=2:2種走法;

n>2:

如果第一步走1級,則還剩下n-1級,如果第一步走2級,則還剩下n-2級,總的走法等於這兩者相加,設剩下n-1級共有f(n-1)種走法,剩下n-2級共有f(n-2)種走法,則f(n)=f(n-1)+f(n-2)。

可見滿足斐波那契數列:1,2,3,5,8,13....(從1開始,且第2個是2,不是1),可用迴圈來求。

斐波那契堆

斐波那契堆(fibonacci heap)是堆中一種,它和二項堆一樣,也是一種可合併堆;可用於實現合併優先佇列。斐波那契堆比二項堆具有更好的平攤分析效能,它的合併操作的時間複雜度是o(1)。

與二項堆一樣,它也是由一組堆最小有序樹組成,並且是一種可合併堆。

與二項堆不同的是,斐波那契堆中的樹不一定是二項樹;而且二項堆中的樹是有序排列的,但是斐波那契堆中的樹都是有根而無序的

插入操作:

插入操作非常簡單:插入乙個節點到堆中,直接將該節點插入到'根鍊錶的min節點'之前即可;若被插入節點比'min節點'小,則更新'min節點'為被插入節點。斐波那契堆的根煉表是'雙向鍊錶',這裡將min節點看作雙向聯表的表頭。在插入節點時,每次都是將節點插入到min節點之前(即插入到雙鏈表末尾)。

合併操作:

合併操作和插入操作的原理非常類似:將乙個堆的根鍊錶插入到另乙個堆的根煉表上即可。簡單來說,就是將兩個雙鏈表拼接成乙個雙向鍊錶。所以斐波那契堆的合併操作時間複雜度是乙個常數,故為o(1)。

取出最小節點:

抽取最小結點的操作是斐波那契堆中較複雜的操作。

1、將要抽取最小結點的子樹都直接串聯在根表中;

2、合併所有degree相等的樹,直到沒有相等的degree的樹;

減小節點值:

減少斐波那契堆中的節點的鍵值,這個操作的難點是:如果減少節點後破壞了'最小堆'性質,如何去維護呢?下面對一般性情況進行分析。

1、首先,將'被減小節點'從'它所在的最小堆'剝離出來;然後將'該節點'關聯到'根鍊錶'中。 倘若被減小的節點不是單獨乙個節點,而是包含子樹的樹根。則是將以'被減小節點'為根的子樹從'最小堆'中剝離出來,然後將該樹關聯到根煉表中。

2、接著,對'被減少節點'的原父節點進行'級聯剪下'。所謂'級聯剪下',就是在被減小節點破壞了最小堆性質,並被切下來之後;再從'它的父節點'進行遞迴級聯剪下操作。而級聯操作的具體動作則是:若父節點(被減小節點的父節點)的marked標記為false,則將其設為true,然後退出。否則,將父節點從最小堆中切下來(方式和'切被減小節點的方式'一樣);然後遞迴對祖父節點進行'級聯剪下'。marked標記的作用就是用來標記'該節點的子節點是否有被刪除過',它的作用是來實現級聯剪下。而級聯剪下的真正目的是為了防止'最小堆'由二叉樹演化成鍊錶。

2、最後,別忘了對根鍊錶的最小節點進行更新。

增加節點值:

增加節點值和減少節點值類似,這個操作的難點也是如何維護'最小堆'性質。思路如下:

1、將'被增加節點'的'左孩子和左孩子的所有兄弟'都鏈結到根煉表中。

2、接下來,把'被增加節點'新增到根鍊錶;但是別忘了對其進行級聯剪下。

刪除節點:

刪除節點,採用操作是:'取出最小節點'和'減小節點值'的組合。

(1) 先將被刪除節點的鍵值減少。減少後的值要比'原最小節點的值'即可。

(2) 接著,取出最小節點即可。

斐波那契數列 斐波那契數列python實現

斐波那契數列 fibonacci sequence 又稱 分割數列 因數學家列昂納多 斐波那契 leonardoda fibonacci 以兔子繁殖為例子而引入,故又稱為 兔子數列 指的是這樣乙個數列 1 1 2 3 5 8 13 21 34 在數學上,斐波納契數列以如下被以遞推的方法定義 f 1 ...

迴圈斐波那契數列 斐波那契數列應用

什麼是斐波那契數列 斐波那契數列指的是這樣乙個數列 1,1,2,3,5,8,13,21,34,55,89,144 這個數列從第3項開始,每一項都等於前兩項之和 台階問題 有一段樓梯有10級台階,規定每一步只能跨一級或兩級,要登上第10級台階有幾種不同的走法?這就是乙個斐波那契數列 登上第一級台階有一...

斐波那契數列

1 題目描述 大家都知道斐波那契數列,現在要求輸入乙個整數n,請你輸出斐波那契數列的第n項。斐波那契數列的定義如下 輸入 輸入可能包含多個測試樣例,對於每個測試案例,輸入包括乙個整數n 1 n 70 輸出 對應每個測試案例,輸出第n項斐波那契數列的值。2 這是九度上的乙個題,要求時間限制1秒,整數的...