開個新坑, 準備學習演算法(第四版), 並把上面學到的東西寫成部落格, 畢竟以前也學過一點演算法, 但效果甚微
並查集, 在這本書的第一章1.5中叫做union-find演算法, 但在其他地方這個叫做並查集,就是說一系列點的連通問題,比如, 我們有十個點, 分別記作0~9:
加入我們要把2和4連線起來怎麼表示呢? 首先我們會想到,給所有的點標上乙個號, 來代表他們的連通關係, 我們初始化這個數就是他們id本身:
如果我們要連線2和4, 就使得4的id為2:
之後要連線間隔點任意兩個點, 就把它們和它們相應的點的值都設定為一樣就行了, 如果我們要比對這兩個是是否連通, 也只要比較他們的值是否相等就行了.
我們可以很輕易的寫出下面的**:
1/*2這就是樹上的quick-find演算法. 但是, 問題來了, 這樣我們查詢兩個點是否連通很方便, 速度很快, 但是連線兩個點就很慢了--我們需要遍歷所有的點! 在例子中我們只有十個點, 可是若有幾百萬個點呢? 每操作一次就遍歷上百萬個點, 這樣我們的**肯定就會無比的慢, 所以, 我們必須想新的辦法.* 並查集實現程式3*/
4public
class
uf 13 count =n;14}
1516
public
void union( int p, int q)
25 count--; //
連通圖數減126}
2728
public
int find(int i)
3132
public
boolean connected(int p, int q)
3536
public
int getcount()
3940 }
這是, 我們有了新的方法,就是書上的quick-union演算法, 就是說, 我們每次連線兩個點時, 只改變乙個點的標識值, 也就形成了一棵棵樹, 這樣在乙個連通圖中就肯定有乙個值的標識值是它本身的id, 沒有發生改變, 當我們用查詢find()方法查詢時,只要一直往下找, 直到找到標識值為它本身的這個點就行, 這樣就不會每次都遍歷到所有的點, 總體上來說時間複雜度就降下來了:
我們也可以輕易地寫出相應的**:
1但是, 還不夠, 因為我們得考慮最壞的情況, 就是當我們形成的這棵數沒有分支, 也就是形成了一條鏈時, 我們就依然變成了需要遍歷所有的點, 這樣, 我們辛辛苦苦降下去的複雜度有回來了public
void union( int p, int q) else
13 count--;14}
1516
public
int find(int i)
然後, 我們就有了書上的加權的quick-union演算法, 就是將樹的高度記錄下來, 然後每次union()時把高度低的數加到高度高的樹上去, 這樣樹的高度就不會超過lgn, 時間複雜度也控制在了o(lgn), **如下:
1/*2當然, 我們再有辦法優化, 我們的目標當然是無限接近常數次操作, 也就是o(1), 雖然這是不可能的. 那麼, 我們還能怎麼優化呢? 這就是,路徑壓縮, 就是說在呼叫find()方法時同時加乙個迴圈, 將所有的這些點直接指向根節點, 這樣我們下次操作這些點不就是常數次操作了嘛! **如下:* 並查集實現程式3*/
4public
class
uf 16 count =n;17}
1819
public
void union( int p, int q) else
31 count--;32}
3334
public
int find(int i)
3940
public
boolean connected(int p, int q)
4344
public
intgetcount()
4748 }
1在最後, 附送下最後的完整**:public
int find(int i)
10return
i;11 }
1/*2完成!* 並查集實現程式
3* 使用路徑壓縮的加權quit-union演算法4*/
5public
class
uf 17 count =n;18}
1920
public
void union( int p, int q) else
32 count--;33}
3435
public
int find(int i)
44return
i;45}46
47public
boolean connected(int p, int
q) 50
51public
intgetcount()
5455 }
演算法 第四版 之堆排序
堆排序是建立在堆的基礎上的,了解堆排序我們得先了解二叉堆.二叉堆是以二叉樹為基礎的,當一棵二叉樹的每個結點都大於等於它的兩個子節點數時,它被稱為堆有序.我們可以很容易的理解出,它的根節點是最大節點 二叉堆可以用指標和陣列兩種方式表示,本文用的是陣列的方式.我們在堆中有兩種操作方法,一種叫做上浮,一種...
《演算法(第四版)》排序 模板
本書對排序類演算法有乙個模板,包括了以下幾種方法 1 sort 這個方法裡面實現的就是排序的演算法 2 less 這個方法裡是利用了comparable介面裡的compareto方法,其中compareto方法對於本物件與傳入的比較物件小於,等於,大於,分別返回負數,0,正數 這個方法如果compa...
演算法 第四版 練習1 4 2
修改threesum,正確處理兩個較大的int值相加可能溢位的情況 首先jdk中定義int佔4個位元組,32位 後面全部的計算都是以此為根據的 32位就是jvm僅僅給分配32個格仔的空間,用以存放資料。總所周知計算機中用0和1存放資料。那麼,32個格仔中放滿0或1的方法 有2的32次方種 或者說32...