Rather than List you might consider System.Collections.BitArray
You might try something like this (pseudo code):
Stack<T> stk
stk.Push(node1)
grandparentnode = null
count = 0
if node1 state is 1 count++
while (node = stk.Pop())
foreach connect in node.connections
if the connect state is 1
if connect != grandparentnode
stk.Push(connect)
count++
grandparentnode = node
I think that will work, but graphs are hard and my brain is very small and filled with errors :-(
Adding to post based on comment.
The grandparent node was a misguided attempt to eliminate the "Visited" field by maintaining a constant rolling grandparent/parent/child relationship. I'm a good programmer but perhaps don't have a mind for graph theory (which is why I'm drawn to such questions :-D) Anyway here is a complete program with revised code which I reached working with my original ideas. It depends on the grid like, double connected arrangement of your nodes and the idea of having a unique numerically increasing label for each. Those constraints might be too specific for your usage. I used a dictionary, but it should never contain more than 4 items. Created a custom class optimized for such a small collection would improve performance. This should remove the need to keep a 'visited' state, run quickly and not recurse. To find any subtree you need to start at the lowest label node of that tree.
It is of course also possible it arrived at the right answer out of luck :-) Worst case if gives anyone interested a full program skeleton to play with.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace stackoverflow1 {
class Program {
class Node {
public int Number;
public int State = 0;
public List<Node> Connects = new List<Node>();
public Node(int num, int state) {
Number = num;
State = state;
}
}
static void Main(string[] args) {
var nodes = new List<Node>();
nodes.Add(new Node(0, -1)); // not used
nodes.Add(new Node(1, 1));
nodes.Add(new Node(2, 1));
nodes.Add(new Node(3, 1));
nodes.Add(new Node(4, 0));
nodes.Add(new Node(5, 1));
nodes.Add(new Node(6, 1));
nodes.Add(new Node(7, 0));
nodes.Add(new Node(8, 0));
nodes.Add(new Node(9, 0));
nodes[1].Connects.Add(nodes[2]);
nodes[1].Connects.Add(nodes[4]);
nodes[2].Connects.Add(nodes[1]);
nodes[2].Connects.Add(nodes[3]);
nodes[2].Connects.Add(nodes[5]);
nodes[3].Connects.Add(nodes[2]);
nodes[3].Connects.Add(nodes[6]);
nodes[4].Connects.Add(nodes[1]);
nodes[4].Connects.Add(nodes[5]);
nodes[4].Connects.Add(nodes[7]);
nodes[5].Connects.Add(nodes[2]);
nodes[5].Connects.Add(nodes[4]);
nodes[5].Connects.Add(nodes[6]);
nodes[5].Connects.Add(nodes[8]);
nodes[6].Connects.Add(nodes[3]);
nodes[6].Connects.Add(nodes[5]);
nodes[6].Connects.Add(nodes[9]);
nodes[7].Connects.Add(nodes[4]);
nodes[7].Connects.Add(nodes[8]);
nodes[8].Connects.Add(nodes[5]);
nodes[8].Connects.Add(nodes[7]);
nodes[8].Connects.Add(nodes[9]);
nodes[9].Connects.Add(nodes[6]);
nodes[9].Connects.Add(nodes[8]);
var dict = new Dictionary<int, Node>();
foreach (var n in nodes) {
if (n.State == 1) {
dict.Add(n.Number, n);
break;
}
}
int count = dict.Count;
while (dict.Count > 0) {
foreach (var k in dict.Keys.ToArray()) { // retains node order
var n = dict[k]; // get the first node in number order
dict.Remove(k);
foreach (var node in n.Connects) { // look over it's connections/children
if ((node.State == 1)
&& (node.Number > n.Number)) {
if (dict.ContainsKey(node.Number) == false) {
// only add if this is has a greater number than the one
// being considered because lower values have already been
// processed
dict.Add(node.Number, node);
count++;
}
}
}
}
}
Console.WriteLine("Count = {0}", count);
Console.ReadKey();
}
}
}