Archief - .NET Sorteren van boompjes

Het archief is een bevroren moment uit een vorige versie van dit forum, met andere regels en andere bazen. Deze posts weerspiegelen op geen enkele manier onze huidige ideeën, waarden of wereldbeelden en zijn op sommige plaatsen gecensureerd wegens ontoelaatbaar. Veel zijn in een andere tijdsgeest gemaakt, al dan niet ironisch - zoals in het ironische subforum Off-Topic - en zouden op dit moment niet meer gepost (mogen) worden. Toch bieden we dit archief nog graag aan als informatiedatabank en naslagwerk. Lees er hier meer over of start een gesprek met anderen.

KiPpIe

Legacy Member
Voor een bepaald iets had ik nood aan een boomstructuur. entries in mijn database hebben een ID, en ook een veld dat verwijst naar hetgeen er boven ligt.
Nu haal ik al die data uit mijn database en moet ik het ook logisch in mijn code krijgen.

Aangezien .NET zelf geen echte Trees ondersteunt heb ik zelf maar iets gemaakt dat de functionaliteit die ik nodig heb bevat.

Ik kwam uiteindelijk uit met volgende code:

Code:
    internal class TreeNode<T>
    {
        private TreeNode<T> _parent;
        private List<TreeNode<T>> _children;
        private object _key;
        private T _cargo;

        public IEnumerable<TreeNode<T>> Children
        {
            get
            {
                return _children;
            }
        }

        public TreeNode<T> Parent
        {
            get
            {
                return _parent;
            }
        }

        public object Key
        {
            get { return _key; }
            set { _key = value; }
        }

        public T Cargo
        {
            get { return _cargo; }
            set { _cargo = value; }
        }

        public TreeNode()
        {
            _children = new List<TreeNode<T>>();
        }

        public TreeNode(object Key, T cargo)
        {
            _key = Key;
            _cargo = cargo;
            _children = new List<TreeNode<T>>();
        }

        public void Add(TreeNode<T> Child)
        {
            _children.Add(Child);
            Child.SetParent(this);
        }

        public void Remove(TreeNode<T> Child)
        {
            Child.SetParent(null);
            _children.Remove(Child);
        }

        public void SetParent(TreeNode<T> Parent)
        {
            _parent = Parent;
        }

        public int Level
        {
            get
            {
                if (this._parent != null)
                    return _parent.Level + 1;
                else
                    return 0;
            }
        }

        public TreeNode<T> Find(TreeNode<T> Child)
        {
            if (this == Child)
                return this;
            foreach (TreeNode<T> child in _children)
                child.Find(Child);
            return null; //no child found
        }

        public TreeNode<T> FindKey(object key)
        {
            TreeNode<T> result = new TreeNode<T>();
            if (_key.Equals(key))
                return this;
            if (_children.Count > 0)
            {
                foreach (TreeNode<T> child in _children)
                {
                    result = child.FindKey(key);
                    if (result != null)
                        return result;
                }
            }
            return null;
        }

        public List<T> Items
        {
            get
            {
                List<T> items = new List<T>();
                items.Add(this.Cargo);
                foreach (TreeNode<T> child in _children)
                {
                    items.AddRange(child.Items);
                }
                return items;
            }
        }

        public List<TreeNode<T>> NodeList
        {
            get
            {
                List<TreeNode<T>> list = new List<TreeNode<T>>();
                list.Add(this);
                foreach (TreeNode<T> child in _children)
                {
                    list.AddRange(child.NodeList);
                }
                return list;
            }
        }
    }

Hoe bouw ik nu mijn boom op? Door eerst een root te maken, en dan door een lijst van entries te gaan.

halfslachtige pseudo-code:
Code:
foreach(entry ent in entrylist)
{
  if(root.FindKey(entry.top))
    root.FindKey(entry.top).Add(entry,entry.ID);
  else
   root.Add(entry,entry.ID);
}

redelijk simpel dus allemaal.

Dit werkt allemaal perfect als ik alles in de juiste volgorde toevoeg.
Doe ik dit echter in willekeurige volgorde, dan krijg ik een hoop kleinere subtrees allemaal onder mijn root.
Ik moet dus eigenlijk een manier vinden om dit alles op een deftige manier te ordenen.

Weet er iemand hoe ik het best door mijn boom kan traversen terwijl ik alles een beetje rangschik?
Kan ik dit best doen voor of na de populatie vanuit mijn lijst->boom ?

Alvast bedankt voor eventuele hulp

Cycloon

Legacy Member
Alles hangt af van hoe je data in elkaar zit. Vermits het om een vrij statische structuur gaat kan je best sorteren voordat je de boom hebt ingevuld. Voor het sorteren van boomstructuren zijn er wel enkele algoritmen. Welke je verkiest hangt een beetje van eigen smaak af.

djbramz

Legacy Member
Er bestaan allerhande soorten bomen naargelang de situatie. Een overzichtje van enkele vind je onderaan deze pagina.

KiPpIe

Legacy Member
Bedankt voor de hulp allemaal.
Jammer genoeg kan ik geen CTE gebruiken (gebruik ik wel op andere plaatsen in de DB) aangezien ik niet de volledige structuur ga ophalen en er ook "gaten" kunnen zijn. Achter elk gat plaats ik de nieuwe subtree gewoon onder de root waarbij ik de root (dummy object eig) gewoon laat vallen als ik de data uit de tree haal.

Maar ik denk dat ik er wel ga geraken met hetgeen jullie hebben gezegd.
Het archief is een bevroren moment uit een vorige versie van dit forum, met andere regels en andere bazen. Deze posts weerspiegelen op geen enkele manier onze huidige ideeën, waarden of wereldbeelden en zijn op sommige plaatsen gecensureerd wegens ontoelaatbaar. Veel zijn in een andere tijdsgeest gemaakt, al dan niet ironisch - zoals in het ironische subforum Off-Topic - en zouden op dit moment niet meer gepost (mogen) worden. Toch bieden we dit archief nog graag aan als informatiedatabank en naslagwerk. Lees er hier meer over of start een gesprek met anderen.
Terug
Bovenaan