最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C#實現(xiàn)并查集的使用示例

 更新時間:2023年11月28日 10:10:58   作者:神仙別鬧  
并查集是一種用于處理一些不相交集合的合并及查詢問題的數(shù)據(jù)結構,具有高效、簡潔、易用的特點,本文主要介紹了C#實現(xiàn)并查集的使用示例,感興趣的可以了解一下

一、場景

有時候我們會遇到這樣的場景,比如:M={1,4,6,8},N={2,4,5,7},我的需求就是判斷{1,2}是否屬于同一個集合,當然實現(xiàn)方法有很多,一般情況下,普通青年會做出 O(MN)的復雜度,那么有沒有更輕量級的復雜度呢?并查集就是用來解決這個問題的。

二、操作

從名字可以出來,并查集其實只有兩種操作,并(Union)和查(Find),并查集是一種算法,所以我們要給它選擇一個好的數(shù)據(jù)結構,通常我們用樹來作為它的底層實現(xiàn)。

2.1、節(jié)點定義

 #region 樹節(jié)點
 /// <summary>
 /// 樹節(jié)點
 /// </summary>
 public class Node
 {
     /// <summary>
     /// 父節(jié)點
     /// </summary>
     public char parent;

     /// <summary>
     /// 節(jié)點的秩
     /// </summary>
     public int rank;
 }
 #endregion

2.2、Union 操作

<1> 原始方案首先我們會對集合的所有元素進行打散,最后每個元素都是一個獨根的樹,然后我們 Union 其中某兩個元素,讓他們成為一個集合,最壞情況下我們進行 M 次的 Union 時會存在這樣的一個鏈表的場景。

image.png

從圖中我們可以看到,Union 時出現(xiàn)了最壞的情況,而且這種情況還是比較容易出現(xiàn)的,最終導致在 Find 的時候就相當復雜了,為 O(N)。

<2> 按秩合并我們發(fā)現(xiàn)出現(xiàn)這種情況的原因在于我們 Union 時都是將合并后的大樹作為小樹的孩子節(jié)點存在,那么我們在 Union 時能不能判斷一下,將小樹作為大樹的孩子節(jié)點存在,最終也就降低了新樹的深度,比如圖中的 Union(D,{E,F})的時候可以做出如下修改。

image.png

可以看出,我們有效的降低了樹的深度,在 N 個元素的集合中,構建樹的深度不會超過 LogN 層。M 次操作的復雜度為 O(MlogN),從代碼上來說,我們用 Rank 來統(tǒng)計樹的秩,可以理解為樹的高度,獨根樹時 Rank=0,當兩棵樹的 Rank 相同時,可以隨意挑選合并,在新根中的 Rank++ 就可以了。

 #region 合并兩個不相交集合
 /// <summary>
 /// 合并兩個不相交集合
 /// </summary>
 /// <param name="root1"></param>
 /// <param name="root2"></param>
 /// <returns></returns>
 public void Union(char root1, char root2)
 {
     char x1 = Find(root1);
     char y1 = Find(root2);

     //如果根節(jié)點相同則說明是同一個集合
     if (x1 == y1)
         return;

     //說明左集合的深度 < 右集合
     if (dic[x1].rank < dic[y1].rank)
     {
         //將左集合指向右集合
         dic[x1].parent = y1;
     }
     else
     {
         //如果 秩 相等,則將 y1 并入到 x1 中,并將x1++
         if (dic[x1].rank == dic[y1].rank)
             dic[x1].rank++;

         dic[y1].parent = x1;
     }
 }
 #endregion

2.3、Find 操作

我們學算法,都希望能把一個問題優(yōu)化到不能優(yōu)化的地步,針對 logN 的級別,我們還能優(yōu)化嗎?當然可以。

<1> 路徑壓縮在 Union 和 Find 這兩種操作中,顯然我們在 Union 上面已經(jīng)做到了極致,下面我們在 Find 上面考慮一下,是不是可以在 Find 上運用伸展樹的思想,這種伸展思想就是壓縮路徑。

image.png

從圖中我們可以看出,當我 Find(F)的時候,找到“F”后,我們開始一直回溯,在回溯的過程中給,把該節(jié)點的父親指向根節(jié)點。最終我們會形成一個壓縮后的樹,當我們再次 Find(F)的時候,只要 O(1)的時間就可以獲取,這里有個注意的地方就是 Rank,當我們在路徑壓縮時,最后樹的高度可能會降低,可能你會意識到原先的 Rank 就需要修改了,所以我要說的就是,當路徑壓縮時,Rank 保存的就是樹高度的上界,而不僅僅是明確的樹高度,可以理解成"伸縮椅"伸時候的長度。

 #region  查找x所屬的集合
 /// <summary>
 /// 查找x所屬的集合
 /// </summary>
 /// <param name="x"></param>
 /// <returns></returns>
 public char Find(char x)
 {
     //如果相等,則說明已經(jīng)到根節(jié)點了,返回根節(jié)點元素
     if (dic[x].parent == x)
         return x;

     //路徑壓縮(回溯的時候賦值,最終的值就是上面返回的"x",也就是一條路徑上全部被修改了)
     return dic[x].parent = Find(dic[x].parent);
 }
 #endregion

