C# 按层次对列表进行排序

C# 按层次对列表进行排序,c#,list,sorting,C#,List,Sorting,我需要按层次对列表进行排序,有人能帮我一下吗?列表如下所示: // create your list List<Person> persons = new List<Person>(); // populate it persons.Add(new Person("child", "father")); persons.Add(new Person("father", "grandfathe

我需要按层次对列表进行排序,有人能帮我一下吗?列表如下所示:

        // create your list
        List<Person> persons = new List<Person>();

        // populate it
        persons.Add(new Person("child", "father"));
        persons.Add(new Person("father", "grandfather"));
        persons.Add(new Person("grandfather", "grandgrandfather"));
        persons.Add(new Person("grandgrandfather", null));
public class Person : IComparable<Person>
{
    public String ID { get; set; }
    public String ParentID { get; set; }

    public Person(String id, String pid)
    {
        this.ID = id;
        this.ParentID = pid;
    }

    public Int32 CompareTo(Person right)
    {


        if (this.ID.Equals(right.ID))
            return 0;

        if (this.ParentID == null) return -1;
        if (right.ParentID == null) return 1;


        return this.ParentID.CompareTo(right.ID);
    }
const int child = 0;
const int father = 1;
const int grandfather = 2;
const int greatgrandfather = 3;

// create your list
List<Person> persons = new List<Person>();

// populate it
persons.Add(new Person(child));
persons.Add(new Person(father));
persons.Add(new Person(grandfather));
persons.Add(new Person(grandgrandfather));

public class Person : IComparable<Person>
{
    public int ID { get; set; }

    public Person(int id)
    {
        this.ID = id;
    }

