The daily walkthrough of the classic Algorithm question--the 15th question and check set

Source: Internet
Author: User

The original: A daily walkthrough of the classic Algorithm--the 15th question and the search set

This article we look at the classic and magical and look-up, as the name implies is and up to check, can be used to deal with some disjoint collection of seconds to kill.

One: Scene

Sometimes we will encounter such a scenario, such as: m={1,4,6,8},n={2,4,5,7}, my need is to determine whether {is} belongs to the same collection, of course, the implementation method

There are many, in general, ordinary youth will make O (MN) complexity, then there is no more lightweight complexity? Hey, and check set is used to solve the problem.

Two: Operation

From the name can come out, and check the set actually only two operations, and (Union) and check (find), and check set is an algorithm, so we have to choose a good data structure,

Usually we use a tree as its underlying implementation.

1. Node definition

1         #region tree Node 2//         <summary> 3//         tree node 4//         </summary> 5 Public         class node 6         {7
   
    ///<summary> 8//             Parent Node 9//             </summary>10 public             char parent;11//             <summary>13 ///             </summary>15 public             int rank;16         }17         #endregion
   

2.Union operation

<1> Original plan

First we break all the elements of the collection, and finally each element is a single tree, and then we union one of the two elements and let them become a collection,

The worst case scenario where we do m union will exist such a list.

We can see that the worst is happening in union, and this is relatively easy to come by, resulting in a rather shabby, hard-to-Find, O (N).

<2> Merge by rank

We find that the reason for this is that when we union, we have the merged tree as a child node of the small tree, so can we judge in Union,

The small tree as a child of the tree nodes exist, and ultimately reduce the depth of the new tree, compared to the Union (d,{e,f}) when the following changes can be made.

As can be seen, we effectively reduce the depth of the tree, in the set of n elements, the depth of the build tree will not exceed the LOGN layer. The complexity of M operations is O (MLOGN), from generation

On the code, we use rank to count the rank of the tree, which can be understood as the height of the tree, when the tree is rank=0, when the rank of the two trees at the same time, you can choose to merge at random, in the new

The rank++ in the root will be all right.

1 #region Merge two disjoint sets 2//         <summary> 3//         merge two disjoint sets 4//         </summary> 5//         <param name= "ro Ot1 "></param> 6//         <param name=" Root2 "></param> 7//         <returns></returns> 8 Public         void Union (char root1, char root2) 9         {Ten             char x1 = Find (ROOT1), one             char y1 = find (Root2); 13
   //If the root node is the same, the description is the same collection if             (x1 = = y1)                 return;16             //Description left set Depth < right collection if             (Dic[x1].rank < dic [Y1].rank] +                 //Set the left set to the right set                 of dic[x1].parent = y1;22             }23             else24             {                 //If the rank is equal, The Y1 is incorporated into X1 and x1++26                 if (Dic[x1].rank = = Dic[y1].rank), dic[x1].rank++;28 dic[y1].parent                 = x1;30< c25/>}31         }32         #endregion

3.Find operation

We learn the algorithm, all want to be able to optimize a problem to the Earth people can not optimize the point, for the level of LOGN, we can also optimize it? Of course.

<1> path Compression

In the two operations of Union and find, it is clear that we have achieved the ultimate in the union above, let's consider on find above, whether it can be used on find

The idea of stretching the tree, this stretching idea is the compression path.

As we can see, when I find the "f", we start to backtrack and, in the process of backtracking, point the parent of the node to the root node. Eventually

We'll form a compressed tree, and when we find (F) again, as long as O (1) is available, here's a note of rank, when we're on the road

Diameter compression, the height of the last tree may be reduced, you may realize that the original rank needs to be modified, so I would say that when the path is compressed, rank saves

is the upper bound of the height of the tree, not just the height of the tree, can be understood as "telescopic chair" extension of the length.

1 #region  Find the collection that x belongs to 2//         <summary> 3//         find the collection that x belongs to 4//         </summary> 5//         <param name= "X" ></param> 6         //<returns></returns> 7 public         Char Find (char x) 8         {9             //if equal, Then the root node is returned, the root node element,             if (dic[x].parent = = x), return                 x;12             //Path compression (the final value is the "X" returned above, That is, all of a path has been modified)             return dic[x].parent = Find (dic[x].parent);         }16         #endregion

We notice that after the path is compressed, we reduce the complexity of LOGN to Alpha (n), and Alpha (n) can be understood as a smaller constant than the hash function, hehe, which

Is the charm of the algorithm.

Finally, the total running code:

Using system;using system.collections.generic;using system.linq;using system.text;namespace ConsoleApplication1{ Class Program {static void Main (string[] args) {//define 6 nodes char[] c = new char[]            {' A ', ' B ', ' C ', ' D ', ' E ', ' F '};            Disjointset set = new Disjointset (); Set.            Init (c); Set.            Union (' E ', ' F '); Set.            Union (' C ', ' D '); Set.            Union (' C ', ' E '); var B = set.            Issameset (' C ', ' E ');            Console.WriteLine ("C,e is in the same set: {0}", b); b = Set.            Issameset (' A ', ' C ');            Console.WriteLine ("A,c is in the same set: {0}", b);        Console.read ();        }}///<summary>//And check set//</summary> public class Disjointset {#region tree node <summary>//tree node///</summary> public class Node {//<summ     Ary>///parent node///</summary> public char parent;       <summary>////node rank///</summary> public int rank;        } #endregion Dictionary<char, node> dic = new Dictionary<char, node> (); #region do a single set of initialization operations///<summary>///do a single set initialization operation////</summary> public void Init (                Char[] c) {//Default parent node that does not want to cross the collection points to itself for (int i = 0; i < c.length; i++) { Dic.            ADD (C[i], new Node () {parent = C[i], rank = 0});        }} #endregion #region determine whether the two elements belong to the same collection///<summary>///Determine whether the two elements belong to the same collection </summary>//<param name= "ROOT1" ></param>//<param name= "Root2" ></p            aram>//<returns></returns> public bool Issameset (char Root1, char Root2) {     return Find (ROOT1) = = Find (ROOT2);   #endregion #region Find the collection that x belongs to///<summary>//Find the collection that x belongs to//</summary> <param name= "x" ></param>///<returns></returns> public char Find (char x            {//If equal, then the root node is returned, and the root node element if (dic[x].parent = = x) return x;        Path compression (when backtracking is assigned, the final value is the "X" returned above, which means that all of the paths have been modified) return dic[x].parent = Find (dic[x].parent);        #endregion #region Merge two disjoint sets///<summary>///Merge two disjoint sets///</summary> <param name= "ROOT1" ></param>//<param name= "Root2" ></param>//<retu            rns></returns> public void Union (char root1, char root2) {char x1 = Find (ROOT1);            Char y1 = Find (Root2);            If the root node is the same, then the same set if (x1 = = y1) return; Describes the depth < right set of the left collection if (Dic[x1].ranK < Dic[y1].rank) {//sets the left collection to the right set dic[x1].parent = y1; } else {//If the rank is equal, the Y1 is incorporated into X1 and x1++ if (Dic[x1].rank = = DIC[Y1].R                Ank) dic[x1].rank++;            Dic[y1].parent = x1; }} #endregion}}

  

The daily walkthrough of the classic Algorithm question--the 15th question and check set

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.