Avatar billede ahara Nybegynder
04. februar 2006 - 18:09 Der er 39 kommentarer og
3 løsninger

Rekursiv funktion

Hej

Jeg har forsøgt at lave et binært træ hvor noderne ligger i et array af objekter. Jeg ønsker at tælle noderne i træet, men jeg har lidt problemer med min rekursive funktion.

Hvis jeg skal tælle noderne skal jeg oprette en global variabel (int nodes) for ellers overskrives variablen min rekursive funktion kaldes med (int count). Er det den rigtige løsning eller kan man benytte variablen som min rekursive funktion kaldes med?

Tak


******MIN KODE******

private int countNodes(Node parent, int count)
{
    count++;
    nodes++;

    if(parent.haveChilds()==true)
    {
        for(int i=0; i<2; i++)
        {
            if(i==0)
            {
                countNodes(parent.getChild1(),count);
            }
            else
            {
                    countNodes(parent.getChild2(),count);
            }
        }
    }
return count;
}

private void Form1_Load(object sender, System.EventArgs e)
{
int count=0;

node[0] = new Node();
node[1] = new Node();
node[2] = new Node();
node[3] = new Node();
node[4] = new Node();
node[5] = new Node();
node[6] = new Node();

node[0].add_childs(node[1],node[2],false);
node[1].add_childs(node[3],node[4],false);
node[2].add_childs(node[5],node[6],false);
node[3].add_childs(false);
node[4].add_childs(false);
node[5].add_childs(false);
node[6].add_childs(false);
   
count = countNodes(node[0],count);

textBox1.Text = Convert.ToString(nodes);
}
Avatar billede Syska Mester
04. februar 2006 - 18:27 #1
forstår slet ikke din kode.....

Prøver lige at lave noget....

// ouT
Avatar billede ahara Nybegynder
04. februar 2006 - 18:31 #2
Sådanne ser træet ud 

      0
    1    2
  3 4  5 6
Avatar billede ahara Nybegynder
04. februar 2006 - 18:33 #3
Jeg har bare lavet et array. For hver node i mit træ oprettes der et objekt. For hvert objekt der ikke er et leaf oprettes der childs.
Avatar billede Syska Mester
04. februar 2006 - 18:35 #4
private void button1_Click(object sender, EventArgs e)
{
    textBox1.Text = Count(treeView1.Nodes).ToString();
}

public static int Count(TreeNodeCollection tnc)
{
    int i = 0;

    i = tnc.Count;

    foreach (TreeNode tn in tnc)
    {
        i += Count(tn.Nodes);
    }

    return i;
}

Sådan her kan du gøre.....

// ouT
Avatar billede ahara Nybegynder
04. februar 2006 - 18:39 #5
Hmm. Har du set mit træ? Hvis jeg skal tælle noderne rekursivt så forstår jeg ikke hvorfor min kode ikke er ok "altså fremgangsmåden".
Avatar billede ahara Nybegynder
04. februar 2006 - 18:54 #6
Det skal selvfølgelig forstås som at jeg opretter et træ og skal tælle noderne rekursivt. Det er ikke meningen at jeg bare skal tage størrelsen på mit array.
Avatar billede Syska Mester
04. februar 2006 - 18:57 #7
Har du prøvet min kode?
Avatar billede Syska Mester
04. februar 2006 - 18:57 #8
Hvis ikke min kode gør som du gerne vil, tror jeg ikke helt jeg er med på hvad du vil.....
Avatar billede ahara Nybegynder
04. februar 2006 - 19:03 #9
Jeg ønsker at oprette et træ som nedenstående:   

      0
    1    2
  3 4  5 6

Dette er gjort ved oprettelse af et array der indeholder objekter af noder. Hver node kan have childs (altså noder der ligger under parent noden "0 har altså 1 og 2 som childs").

Nu ønsker jeg så at benytte en rekursiv funktion der tæller mine noder i arrayet. Funktionen er som følger:

private int countNodes(Node parent, int count)
{
    count++;
    nodes++;

    if(parent.haveChilds()==true)
    {
        for(int i=0; i<2; i++)
        {
            if(i==0)
            {
                countNodes(parent.getChild1(),count);
            }
            else
            {
                    countNodes(parent.getChild2(),count);
            }
        }
    }
return count;
}

