1. 程式人生 > >資料結構與演算法——不相交集類的C++實現

資料結構與演算法——不相交集類的C++實現

/*************************************************************************
	> File Name: DisjointSets.cpp
	> Author: 
	> Mail: 
	> Created Time: 2016年04月25日 星期一 11時22分48秒
 ************************************************************************/

#include <iostream>
#include <vector>
using namespace std;


/********************************************
*    類名稱:不相交集合類DisjSets
********************************************/
class DisjSets{
    public:
        explicit DisjSets(int numElements);
        ~DisjSets(){}
        
        int find(int x) const;//查詢
        void unionSets(int root1, int root2);//合併
        void unionSetsBySize(int root1, int root2);//按樹大小合併
        void unionSetsByHeight(int root1, int root2);//按樹高度合併
        void print();//輸出各個不相交集合類中元素
    private:
        void print(int x);
    private:
        vector<int> s;//存放每個元素的根節點或父節點
};


/****************************************************************
*   函式名稱:DisjSets(int numElements)
*   功能描述: 建構函式,同時對每個元素進行集合初始化
*   引數列表: numElements是集合中元素的個數
*   返回結果:無
*****************************************************************/
DisjSets::DisjSets(int numElements):s(numElements)
{
    for(unsigned i = 0; i < s.size(); ++i)
        s[i] = -1;
}

/****************************************************************
*   函式名稱:print(int x)
*   功能描述: 列印元素x
*   引數列表: x是元素的
*   返回結果:void 
*****************************************************************/
void DisjSets::print(int x)
{
    cout << x << " "; 
    for(unsigned i = 0; i < s.size(); ++i){
        if(s[i] == x)
            print(i);
    }
}
/****************************************************************
*   函式名稱:print
*   功能描述: 列印集合中的元素
*   引數列表: 無
*   返回結果:void 
*****************************************************************/
void DisjSets::print()
{
    cout << "輸出不相交集合類(每行表示一個相交集合): " << endl;
    cout << "s: ";
    for(unsigned i = 0; i < s.size(); ++i)
        cout << s[i] << " ";
    cout << endl;

    for(unsigned i = 0; i < s.size(); ++i){
        if(s[i] < 0){
            print(i);
            cout << endl;
        }
    }
}

/****************************************************************
*   函式名稱:find(int x) const
*   功能描述: 查詢元素x處於集合的名字
*   引數列表: x是要查詢的元素
*   返回結果:返回元素x的集合名字
*****************************************************************/
int DisjSets::find(int x) const
{
    if(s[x] < 0)
        return x;
    else
        return find(s[x]);
}


/****************************************************************
*   函式名稱:unionSets(int root1, int root2)
*   功能描述: 合併兩個集合
*   引數列表: root1表示集合1,root2表示集合2
*   返回結果:void 
*****************************************************************/
void DisjSets::unionSets(int root1, int root2)
{
    s[root2] = root1; 
}

/****************************************************************
*   函式名稱:unionSetsBySize(int root1, int root2)
*   功能描述: 按集合大小合併兩個集合,使得較小的樹成為較大樹的子樹
*   引數列表: root1表示集合1,root2表示集合2
*   返回結果:void 
*****************************************************************/
void DisjSets::unionSetsBySize(int root1, int root2)
{
    if(s[root2] < s[root1]){//root2樹比較大
        s[root2] += s[root1];//更新樹的大小
        s[root1] = root2;//root1的父節點變為root2
    }
    else{
        s[root1] += s[root2];
        s[root2] = root1;
    }
}


/****************************************************************
*   函式名稱:unionSetsByHeight(int root1, int root2)
*   功能描述: 按集合高度合併兩個集合,使較淺的樹成為較深的樹的子樹
*   引數列表: root1表示集合1,root2表示集合2
*   返回結果:void 
*****************************************************************/
void DisjSets::unionSetsByHeight(int root1, int root2)
{
    if(s[root2] < s[root1]){//root2樹比較高
        s[root1] = root2;//直接合並, root1成為root2樹的子樹 
    }
    else{//root1樹比較高,或相等。

         //如果相等則更新樹的高度
        if(s[root1] == s[root2])
            s[root1]--;
         s[root2] = root1;
    }   
}


