目錄html
更新、更全的《數據結構與算法》的更新網站,更有python、go、人工智能教學等着你:http://www.javashuo.com/article/p-zfinzipt-hh.htmlpython
集合運算:交、並、補、差,斷定一個元素是否屬於某一集合算法
在上述集合運算中,咱們只關心兩個集合運算,爲並查集:集合並和查某元素屬於什麼集合。所以有一個問題——並查集問題中集合存儲如何實現?數組
對於上述問題,咱們能夠用樹結構表示集合,樹的每一個結點表明一個集合元素數據結構
例如:有如下三個整數集合網站
對於上述三個集合,咱們可使用雙親表示法(孩子指向雙親)來構造下圖所示樹結構:人工智能
對於上述的樹結構,咱們能夠考慮使用數組存儲,存儲形式以下圖所示:spa
負數表示根結點;非負數表示雙親結點的下標。3d
對於數組中的每一個元素,咱們可使用以下所示的代碼描述:指針
/* c語言實現 */ typedef struct{ ElementType Data; int Parent; } SetType;
# python語言實現 class TreeNode: def __init__(self, x): self.data = None self.parent = None
查找某個元素所在的集合(用根結點表示)
/* c語言實現 */ int Find(SetType S[], ElementType X) { // 在數組S中查找值爲X的元素所屬的集合 // MaxSize是全局變量,爲數組S的最大長度 int i; for (i = 0; i < MaxSize && S[i].Data != X; i++); if (i >= MaxSize) return -1; // 未找到X,返回-1 for (; S[i].Parent >= 0; i = S[i].Parent); return i; // 找到X所屬集合,返回樹根結點在數組S中的下標 }
分別找到X1和X2兩個元素所在集合樹的根結點
若是它們不一樣根,則將其中一個根結點的父結點指針設置成另個一個根結點的數組下標
/* c語言實現 */ void Union(SetType S[], ElementType X1, ElementType X2) { int Root1, Root2; Root1 = Find(S, X1); Root2 = Find(S, X2); if (Root1 != Root2) S[Root2].Parent = Root1; // 當X1和X2不屬於同一個子集時,才須要合併 }
下圖所示爲集合 {1, 2, 4, 7} 和 集合 {3, 5, 8}的並運算:
對於上述的兩個小集合,隨意選擇一個根結點並沒有太大影響,可是對於以下圖所示的兩個集合,隨意選擇根結點則會增長將來並集的查找效率:
對於上圖所示的兩個集合,若是要增長將來兩個集合並集的查找效率,應該儘可能採用小的集合合併到相對大的集合中,可是咱們如何判斷哪個集合元素更多呢?
爲了更高效的判斷那個集合元素更多,咱們能夠把根結點的-1改爲-7或-3,用根結點的絕對值表示集合元素的個數,即數組更改成以下圖所示:
其中-7表示根結點數據爲1的集合有7個元素;其中-3表示根結點數據爲6的集合有3個元素。