Det virker egentlig godt nok, hvis jeg bare udskriver min globale variabel "nodes". Den tæller syv noder som der også er i mit træ. Mit spm er bare om jeg har mulighed for at få variablen count til at indeholde antallet af noder.
Avatar billede Syska Mester
04. februar 2006 - 19:48 #10
Ja, det kan du godt....

Er det asp.net eller hvad snakker vi om her?

Er Node din egen klasse?

Den sidste return du laver må vel returenere det samlede antal Nodes.....

// ouT
Avatar billede Syska Mester
04. februar 2006 - 19:50 #11
parent.getChild1() og parent.getChild2() hvad er det for nogle?

lidt mere info....

// ouT
Avatar billede ahara Nybegynder
04. februar 2006 - 20:05 #12
Det er skrevet i c# (visual studio).

Node er min egen klasse, hvis formål er at oprette objekter (noder) der indeholder 0..2 childs.

parent.GetChild1() returnerer child 1 for en node (for noden 0 er det 1)
parent.GetChild2() returnerer child 2 for en node (for noden 0 er det 2)
Avatar billede Syska Mester
04. februar 2006 - 20:12 #13
Hvorfor indeholder Node klasse ikke bare en "int" som inholder antal nodes der er i den, på den måde kan du jo også nemt lave sådan at der ikke kan addeds flere end 2 til hver Node......

Men en helt anden ting, er at jeg slet ikke forstår hvorfor du vil lave din egen klasse i stedet for at bruge det som allerede er lavet for dig......

// ouT
Avatar billede ahara Nybegynder
04. februar 2006 - 20:19 #14
Jeg ønsker som tidliger beskrevet oprette et binært træ, med f.eks. 7 noder (se tidligere tegning). Det har jeg gjort med min egen klasse. Derefter ønsker jeg en rekursiv funktion der tæller antallet af noder i træet. Forestil dig at jeg ikke kender array størrelsen mm. Selvfølgelig kan jeg bare tage størrelsen på mit array men det er ikke det jeg vil.

Hele denne sag drejer sig om min rekursive funktion der ikke returnere tallet 7 ved ovenstående eksempel uden jeg benytter min globale variabel.

Er der evt. andre der har et foreslag?
Avatar billede Syska Mester
04. februar 2006 - 20:36 #15
Tror så slet ikke jeg er med på hvad du mener med et binært træ?

Hvor skal det bruges henne? Kan ikke se nogen speciel funktionalitet i det eller noget, måske derfor jeg ikke lige kan gennemskue hvordan jeg kan hjælpe dig med det... men jeg lytter da gerne med, hvis andre har en idé.....

Lyder som om du har gang i noget vildt, eller også gør du bare det hele mere besværligt end det er........

// ouT
Avatar billede bitsch Nybegynder
04. februar 2006 - 22:44 #16
Og hvorfor vil du pine død stoppe den ind  et array?
Avatar billede bitsch Nybegynder
04. februar 2006 - 23:03 #17
Hvorfor ændrer du ikke blot din nodeklasse så den kan danne det binære træ?
Avatar billede bitsch Nybegynder
04. februar 2006 - 23:16 #18
Men for at vende tilbage til din egen kode så benytter du dig jo ikke af at din contNodes returnerer en værdi. Antallet er jo lig summen af nuværende niveau + underliggende niveau. Med andre ord så glemmer du jo at fange din returværdi fra countNodes. Nb jeg har ikke testet dit eksempel da du ikke har bidraget med din node klasse.
Avatar billede bitsch Nybegynder
04. februar 2006 - 23:24 #19
Det her er i øvrigt noget vås:

        for(int i=0; i<2; i++)
        {
            if(i==0)
            {
                countNodes(parent.getChild1(),count);
            }
            else
            {
                    countNodes(parent.getChild2(),count);
            }
        }

Resultatet bliver nemlig:

countNodes(parent.getChild1(),count);
countNodes(parent.getChild2(),count);

