Dynamic connectivity directly sounds like a bit of a bit, simply to enter a column of integer pairs, where each integer represents some type of object, assuming that the input of the integer pair is p and Q, we can understand that P and Q are connected, assuming that the connection is an equivalence relationship, generally has three characteristics of reflexivity, symmetry, transitivity, According to the above characteristics, if an integer pair does not have an equivalence relationship, then the direct output, if present, does not output. Simply to cite a few examples, the computer network to determine whether two computers need to establish a new connection communication, if you can communicate through one or several nodes, then we do not need to establish a new connection, mathematics can be p
and q as a set, off-topic, see How to achieve it, four ways progressive:
Quick-find Algorithm
P and Q are connected on the network can be seen as a connection, a separate view of P and Q can be regarded as the contact point, you can determine whether there is a P and Q or PQ equivalent connection:
@interface Dynamicunion:nsobject@property (strong,nonatomic) Nsmutablearray *ids;//stores the value corresponding to each contact @property (assign , nonatomic) Nsinteger count;//The number of connections connected-(BOOL) Connected: (Nsinteger) a secondnumber: (Nsinteger) b;// Whether there is already a connection or equivalent connection-(Nsinteger) Find: (Nsinteger) index;//Remove the value of the contact-(void) Dynamicunion: (Nsinteger) a secondnumber: ( Nsinteger) B;//a,b Establish a connection between (void) InitData: (Nsinteger) count;//Initialize the number of contacts @end
Specific implementation code:
-(void) InitData: (nsinteger) count{ self.count=count; Self.ids=[[nsmutablearray Alloc]initwithcapacity:count]; for (Nsinteger i=0; i<count; i++) { [self.ids addobject:[nsnumber numberwithinteger:i]; }} http://www.cnblogs.com/xiaofeixiang-(BOOL) Connected: (Nsinteger) a secondnumber: (nsinteger) b{ return [self Find:a]==[self find:b];} -(Nsinteger) Find: (Nsinteger) index{ return [[Self.ids Objectatindex:index] integervalue];} -(void) Dynamicunion: (Nsinteger) a secondnumber: (nsinteger) b{Nsinteger aid=[self find:a]; Nsinteger bid=[self find:b]; if (aid==bid) { return; } For (Nsinteger i=0;i<[self.ids Count]; i++) { if ([[Self.ids objectatindex:i] integervalue]==aid) { Self.ids[i]=[nsnumber numberwithinteger:bid]; } } Self.count=self.count-1;}
quick-union Algorithm
Quick-find in the Union process, each time the array is traversed, so lossy performance, or with the IDs array to store each contact value, but each value is not the same meaning, we can use the value in IDs storage contact parent, as a tree exists, we do not have to traverse the IDs array, Simply speaking is 4,3 when ids[4] stored value when the deposit is 3, so that the end will be as long as the root node can be determined. Other methods don't change, we just need to change the find and Dynamicunion methods.
-(Nsinteger) Find: (Nsinteger) index{while (Index!=[[self.ids Objectatindex:index] integervalue]) { index=[[ Self.ids Objectatindex:index] integervalue]; } return index;} http://www.cnblogs.com/xiaofeixiang-(void) Dynamicunion: (Nsinteger) a secondnumber: (nsinteger) b{ NSInteger Aroot=[self find:a]; Nsinteger broot=[self find:b]; if (aroot==broot) { return; } Self.ids[aroot]=[nsnumber Numberwithinteger:broot]; self.count--; }
Weighted quick-union algorithm
Quick-union There may be a situation where the tree's parent level may end up being a small tree, because we need to pass a weight value to avoid this, but we need to review the underlying concept of a tree. The size of a tree is the number of its nodes, and the depth of a node in the tree is the number of links to its path to the root node. The height of the loss is the maximum depth of all its nodes. The weighted energy guarantees that each find, connected, and union are LGN levels.
Http://www.cnblogs.com/xiaofeixiang@interface Dynamicunionweight:nsobject@property (strong,nonatomic) Nsmutablearray *ids;//stores the value corresponding to each contact @property (strong,nonatomic) Nsmutablearray *weightarr;// The size of each root node for the component of ING @property (assign,nonatomic) Nsinteger count;//The number of connections that have been connected-(BOOL) Connected: (Nsinteger) A Secondnumber: (Nsinteger) b;//whether there is already a connection or equivalent connection-(Nsinteger) Find: (Nsinteger) index;//Remove the value of the contact-(void) Dynamicunion: ( Nsinteger) a secondnumber: (Nsinteger) B;//a,b Establish a connection-(void) InitData: (Nsinteger) count;//Initialize the number of contacts @end
Specific implementation:
-(void) InitData: (Nsinteger) count{Self.count=count; Self.ids=[[nsmutablearray Alloc]initwithcapacity:count]; Self.weightarr=[[nsmutablearray Alloc]initwithcapacity:count]; for (Nsinteger i=0; i<count; i++) {[Self.ids addobject:[nsnumber numberwithinteger:i]]; [Self.weightarr Addobject:[nsnumber numberwithinteger:1]; }}//http://www.cnblogs.com/xiaofeixiang-(BOOL) Connected: (Nsinteger) a secondnumber: (Nsinteger) b{return [self find: A]==[self find:b];} -(Nsinteger) Find: (Nsinteger) index{while (Index!=[[self.ids Objectatindex:index] integervalue]) {INDEX=[[SELF.I DS Objectatindex:index] integervalue]; } return index; -(void) Dynamicunion: (Nsinteger) a secondnumber: (nsinteger) b{Nsinteger i=[self find:a]; Nsinteger j=[self Find:b]; if (i==j) {return; } nsinteger Weighta=[[self.weightarr objectatindex:i] integervalue]; Nsinteger Weightb=[[self.weightarr Objectatindex:j] integervalue]; if (WEIGHTA<WEIGHTB) {Self.ids[i]=[nsnumber numberwithinteger:j]; Self.weightarr[j]=[nsnumber NUMBERWITHINTEGER:WEIGHTA+WEIGHTB]; }else{Self.ids[j]=[nsnumber NUMBERWITHINTEGER:I]; Self.weightarr[i]=[nsnumber NUMBERWITHINTEGER:WEIGHTA+WEIGHTB]; } self.count--;}
path compression algorithm
Path compression guarantees that the union is close to 1, and this implementation requires only a slight change in the weighted quick-union algorithm, changing the find:
-(Nsinteger) Find: (Nsinteger) index{while (Index!=[[self.ids ObjectAtIndex: Index] IntegerValue]) {Self.ids[index]=self.ids[[self.ids[index] integervalue]]; Index=[[self.ids Objectatindex:index] IntegerValue]; } return index; http://www.cnblogs.com/xiaofeixiang-(void) Dynamicunion: (Nsinteger) a secondnumber: (nsinteger) b{NSInteger i=[ Self find:a]; Nsinteger j=[self Find:b]; if (i==j) {return; } nsinteger Weighta=[[self.weightarr objectatindex:i] integervalue]; Nsinteger Weightb=[[self.weightarr Objectatindex:j] integervalue]; if (WEIGHTA<WEIGHTB) {self.ids[i]=[nsnumber numberwithinteger:j]; Self.weightarr[j]=[nsnumber NUMBERWITHINTEGER:WEIGHTA+WEIGHTB]; }else{Self.ids[j]=[nsnumber NUMBERWITHINTEGER:I]; Self.weightarr[i]=[nsnumber NUMBERWITHINTEGER:WEIGHTA+WEIGHTB]; } self.count--;}
simulation test:
Dynamicunion *dynamicunion=[[dynamicunion Alloc]init]; [Dynamicunion Initdata:10]; Nsmutablearray *datasource=[[nsmutablearray Alloc]initwithcapacity:10]; [DataSource addobject:@ "4,3"]; [DataSource addobject:@ "3,8"]; [DataSource addobject:@ "6,5"]; [DataSource addobject:@ "9,4"]; [DataSource addobject:@ "2,1"]; [DataSource addobject:@ "8,9"]; [DataSource addobject:@ "5,0"]; [DataSource addobject:@ "7,2"]; [DataSource addobject:@ "6,1"]; [DataSource addobject:@ "1,0"]; for (Nsinteger i=0; I<[datasource count]; i++) {nsstring *node=[datasource objectatindex:i]; Nsinteger A=[[node substringwithrange:nsmakerange (0, 1)] integervalue]; Nsinteger B=[[node Substringwithrange:nsmakerange (2, 1)] integervalue]; if ([Dynamicunion connected:a secondnumber:b]) {continue; } [Dynamicunion dynamicunion:a secondnumber:b]; NSLog (@ "%ld---%ld", A, b); } NSLog (@ "%ld already exists connection", dynamicunion.count); NSLog (@ "iOS technology Group: 228407086"); NSLog (@ "Original address: Http://www.cnblogs.com/xiaofeixiang");
The results are as follows:
Algorithm-Dynamic connectivity