不相交集ADT--鏈表實現
阿新 • • 發佈:2017-05-20
+= 交換 return 合成 簡單實現 lis turn 思想 對象
每一個集合用用一個鏈表來表示。鏈表的第一個對象作為它所在集合的代表。鏈表中每個對象都包含一個集合成員,一個指向下一個對象的指針,以及指向代表的指針。每個鏈表含head和tail指針,head指向鏈表的代表,tail指向鏈表中最後的對象。
如下圖所示:
Union的簡單實現:將x所在的鏈表拼接到y所在鏈表的表尾。對於原先x所在鏈表中的每一個對象都要更新其指向代表的指針。
如下圖所示:
根據以上思想,代碼如下:
#include<iostream> using namespace std; #define NumSets 8 typedef struct Node *Position; typedef struct Node *Head; typedef Head DisjSet[NumSets + 1]; //對於頭節點,head_node指向第一個元素,tail指向最後一個元素,Key為該集合的大小 //對於普通節點,head_node指向第一個元素,tail指向後面的一個元素,相當於Next,Key為關鍵字 struct Node { Position head_node; Position tail; int Key; }; Head Make_One_Node (int x) { Head Head_one = (Head)malloc(sizeof(Node)); //先申請一個頭結點 Head_one->Key = 1; //個數為1 Position p = (Position)malloc(sizeof(Node)); //這個節點才是存儲數據的節點 p->Key = x; p->head_node = p; //普通節點的hand_node域指向第一個元素,此時就是它本身 p->tail = NULL; Head_one->head_node = p; //頭節點的hand_node域指向第一個元素 Head_one->tail = p; //頭節點的tail域指向最後一個元素 return Head_one; } void Set_Union (Head head1, Head head2) { Head tempHead; if (head1->Key < head2->Key ) { tempHead = head1; head1 = head2; head2 = tempHead; } //把短的接在長的後面 //下面兩句話的位置不能交換,否則會陷入死循環 head1->tail->tail = head2->head_node; //head1最後一個元素的tail域指向head2的第一個元素 head1->tail = head2->tail ; //head1的tail域指向head2的最後一個元素,也就是head2->tail Position p = head2->head_node ; while(p) { p->head_node = head1->head_node ;//head2的所有元素都指向head1的第一個元素 p = p->tail; } head1->Key += head2->Key ; //釋放head2的所有元素 head2->Key = 0; head2->head_node = NULL; head2->tail = NULL; } Head Set_Find (DisjSet S,int x) //返回該節點的頭結點 { for (int i = 1; i <= NumSets; ++i) { Position p = S[i]->head_node ; while(p) { if(x == p->Key ) return p->head_node; else p = p->tail; } } } void printf_list(DisjSet S) { for (int i = 1; i <= NumSets; ++i) { if(S[i]->Key == 0) { cout << "第 "<< i << " 個集合沒有元素。" <<endl; } else { cout << "第 "<< i << " 個集合一個共有 " << S[i]->Key << " 個元素,分別是:"; Position p = S[i]->head_node ; while(p) { cout << p->Key << "\t"; p = p->tail; } cout << endl; } } } int main () { DisjSet S; for (int i = 1; i <= NumSets; ++i) { S[i] = Make_One_Node (i); } Set_Union (S[1], S[2]); Set_Union (S[3], S[4]); Set_Union (S[3], S[1]); printf_list(S); cout << Set_Find (S,5)->Key << endl; return 0; }
看著比數組實現要復雜一點啊。
夜深了,,,
今天5月20號啊,520啊,還是周末啊,還在寫代碼,代碼才是真愛。
不相交集ADT--鏈表實現