Og så er det jo let at se at din countNodes blot skal returnere summen af returværdierne fra de enkelte kald.

Men der er altså som sagt mulighed for at ændre designet til noget smukkere.
Avatar billede bitsch Nybegynder
05. februar 2006 - 00:20 #20
Her et lille hurtigt eksemple på hvordan du kan ændre din nodeklasse, samt hvordan du laver din "Count" rekursivt. Bemærk at dette kan naturligvis laves på utallige måder.

namespace Example
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            // Opret 7 noder.
            BinaryNode rootNode = new BinaryNode("0");

            BinaryNode binaryNode1 = new BinaryNode("1");
            BinaryNode binaryNode2 = new BinaryNode("2");

            rootNode.ChildTrue = binaryNode1;
            rootNode.ChildFalse = binaryNode2;

            binaryNode1.ChildTrue = new BinaryNode("3");
            binaryNode1.ChildFalse = new BinaryNode("4");

            binaryNode2.ChildTrue = new BinaryNode("5");
            binaryNode2.ChildFalse = new BinaryNode("6");


            MessageBox.Show(rootNode.Count.ToString());
        }

    }


    /// <summary>
    /// Kun et eksempel. Der er ikke taget højde for cyklisk reference!
    /// </summary>
    class BinaryNode
    {
        private BinaryNode parentNode = null;
        private BinaryNode childNodeTrue = null;
        private BinaryNode childNodeFalse = null;
        private string name = string.Empty;

        public BinaryNode Parent
        {
            get
            {
                return this.parentNode;
            }
            set
            {
                if (value != null)
                {
                    this.parentNode = value;
                }
            }
        }

        public BinaryNode ChildTrue
        {
            get
            {
                return this.childNodeTrue;
            }
            set
            {
                if (value != null)
                {
                    BinaryNode binaryNode = value;
                    binaryNode.Parent = this;
                    this.childNodeTrue = binaryNode;
                }
            }
        }

        public BinaryNode ChildFalse
        {
            get
            {
                return this.childNodeFalse;
            }
            set
            {
                if (value != null)
                {
                    BinaryNode binaryNode = value;
                    binaryNode.Parent = this;
                    this.childNodeFalse = binaryNode;
                }
            }
        }

        public string Name
        {
            get { return this.name; }
            set { this.name = value; }
        }

        public int Count
        {
            get
            {
                int value = 1; // Noden selv

                if (this.childNodeTrue != null) // Bidraget fra "True"
                {
                    value += this.childNodeTrue.Count;
                }
                if (this.childNodeFalse != null) // Bidraget fra "False"
                {
                    value += this.childNodeFalse.Count;
                }

                return value;
            }
        }

        public BinaryNode(string name)
        {
            this.name = name;
        }
    }
}
Avatar billede mysund Nybegynder
05. februar 2006 - 15:59 #21
Hej

Du bør nok ha en funktion der fortæller om en node har 1 eller 2 children parent.numberofchildren()
Så vidt jeg kan se har du ikke brug for at give andre værdier med til countNodes en noden der skal undersøges.

Hvis en node ikke har cildren, så returneres 1
er der 1, så tælles den op rekursivt, og 1 lægges til
er der 2, så tælles de rekursivt og lægges sammen med 1

Jeg har aldrig programmeret i C#, men så vidt jeg kan se er det noget i retning af:

private int countNodes(Node parent) {

switch (Parent.numberofchildren())
      {
      case 0:
      return 1;
      brake;
   
      case 1:
      return countNodes(parent.getChild1())+1;
      brake;

      case 2:
      return countNodes(parent.getChild1())+countNodes(parent.getChild2())+1;
      }
}

Mvh
Mysund
Avatar billede ahara Nybegynder
05. februar 2006 - 17:16 #22
Til bitsch:

Har lige før jeg gik på eksperten ændret min kode til nedenstående. Jeg havde selvfølgelig glemt at modtage returværdien i count     "count=countNodes(parent.getChild1(),count)".

Hvorfor skulle det være skidt at oprette mine data i et array. Er det bare fordi du mener c# har en funktion til at oprette et binært træ?

