2

親子関係で組み立てられた大きな結果セットがあります。ツリーを歩き、結果をユーザーに表示する必要があります。

再帰を使用する前にこれを実行しましたが、結果セットが大きい可能性があるため、StackOverflowExceptionを受け取る可能性を回避したいと思います。

スタックを使用するMSDNで次のを見つけました。私が抱えている問題は、スタックが後入れ先出しであるため、データが正しく表示されないことです。次のようにしたいと思います。


LeveL 1
Level 1.1
Level 1.1.1 
Level 1.1.2 
Level 1.2 
Level 1.2.1 
Level 1.2.2

しかし、次のようになります。


LeveL 1
Level 1.2 
Level 1.2.2 
Level 1.2.1 
Level 1.1 
Level 1.1.2 
Level 1.1.1 

何か案は?

これが私のコードの例です。に次の列があると仮定しDataTable dtます:ID、ParentID、およびText

    private struct Item
    {
        public string Text;
        public int ID;
        public int ParentID;
    }

    private void BuildView()
    {
        Stack<Item> itemTree = new Stack<Item>(40);

        //Get All Parent Nodes
        DataView dv = new DataView(dt);
        dv.RowFilter = "ParentID = 0";

        //Add the parent nodes to the stack
        foreach (DataRowView drv in dv)
        {
            Item item = new Item();
            item.Text = drv["Text"].ToString();
            item.ID = drv["ID"].ToString();
            item.ParentID = drv["ParentID"].ToString();
            itemTree.Push(item);
        }

        //Go through the stack one node at a time
        while (itemTree.Count > 0)
        {
            Item currentItem = itemTree.Pop();
            Debug.WriteLine(currentItem.Text);

            //Get children of current node
            dv.RowFilter = String.Format("ParentID = {0}", currentItem.ID);
            if (dv.Count > 0)
            {
                //Add child nodes to the stack
                foreach (DataRowView drvChild in dv)
                {
                    Item item = new Item();
                    item.Text = drvChild["Text"].ToString();
                    item.ID = drvChild["ID"].ToString();
                    item.ParentID = drvChild["ParentID"].ToString();
                    itemTree.Push(item);
                }
            }
        }

    }
4

4 に答える 4

3

現在のアルゴリズムでは、最初に適切な子を選択します。

最初に子供を残します。それで全部です。

たとえば、コードには次のようなものがあります。

node = node.rightChild()

に変更します

node = node.leftChild()

これは、この種の問題の一般的な解決策です。

MSDNの実装ではこの種のコードは公開されていないため、コメントすることはできません。

于 2009-02-03T18:21:24.833 に答える
1

アイテムを逆の順序でスタックにプッシュします。つまり、1の前に2を押します。

例:

// suppose I want to push children[] onto the stack

for (int i = children.Length - 1; i >= 0; i--)
{
   stack.Push(children[i]);
}

コードでこれを行うには、次のfor-eachステートメントを試してください。

foreach (DataRowView drvChild in dv.Reverse())
于 2009-02-03T18:24:45.623 に答える
0

懸念されるのが単に順序である場合は、スタックの使用からキューの使用に変更してください。これらは実際の目的では同じですが、キューが先入れ先出しであるという違いがあります。

于 2009-02-03T18:45:55.377 に答える
0

子ノードの反復を逆の順序で変更することにより、必要に応じて表示されます

//Add child nodes to the stack
for (int i = dv.Count - 1; i >= 0; i--)
{
    DataRowView drvChild = dv[i];
    Item item = new Item();
    item.Text = drvChild["Text"].ToString();
    item.ID = drvChild["ID"].ToString();
    item.ParentID = drvChild["ParentID"].ToString();
    itemTree.Push(item);
}
于 2009-02-03T19:07:49.170 に答える