說起那個無限級分類,相信很多人都知道是什麼東西,也曾經做過。我也相信,大家用得最多的實作方式就是做一個遞歸。
最近我也要做一個帶無限級分類的菜單,但是我又不想用遞歸來做,是以我需要用其他方式來實作,那就是疊代了。
首先,我需要定義一個實體模型,這舉一個省市無限級的例子:
class Loaction
{
public int ID { get; set; }
public int PID { get; set; }
public string Name { get; set; } //地方名
public int Level { get; set; } //深度
}
然後寫方法,這裡需要利用到棧的後進先出的特點:
public static List<Loaction> Soft(List<Loaction> data, int pid)
{
Stack task = new Stack();
task.Push(pid);
List<Loaction> tree = new List<Loaction>();
int level = 0;
while (task.Count > 0)
{
bool flag = false;
for (int i = 0; i < data.Count; i++)
{
var l = data[i];
if (l.PID == pid)
{
pid = l.ID;
task.Push(l.ID);
l.Level = level;
level++;
tree.Add(l);
data.Remove(l);
i--;
flag=true;
}
}
if (!flag)
{
task.Pop();
if (task.Count > 0)
{
pid = Convert.ToInt32(task.Peek());
level--;
}
}
}
return tree;
}
最後準備資料->調用->輸出:
static void Main(string[] args)
{
var data = new List<Loaction>();
data.Add(new Loaction() { ID = 1, PID = 0, Name = "北京" });
data.Add(new Loaction() { ID = 2, PID = 0, Name = "廣東" });
data.Add(new Loaction() { ID = 3, PID = 0, Name = "上海" });
data.Add(new Loaction() { ID = 4, PID = 0, Name = "重慶" });
data.Add(new Loaction() { ID = 5, PID = 0, Name = "黑龍江" });
data.Add(new Loaction() { ID = 6, PID = 1, Name = "豐台" });
data.Add(new Loaction() { ID = 7, PID = 1, Name = "海澱" });
data.Add(new Loaction() { ID = 8, PID = 1, Name = "石景山" });
data.Add(new Loaction() { ID = 9, PID = 3, Name = "上海市" });
data.Add(new Loaction() { ID = 10, PID = 2, Name = "廣州" });
data.Add(new Loaction() { ID = 11, PID = 5, Name = "齊齊哈爾" });
data.Add(new Loaction() { ID = 12, PID = 2, Name = "茂名" });
data.Add(new Loaction() { ID = 13, PID = 2, Name = "深圳" });
data.Add(new Loaction() { ID = 14, PID = 5, Name = "哈爾濱" });
data.Add(new Loaction() { ID = 15, PID = 4, Name = "重慶市" });
data.Add(new Loaction() { ID = 16, PID = 2, Name = "東莞" });
data.Add(new Loaction() { ID = 17, PID = 2, Name = "中山" });
data.Add(new Loaction() { ID = 18, PID = 16, Name = "厚街鎮" });
var tree = Soft(data, 0);
foreach (var t in tree)
{
var sb = new StringBuilder();
for (int i = 0; i < t.Level; i++)
{
sb.Append(" ");
}
sb.Append(t.Name);
Console.WriteLine(sb.ToString());
}
Console.ReadKey();
}
然後效果如下:
就是這個樣子。。。。。(END)