我們注意到,在路徑壓縮后,我們將 LogN 的復雜度降低到 Alpha(N),Alpha(N)可以理解成一個比 hash 函數(shù)還有小的常量,這就是算法的魅力。

image.png

到此這篇關于C#實現(xiàn)并查集的使用示例的文章就介紹到這了,更多相關C# 并查集內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家! 

您可能感興趣的文章:

相關文章

  • C#折線圖控件使用方法詳解

    C#折線圖控件使用方法詳解

    這篇文章主要為大家詳細介紹了C#折線圖控件的使用方法,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • c#判斷輸入的是不是數(shù)字的小例子

    c#判斷輸入的是不是數(shù)字的小例子

    c#判斷輸入的是不是數(shù)字的小例子,需要的朋友可以參考一下
    2013-03-03
  • C#?變量,常量數(shù)據(jù)類型詳情

    C#?變量,常量數(shù)據(jù)類型詳情

    這篇文章主要介紹了C#?變量,常量數(shù)據(jù)類型詳情,常量是指在程序運行中不能改變的數(shù)據(jù),定義一個常量與定義一個變量過程類似,只是多加一個關鍵詞const
    2022-07-07
  • C#基于SerialPort類實現(xiàn)串口通訊詳解

    C#基于SerialPort類實現(xiàn)串口通訊詳解

    這篇文章主要為大家詳細介紹了C#基于SerialPort類實現(xiàn)串口通訊,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • C#  Task  TaskFactory  設置最大并行線程數(shù)的方法

    C#  Task  TaskFactory  設置最大并行線

    本文深入探討了LimitedConcurrencyLevelTaskScheduler的工作原理,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2026-04-04
  • Unity后處理效果之邊角壓暗

    Unity后處理效果之邊角壓暗

    這篇文章主要為大家詳細介紹了Unity后處理效果之邊角壓暗,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-03-03
  • 90分鐘實現(xiàn)一門編程語言(極簡解釋器教程)

    90分鐘實現(xiàn)一門編程語言(極簡解釋器教程)

    本文介紹了如何使用 C# 實現(xiàn)一個簡化 Scheme——iScheme 及其解釋器,需要的朋友可以參考下
    2016-12-12
  • 使用C#為PDF文檔添加專業(yè)水印的實現(xiàn)指南

    使用C#為PDF文檔添加專業(yè)水印的實現(xiàn)指南

    在數(shù)字化時代,PDF文檔已成為信息傳遞和存儲的核心載體,無論是商業(yè)合同、技術報告還是內部資料,保護文檔的版權、標識其狀態(tài)或強化品牌形象都至關重要,為PDF文檔添加水印,正是實現(xiàn)這些目標的一種高效且常見的方式,所以本文介紹了如何使用C#為PDF文檔添加專業(yè)水印
    2025-09-09
  • c#中Linq to Sql 增刪除的實例

    c#中Linq to Sql 增刪除的實例

    c#中Linq to Sql 增刪除的實例,需要的朋友可以參考一下
    2013-05-05
  • 使用C#獲取操作系統(tǒng)版本號的四種方法

    使用C#獲取操作系統(tǒng)版本號的四種方法

    這篇文章主要介紹了在C#中檢測Windows10和Windows11的方法,包括Environment.OSVersion、Registry、WMI和IsWindows11OrGreater()(WinAPI),每種方法都有各自的優(yōu)缺點,需要的朋友可以參考下
    2025-11-11

最新評論

沅江市| 滨州市| 图们市| 沿河| 林芝县| 藁城市| 布尔津县| 沙河市| 崇州市| 汉寿县| 高雄市| 卢湾区| 江西省| 华宁县| 石楼县| 宝应县| 灵川县| 安西县| 介休市| 东丽区| 凉城县| 武安市| 福海县| 开远市| 聂荣县| 奎屯市| 沁阳市| 句容市| 武川县| 万盛区| 娄底市| 苏州市| 健康| 宁陕县| 平远县| 南陵县| 卢龙县| 新郑市| 白河县| 扬中市| 永泰县|