//測試主函式
int main()
{
    cout << "任意合併: " << endl;
    DisjSets disjSets(8);
    disjSets.unionSets(4, 5);
    disjSets.unionSets(6, 7);
    disjSets.unionSets(4, 6);

    disjSets.print();

    cout << "按大小合併: " << endl;
    DisjSets disjSets2(8);
    disjSets2.unionSetsBySize(4, 5);
    disjSets2.unionSetsBySize(6, 7);
    disjSets2.unionSetsBySize(4, 6);
    disjSets2.unionSetsBySize(3, 4);
    disjSets2.print();


    cout << "按高度合併: " << endl;
    DisjSets disjSets3(8);
    disjSets3.unionSetsByHeight(4, 5);
    disjSets3.unionSetsByHeight(6, 7);
    disjSets3.unionSetsByHeight(4, 6);
    disjSets3.unionSetsByHeight(3, 4);
    disjSets3.print();

    return 0;
}

執行結果為:

相關推薦

資料結構演算法——交集C++實現

/************************************************************************* > File Name: DisjointSets.cpp > Author: > Mail: > Created Time

17_資料結構演算法_二叉堆_Python實現

#Created By: Chen Da #先實現一個二叉堆,基於完整二叉樹 class Binary_heap(object): def __init__(self): self.heap_list = [0] #一個空的二叉堆以零作為第一個元素,方

14_資料結構演算法_二叉樹_Python實現

#Created By: Chen Da class BinaryTree(object): def __init__(self,rootObj): self.key = rootObj self.left_child = None sel

java版資料結構演算法—佇列、兩個棧實現一個佇列

/** * 佇列:先進先出 */ class MyQueue { int a[]; int maxSize; //大小 int front; //開頭 int rear; //結尾 int nItems; //元素個數 //初始化

資料結構演算法-->冪運算的不同實現

package test; public class Miyunsuan { public static void main(String[] args) { System.out.println(pow2(2,4)); } /** * 普通遞迴演

資料結構演算法之 棧(Stack)的Java實現

 後入先出的資料結構 在 LIFO 資料結構中,將首先處理新增到佇列中的最新元素。 與佇列不同,棧是一個 LIFO 資料結構。通常,插入操作在棧中被稱作入棧 push 。與佇列類似,總是在堆疊的末尾新增一個新元素。但是,刪除操作,退棧 pop ,將始終刪除佇列中相對於

Javascript之資料結構演算法的圖(Graph)實現

Javascript之資料結構與演算法的圖(Graph)實現 簡介 廣度優先搜尋演算法實際應用-最短路徑(非權值) 深度優先搜尋演算法實際應用-拓撲排序(有向無環圖) Dijkstra 演算法 Floyd-Warshall

資料結構演算法(2)——各種方法實現楊輝三角

分別用二維陣列、一維陣列、遞迴等三種方法實現楊輝三角; 楊輝三角:首尾都為1,中間數值等於其肩上兩個數值之和,形如下面: 1

資料結構演算法分析》學習筆記-第八章-交集

[toc] *** 對於每一對元素(a,b), a, b屬於S,aRb或者為true或者為false,則稱在集合S上定義關係R,如果aRb是true。那麼我們說a與b有關係。 ## 8.1 等價關係 等價關係是滿足下列三個性質的關係R: 1. (自反性)對於所有的a屬於S,aRa 2. (對稱性)aRb當

資料結構演算法----自定義中函式資料成員

近期在梳理知識,做一個小結,希望自己能多多使用 在標頭檔案中: enum sign {plus, minus}; class Accruency { public: Accruency(sign s = plus, unsigned long d = 0, unsigned in

資料結構演算法分析-C語言描述 3.4 交集

題目:給定兩個已排序的表L1和L2,只使用基本的表操作編寫計算L1∩L2的過程 /* 3.4 交集 思路:由於是已排序,遍歷L的同時,將L的資料和P的資料進行比較, 如果相同則輸出,並因為是交集,不需要相同,所以P = P->next; 如果不相同,則L = L->nex

資料結構演算法 python語言描述》學習筆記(二)————抽象資料型別和Python

第一部分:學習內容概要 抽象資料型別 Python的類 第二部分:學習筆記 抽象資料型別   1.抽象資料型別(Abstract Data Type,ADT),通過一套介面闡述說明這一程式部分的可用功能,但不不限制功能的實現方法。      2.抽象資料型

JS資料結構演算法 —— 集合,並集,交集,補集

概念:集合是由一組無序且唯一(每個元素只出現一次)的項組成的一組資料。其與數學裡的集合是同一個概念。在ES6裡已經引入了集合的資料結構概念——Set類。 分類:常見的有空集,並集,交集,差集。 應用場景:1)資料去重;2)用於儲存一些獨一無二的資料。 js實現一個集合 集合的特性

資料結構演算法-java實現】三 Java陣列實現

上一篇文章學習了:最好、最壞、平均、均攤時間複雜度的計算與分析方法. 本片文章學習陣列這種結構。由於陣列這種結構比較簡單,本文直接簡單介紹,然後給出兩種實現陣列類的Java程式碼:整形陣列類與通用性的陣列類 由於陣列是相比於其他資料結構實在太簡

資料結構演算法——表示式樹C++實現(二叉樹)

表示式簡介: 表示式樹的樹葉是運算元,如數字或字母,而其它結點為操作符(+ - * / %等);由於這裡的操作都是二元的,所以這棵特定的樹正好是二叉樹。 下面這個樹的中綴表示式為:(a+b*c) + ((d*e + f)*g);(可以中序遍歷該表示式樹獲得該

資料結構演算法C#語言描述》筆記10_雜湊和Hashtable

雜湊概述 儲存在陣列內的每一個數據項都是基於一些資料塊,這資料塊被稱為鍵。 把鍵對映到一個範圍從0到雜湊大小的數上,這需要雜湊函式完成。 雜湊函式的理想目標是把自身單元內的每一個鍵都儲存到陣列內,但可能會出現兩個鍵雜湊到相同數值的情況,這現象叫做衝突。 雜湊的主要問題是:

JavaScript 資料結構演算法之美 - 你可能真的懂遞迴

1. 前言 演算法為王。 排序演算法博大精深,前輩們用了數年甚至一輩子的心血研究出來的演算法,更值得我們學習與推敲。 因為之後要講有內容和演算法,其程式碼的實現都要用到遞迴,所以,搞懂遞迴非常重要。 2. 定義 方法或函式呼叫自身的方式稱為遞迴呼叫,呼叫稱為遞,返回稱為歸。 簡單來說就是:自己呼

交集

with 可能 i++ 裏的 style 數據結構與算法 連續 max set 轉載請註明出處:https://i.cnblogs.com/EditPosts.aspx?postid=5748920 一、基本概念 不相交集類維持著多個彼此之間沒有交集的子集的集合,可以用

為什麼我要放棄javaScript資料結構演算法(第一章)—— JavaScript簡介

資料結構與演算法一直是我算比較薄弱的地方,希望通過閱讀《javaScript資料結構與演算法》可以有所改變,我相信接下來的記錄不單單對於我自己有幫助,也可以幫助到一些這方面的小白,接下來讓我們一起學習。 第一章 JavaScript簡介 眾所周知,JavaScript是一門非常強大的程式語言,不僅可以用於

資料結構演算法 二分法查詢【PythonC】的實現

程式碼如下: Python: def ErFen(List ,Number ,Len): left = 0 high = Len - 1 while left <= high: mid = (left + high)//2