C # common tree generation method

Source: Internet
Author: User

 

This tree structure is often used when writing a program. For interface programming, TreeView is a good choice. You can bind data with several settings, but what if I write the class myself? It is relatively troublesome.

 

Here we will discuss how to quickly build your own tree structure, that is, how to extract the methods for building and reuse them.

 

Code reuse is similar to class, interface, and generic.

 

First consider using interfaces to implement, define an ITreeNode, and then implement each node that wants to establish a tree structure? It doesn't feel good, because it is very troublesome to define a series of things, such as Parent Children, and every implementation is very difficult.

 

Which image class? It is convenient to inherit abstract classes, but it involves various types of conversions in actual use, so the code is not easy to write.

 

What about generics? The generic structure is too general, but it can be a compromise, that is, the class that defines a node with the generic type

 

(The younger brother's code writing method is relatively "compromised". As an adult said, you will be watching it)

 

 

 

1 namespace Soway. DB. Tree

2 {

3 public class TreeNode <T>

4 {

5

6 public T Data {get; set ;}

7 public TreeNode <T> Parent {get; set ;}

8 public List <TreeNode <T> Children {get; set ;}

9}

10}

 

 

 

After the node class is defined, it is necessary to implement a TreeFactory and propose a general algorithm for the Creation.

 

 

 

Namespace Soway. DB. Tree

{

 

Public class TreeFactory <T>

{

Public List <TreeNode <T> CreateTreeByLevel

(List <T> Items)

{

//////

}

}

}

 

Here, my method name is ByLevel by default, that is, build a tree by layer. In this way, a new problem occurs again:

 

1. How can I ensure that the input value Items has been set up on a layer-by-layer basis?

 

2. How to layer? That is, how to differentiate the relationship between the parent node, child node, and peer node of the tree?

 

These problems are actually related to the specific type of the generic type, but if we constrain the specific type, it violates our intention.

 

Let's take a step by step. First, define the relationship between Tree nodes as an enumeration:

 

 

 

Namespace Soway. DB. Tree

{

Public enum TeeNodeCompareResult

{

/// <Summary>

/// Tree node

/// </Summary>

Parent,

/// <Summary>

/// Subnode

/// </Summary>

Child,

/// <Summary>

/// Next peer node

/// </Summary>

NextNode,

/// <Summary>

/// Previous peer node

/// </Summary>

PreNode,

/// <Summary>

/// Same node

/// </Summary>

EquealNode,

/// <Summary>

/// Node of the next layer

/// </Summary>

NexLevelNode

 

}

}

 

 

 

With this relationship, I had a further idea. I want to pass a delegate to the TreeFactory to obtain the comparison between the two nodes:

 

 

 

Namespace Soway. DB. Tree

{

Public delegate TeeNodeCompareResult TeeNodeCompare <T> (T child, T parent );

}

 

In this way, our TreeFactory has an additional member of the generic delegate...

 

 

 

Private TeeNodeCompare <T> compare;

 

Public TreeFactory (Tree. TeeNodeCompare <T> Compare)

{

This. compare = Compare;

 

}

 

 

 

Now, after this generic delegate is processed, we can solve the problem in the next step, that is, sort the input Items by layer. If there is a Comparison <T> (), I directly call List <T>. sort (Comprarion <T> ).

 

The following describes how to implement Comparation <T>:

 

 

 

Private int CompareResult (T ob1, T ob2)

{

Switch (compare (ob1, ob2 ))

{

Case TeeNodeCompareResult. Child:

Case TeeNodeCompareResult. NextNode:

Case TeeNodeCompareResult. NexLevelNode:

Return 1;

Case TeeNodeCompareResult. Parent:

Case TeeNodeCompareResult. PreNode:

Return-1;

Default:

Return 0;

}

}

 

Well, after these basic jobs are completed, it will be easy to build:

 

 

 

/// <Summary>

/// Create a tree by Layer

/// </Summary>

/// <Param name = "Items"> create a set of trees </param>

/// <Returns> Create a tree structure </returns>

Public List <TreeNode <T> CreateTreeByLevel

(List <T> Items)

{

Items. Sort (new Comparison <T> (this. CompareResult ));

List <TreeNode <T> result = new List <TreeNode <T> ();

TreeNode <T> lastNode = null;

Queue <TreeNode <T> queue = new Queue <TreeNode <T> ();

TreeNode <T> currentNode = null;

Var current = result;

If (Items. Count> 0)

{

 

 

 

For (int I = 0; I <Items. Count; I ++)

{

 

 

TreeNode <T> AddedNode = new TreeNode <T> () {Data = Items [I],

Parent = null, Children = new List <TreeNode <T> ()}; // generate the data to be added

 

Queue. Enqueue (AddedNode); // enter the queue

// Check whether the node at the next layer is reached

If (lastNode! = Null &&

(Compare (AddedNode. Data, lastNode. Data) = Tree. TeeNodeCompareResult. Child

| Compare (AddedNode. Data, lastNode. Data) = Tree. TeeNodeCompareResult. NexLevelNode) // next layer: that is, the node is a subnode or a next layer node.

)

{

CurrentNode = queue. Dequeue ();

}

// Find the corresponding parent node

While (currentNode! = Null

&&

Compare (AddedNode. Data, currentNode. Data )! = TeeNodeCompareResult. Child

)

{

CurrentNode = queue. Dequeue ();

}

If (currentNode! = Null & compare (AddedNode. Data, currentNode. Data )! = TeeNodeCompareResult. EquealNode)

{

AddedNode. Parent = currentNode;

Current = currentNode. Children;

}

Current. Add (AddedNode );

LastNode = AddedNode;

}

}

Return result;

 

}

 

 

 

Below is a Demo using ^_^

 

 

 

// Class:

{

[Table (Name = "Auth")]

Public class Auth

{

[Column (IsKey = true)]

Public string Code {get; set ;}

Public string Name {get; set ;}

Public String Url {get; set ;}

Public string View {get; set ;}

Public string Action {get; set ;}

Public string Text {get; set ;}

Public string Image {get; set ;}

 

 

Public override string ToString ()

{

Return Code + "" + Name;

}

 

 

}

// Compare the relationship between nodes:

Static Soway. DB. Tree. TeeNodeCompareResult compare (Auth ob1, Auth ob2)

{

 

If (ob1.Code = ob2.Code)

Return TeeNodeCompareResult. EquealNode;

If (ob1.Code. Length> ob2.Code. Length)

If (ob1.Code. IndexOf (ob2.Code) = 0)

Return TeeNodeCompareResult. Child;

Else

Return TeeNodeCompareResult. NexLevelNode;

Else if (ob1.Code. Length <ob2.Code. Length)

Return TeeNodeCompareResult. Parent;

Else if (ob1.Code. CompareTo (ob2.Code) <0)

Return TeeNodeCompareResult. PreNode;

Else

Return TeeNodeCompareResult. NextNode;

 

}

 

 

/// Www.2cto.com in the main function

Var c = new Soway. DB. DBContext (builder. ToString ());

Var items = c. Get <Auth> (); // Initialization

Var tree = new TreeFactory <Auth> (new TeeNodeCompare <Auth> (compare). CreateTreeByLevel (items); // create a tree Structure

 

FROM Ge Yunfei

Related Article

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.