    public Int32 CompareTo(Person right)
    {
        if (this.ID == right.ID)
            return 0;

        if (this.ID > right.ID) return -1;
        else return 1;
    }
}
//创建您的列表
列表人员=新列表();
//填充它
新增(新增人员(“子女”、“父亲”);
添加(新的人(“父亲”、“祖父”);
人员。添加(新人员(“祖父”、“祖父”);
人员。添加(新人员(“祖父”,空);
我想要像这样的东西:

  • 祖父
  • 祖父
  • 父亲
  • 孩子
我尝试在我的类“Person”中实现IComparable,如下所示:

        // create your list
        List<Person> persons = new List<Person>();

        // populate it
        persons.Add(new Person("child", "father"));
        persons.Add(new Person("father", "grandfather"));
        persons.Add(new Person("grandfather", "grandgrandfather"));
        persons.Add(new Person("grandgrandfather", null));
public class Person : IComparable<Person>
{
    public String ID { get; set; }
    public String ParentID { get; set; }

    public Person(String id, String pid)
    {
        this.ID = id;
        this.ParentID = pid;
    }

    public Int32 CompareTo(Person right)
    {


        if (this.ID.Equals(right.ID))
            return 0;

        if (this.ParentID == null) return -1;
        if (right.ParentID == null) return 1;


        return this.ParentID.CompareTo(right.ID);
    }
const int child = 0;
const int father = 1;
const int grandfather = 2;
const int greatgrandfather = 3;

// create your list
List<Person> persons = new List<Person>();

// populate it
persons.Add(new Person(child));
persons.Add(new Person(father));
persons.Add(new Person(grandfather));
persons.Add(new Person(grandgrandfather));

public class Person : IComparable<Person>
{
    public int ID { get; set; }

    public Person(int id)
    {
        this.ID = id;
    }

    public Int32 CompareTo(Person right)
    {
        if (this.ID == right.ID)
            return 0;

        if (this.ID > right.ID) return -1;
        else return 1;
    }
}
公共类人员:i可比较
{
公共字符串ID{get;set;}
公共字符串ParentID{get;set;}
公众人物(字符串id、字符串pid)
{
this.ID=ID;
this.ParentID=pid;
}
公共Int32比较(个人权利)
{
if(this.ID.Equals(right.ID))
返回0;
if(this.ParentID==null)返回-1;
if(right.ParentID==null)返回1;
将此.ParentID.CompareTo(右.ID)返回;
}
}


但是它并没有起作用……

您必须根据排序逻辑修改
公共int CompareTo(Person right)
方法的逻辑

比如说

if (this.ID == grandgrandfather &&  
        right.ID == grandfather) return 1;


if (this.ID == grandgrandfather &&  
        right.ID == child) return 1;

....... a lot more 

您必须根据排序逻辑修改
public int CompareTo(Person right)
方法的逻辑

比如说

if (this.ID == grandgrandfather &&  
        right.ID == grandfather) return 1;


if (this.ID == grandgrandfather &&  
        right.ID == child) return 1;

....... a lot more 

这是一个数据问题。您正在尝试比较字符串值,但数据中没有提供相对关系的固有内容

我建议您将您的值转换为枚举,然后可以很容易地进行比较。下面是一些我没有测试过的伪代码,但应该可以让您了解:

public class Person : IComparable<Person>
{
        public enum Types: int {
            None,
            Child,
            Father,
            Grandfather,
            GrandGrandFather
        }
    public Types ID { get; set; }
    public Types ParentID { get; set; }

    public Person(Types id, Types pid)
    {
        this.ID = id;
        this.ParentID = pid;
    }

    public Int32 CompareTo(Person right)
    {
        return this.ParentID.CompareTo(right.ID);
    }

}
公共类人员:i可比较
{
公共枚举类型:int{
没有一个
小孩
父亲
祖父
祖父
}
公共类型ID{get;set;}
公共类型ParentID{get;set;}
公众人物(类型id、类型pid)
{
this.ID=ID;
this.ParentID=pid;
}
公共Int32比较(个人权利)
{
将此.ParentID.CompareTo(右.ID)返回;
}
}

这是一个数据问题。您正在尝试比较字符串值,但数据中没有提供相对关系的固有内容

我建议您将您的值转换为枚举,然后可以很容易地进行比较。下面是一些我没有测试过的伪代码,但应该可以让您了解:

public class Person : IComparable<Person>
{
        public enum Types: int {
            None,
            Child,
            Father,
            Grandfather,
            GrandGrandFather
        }
    public Types ID { get; set; }
    public Types ParentID { get; set; }

    public Person(Types id, Types pid)
    {
        this.ID = id;
        this.ParentID = pid;
    }

    public Int32 CompareTo(Person right)
    {
        return this.ParentID.CompareTo(right.ID);
    }

}
公共类人员:i可比较
{
公共枚举类型:int{
没有一个
小孩
父亲
祖父
祖父
}
公共类型ID{get;set;}
公共类型ParentID{get;set;}
公众人物(类型id、类型pid)
{
this.ID=ID;
this.ParentID=pid;
}
公共Int32比较(个人权利)
{
将此.ParentID.CompareTo(右.ID)返回;
}
}

您的问题是,如果值分布太远,您无法确定哪个值更大。例如:您的祖父和子元素将始终返回-1,因为字符串“父”总是小于字符串“祖父”。尝试将个人值转换为常量int值,然后进行如下比较:

        // create your list
        List<Person> persons = new List<Person>();

        // populate it
        persons.Add(new Person("child", "father"));
        persons.Add(new Person("father", "grandfather"));
        persons.Add(new Person("grandfather", "grandgrandfather"));
        persons.Add(new Person("grandgrandfather", null));
public class Person : IComparable<Person>
{
    public String ID { get; set; }
    public String ParentID { get; set; }

    public Person(String id, String pid)
    {
        this.ID = id;
        this.ParentID = pid;
    }

    public Int32 CompareTo(Person right)
    {


        if (this.ID.Equals(right.ID))
            return 0;

        if (this.ParentID == null) return -1;
        if (right.ParentID == null) return 1;


        return this.ParentID.CompareTo(right.ID);
    }
const int child = 0;
const int father = 1;
const int grandfather = 2;
const int greatgrandfather = 3;

// create your list
List<Person> persons = new List<Person>();

// populate it
persons.Add(new Person(child));
persons.Add(new Person(father));
persons.Add(new Person(grandfather));
persons.Add(new Person(grandgrandfather));

public class Person : IComparable<Person>
{
    public int ID { get; set; }

    public Person(int id)
    {
        this.ID = id;
    }

    public Int32 CompareTo(Person right)
    {
        if (this.ID == right.ID)
            return 0;

        if (this.ID > right.ID) return -1;
        else return 1;
    }
}
const int child=0;
const int father=1;
常数=2;
常量int greatgrander=3;
//创建您的列表
列表人员=新列表();
//填充它
新增(新增人员(子女));
人员。添加(新人员(父亲));
人员。添加(新人员(祖父));
人员。添加(新人员(祖父));
公共类人物:i可比较
{
公共int ID{get;set;}
公众人士(国际身份证)
{
this.ID=ID;
}
公共Int32比较(个人权利)
{
if(this.ID==right.ID)
返回0;
if(this.ID>right.ID)返回-1;
否则返回1;
}
}

您的问题是,如果值分布太远,您无法确定哪个值更大。例如:您的祖父和子元素将始终返回-1,因为字符串“父”总是小于字符串“祖父”。尝试将个人值转换为常量int值,然后进行如下比较:

        // create your list
        List<Person> persons = new List<Person>();

        // populate it
        persons.Add(new Person("child", "father"));
        persons.Add(new Person("father", "grandfather"));
        persons.Add(new Person("grandfather", "grandgrandfather"));
        persons.Add(new Person("grandgrandfather", null));
public class Person : IComparable<Person>
{
    public String ID { get; set; }
    public String ParentID { get; set; }

    public Person(String id, String pid)
    {
        this.ID = id;
        this.ParentID = pid;
    }

    public Int32 CompareTo(Person right)
    {


        if (this.ID.Equals(right.ID))
            return 0;

        if (this.ParentID == null) return -1;
        if (right.ParentID == null) return 1;


        return this.ParentID.CompareTo(right.ID);
    }
const int child = 0;
const int father = 1;
const int grandfather = 2;
const int greatgrandfather = 3;

// create your list
List<Person> persons = new List<Person>();

// populate it
persons.Add(new Person(child));
persons.Add(new Person(father));
persons.Add(new Person(grandfather));
persons.Add(new Person(grandgrandfather));

public class Person : IComparable<Person>
{
    public int ID { get; set; }

    public Person(int id)
    {
        this.ID = id;
    }

    public Int32 CompareTo(Person right)
    {
        if (this.ID == right.ID)
            return 0;

        if (this.ID > right.ID) return -1;
        else return 1;
    }
}
const int child=0;
const int father=1;
常数=2;
常量int greatgrander=3;
//创建您的列表
列表人员=新列表();
//填充它
新增(新增人员(子女));
人员。添加(新人员(父亲));
人员。添加(新人员(祖父));
人员。添加(新人员(祖父));
公共类人物:i可比较
{
公共int ID{get;set;}
公众人士(国际身份证)
{
this.ID=ID;
}
公共Int32比较(个人权利)
{
if(this.ID==right.ID)
返回0;
if(this.ID>right.ID)返回-1;
否则返回1;
}
}

您需要计算层次结构中项目的部门,并按部门对列表进行排序:

如果以下为人员类别:

class Person 
{
    public string Name {get; private set;}
    public string Parent {get; private set;}

    public Person(string name, string parent) 
    {
        this.Name = name;
        this.Parent = parent;
    }
}
这是一个计算层次结构中人员的部门的方法示例

int GetDept(List<Person> list, Person person) 
{
    if (person.Parent == null) return 0;
    return GetDept(list, list.First(p => p.Name == person.Parent)) + 1;
}

请注意,在本例中,dept的计算效率不高,因为
GetDept
方法将一次又一次地调用它自己,并且它对列表使用O(n)查找。所有这些都可以通过为每个人只计算一次dept并将其存储,再加上更高效的查找机制(如字典)来提高大型数据集的性能。

您需要计算层次结构中项目的dept,并按dept对列表进行排序:

如果以下为人员类别:

class Person 
{
    public string Name {get; private set;}
    public string Parent {get; private set;}

    public Person(string name, string parent) 
    {
        this.Name = name;
        this.Parent = parent;
    }
}
这是一个计算层次结构中人员的部门的方法示例

int GetDept(List<Person> list, Person person) 
{
    if (person.Parent == null) return 0;
    return GetDept(list, list.First(p => p.Name == person.Parent)) + 1;
}
注意,在本例中,dept不是计算eff的