private int countNodes(Node parent, int count)
{
    count++;

    if(parent.haveChilds()==true)
    {
        count=countNodes(parent.getChild1(),count);
        count=countNodes(parent.getChild2(),count);
    }
return count;
}
Avatar billede ahara Nybegynder
05. februar 2006 - 17:17 #23
Et svar og der er forresten point
Avatar billede Syska Mester
05. februar 2006 - 17:37 #24
Binært må da være 0 og 1, og træ ala struktur.....

Hvor er det lige jeg er faldet af.......... og ikke forstår hvad det her skal bruges til.....

hvem skal svare?
Avatar billede Syska Mester
05. februar 2006 - 17:39 #25
Men synes nu stadig du skulle lave det hele på en andne måde....

// ouT
Avatar billede ahara Nybegynder
05. februar 2006 - 17:46 #26
Svar i bare alle og der er point
Avatar billede mysund Nybegynder
05. februar 2006 - 17:52 #27
Vil stadig mene at count er helt unødvændigt, det er netop idéen i at bruge rekursion.

(f.eks fakultets beregning fakultet(n) = n*(n-1)*(n-2)*...4*3*2*1

private int fakultet(tal int) {

if(tal==0) {
  return 1;
  } else {
  return fakultet(tal-1) * tal;
  }
}

"To iterate is human
To recurse is devine"
Avatar billede Syska Mester
05. februar 2006 - 17:57 #28
svar her.....

til mysund:
Ville nok også lave noget ala det TreeView har.....
Avatar billede Syska Mester
05. februar 2006 - 17:58 #29
LOL, så lige at der var 0 point til det her spm :-) Men man kan måske tilføje flere senere... eller?
Avatar billede dr_chaos Nybegynder
05. februar 2006 - 18:16 #30
ja det kan man :)
Avatar billede bitsch Nybegynder
05. februar 2006 - 18:26 #31
Det kunne jo egentligt være sjovt at vide hvad det skulle bruges til?
Avatar billede dr_chaos Nybegynder
05. februar 2006 - 18:28 #32
måske til en skole opgave på IT-ingeniør.
Vi har havde lignende opgaver bare i java.
Avatar billede bitsch Nybegynder
05. februar 2006 - 18:40 #33
Ja det er jo gratis at gætte ;-)
Du har nok ret, for hvad skulle man dog ellers med et binært træ?
Avatar billede ahara Nybegynder
05. februar 2006 - 18:48 #34
Tak for hjælpen
Avatar billede dr_chaos Nybegynder
05. februar 2006 - 18:51 #35
hoho
Avatar billede ahara Nybegynder
05. februar 2006 - 18:52 #36
P.S dette er ikke til en skole, men privat :o) Bare til orientering.
Avatar billede Syska Mester
05. februar 2006 - 19:12 #37
yes 0 point, mere til samlingen :-) *hehehe*

Er stadig ikke helt klar over hvad et binært træ er..........
Avatar billede ahara Nybegynder
05. februar 2006 - 19:15 #38
http://da.wikipedia.org/wiki/Bin%C3%A6rt_s%C3%B8getr%C3%A6

Jeg er ude af denne diskussion. Hej igen
Avatar billede arne_v Ekspert
05. februar 2006 - 19:17 #39
et binaert trae er et trae med 2 grene

det er den hurtigste datastruktur til soegning hvor data er sorteret

eksempel (som sikkert ser gyseligt ud p.g.a. fonten):

                  buzzz
      arne_v            dr_chaos
ahara      bitch                  mysund
Avatar billede bitsch Nybegynder
05. februar 2006 - 19:59 #40
Sjovt eksempel ;-) ja jeg ved skam godt hvad der er,men jeg har dog aldrig nogensinde i min lange tid i branchen haft brug for et.
Avatar billede arne_v Ekspert
05. februar 2006 - 20:13 #41
jeg har set det brugt nogle gange ...
Avatar billede Syska Mester
05. februar 2006 - 20:47 #42
ahhh, nu er jeg med..... men synes nu stadig tælle måden er wag ahara bruger er wag, men det er vel op til den enkelte, ved ikke hvad der er hurtigst.

// ouT
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester