Matematické Fórum

Nevíte-li si rady s jakýmkoliv matematickým problémem, toto místo je pro vás jako dělané.

Nástěnka
22. 8. 2021 (L) Přecházíme zpět na doménu forum.matweb.cz!
04.11.2016 (Jel.) Čtete, prosím, před vložení dotazu, děkuji!
23.10.2013 (Jel.) Zkuste před zadáním dotazu použít některý z online-nástrojů, konzultovat použití můžete v sekci CAS.

Nejste přihlášen(a). Přihlásit

#1 18. 10. 2009 09:52 — Editoval gladiator01 (18. 10. 2009 09:56)

gladiator01
Místo: Jindřichův Hradec
Příspěvky: 1587
Škola: ZČU FAV - SWI
Pozice: absolvent
Reputace:   53 
Web
 

výpis stromu, součet hodnot - c++

Ahoj,
    mohl by někdo říci co mám špatně (resp. proč to tak je) ve funkcích int soucetNerek(Node *p) a void print2Nerek(Node *p).
   
   Zde je co to dělá (výpis a součet prvků rekurzivně je správně):
   http://forum.matweb.cz/upload/1255851886-strom.jpg
   
   a zde je kod:
   

Code:

#include <iostream>
#include <iomanip>
#include <cstdlib>

#include"stack.h"

using namespace std;

struct Node 
{
  int info;
  Node *left, *right;
  Node(int x, Node* l, Node* r) 
  {
    info = x; left = l; right = r;
  }
};

inline int random(int m) 
{
// vysledkem je pseudonahodne cislo z intervalu 0 az m-1
  return rand()%m;
}

Node *randTree(int depth) 
{
  if(depth<=0 || random(10)>7) return NULL;
  return new Node(random(100),randTree(depth-1), randTree(depth-1));
}
//------------------------------------------------------------------------------

// vypíše ve tvaru stromu (hodnoty pod sebe)
void print(Node *p, int s) 
{
  cout << setw(s) << ' ';
  if(p) 
  {
    cout <<  p->info << endl;
    print(p->left, s+1);
    print(p->right, s+1);
  }
  else
    cout << "x" << endl;
}

//vypíše ve tvaru: hodnota uzlu(levý podstrom, pravý podstrom) - rekurzivně
void print2(Node *p) 
{
  if(p) 
  {
    cout <<  p->info << " (" ;
    print2(p->left); 
    cout << ",";
    print2(p->right);
    
    cout << ")";
  }
  else
    cout << "x";
}

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//vypíše ve tvaru: hodnota uzlu(levý podstrom, pravý podstrom) - nerekurzivně (s použitím zásobníku)
struct Pair 
{
  Node *ptr;
  int spc;
  Pair(Node *p) 
  {
    ptr = p;
  }
};
void print2Nerek(Node *p) 
{
  Stack<Pair> stc;
  stc.push(Pair(p));
  while(!stc.empty()) 
  {
    Pair pair = stc.pop();
    if(!pair.ptr)
       cout << "x" ;
    else if(pair.ptr) 
    {     
      cout << pair.ptr->info;
      cout << " (";
      stc.push(Pair(pair.ptr->right));
      cout << ",";
      stc.push(Pair(pair.ptr->left));
      cout << ")";
    }
  }
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------

//sečte hodnoty všech uzlů - rekurivně
int soucet(Node *p) 
{
  if(p)
    return p->info+soucet(p->left)+ soucet(p->right);
  else
    return 0;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//sečte hodnoty všech uzlů s použitím zásobníku - nerekurzivně (s použitím zásobníku)
int soucetNerek(Node *p) 
{
  Stack<Node*> stc;
  int soucet = 0;
  stc.push(p);
  while(!stc.empty()) 
  {
    Node *q = stc.pop();
    if(q) 
    {
      soucet+=q->info;
      stc.push(q->right);
      stc.push(q->left);
      soucet++;
    }
  } 
  return soucet;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------

int main() 
{
  Node *root = randTree(4);
  cout << "vypis (rekurzivne)" << endl;
  print2(root);
  
  cout << endl << endl;
  
  cout << "vypis (nerekurzivne)" << endl;
  print2Nerek(root);
  
  cout << endl << endl;
  //print(root, 1);
  cout << "soucet uzlu stromu (rekurzivne):   " << soucet(root) << endl;
  cout << "soucet uzlu stromu (nerekurzivne): " << soucetNerek(root) << endl << endl;
  
  system("PAUSE");
  return 0;
}

Děkuji


Naděje jako svíce jas, potěší srdce štvané, čím temnější je noční čas, tím zářivěji plane.
VIVERE - MILITARE EST (Seneca)
Vím, že nic nevím. - Sokrates

Offline

 

#2 18. 10. 2009 21:40

Kondr
Veterán
Místo: Linz, Österreich
Příspěvky: 4246
Škola: FI MU 2013
Pozice: Vývojář, JKU
Reputace:   38 
 

Re: výpis stromu, součet hodnot - c++

Tak ta chyba u součtu je dost triviální: stačí umazat soucet++
Chyba u výpisu je horší, tam je špatně celá logika věci (vypisuješ "(,)" hned, když narazíš na ten uzel; je potřeba vypsat pouze "(" a uzel si držet v zásobníku, zpracovat jeho levý podstrom, vypsat ",", zpracovat pravý podstrom, vypsat ")" a pak teprve odstranit ze zásobníku.

Zkuším si to naprogramovat, pak třeba dodám kód.


BRKOS - matematický korespondenční seminář pro střední školy

Offline

 

#3 18. 10. 2009 22:27

gladiator01
Místo: Jindřichův Hradec
Příspěvky: 1587
Škola: ZČU FAV - SWI
Pozice: absolvent
Reputace:   53 
Web
 

Re: výpis stromu, součet hodnot - c++

Jo, děkuju.


Naděje jako svíce jas, potěší srdce štvané, čím temnější je noční čas, tím zářivěji plane.
VIVERE - MILITARE EST (Seneca)
Vím, že nic nevím. - Sokrates

Offline

 

#4 19. 10. 2009 14:39

Kondr
Veterán
Místo: Linz, Österreich
Příspěvky: 4246
Škola: FI MU 2013
Pozice: Vývojář, JKU
Reputace:   38 
 

Re: výpis stromu, součet hodnot - c++

Tak jsem si našel čas to doprgat:

Code:

struct Pair 
{
  Node *ptr;
  char spc;
  Pair(Node *p,char s) 
  {
    ptr = p;
    spc = s;
  }
};
void print2Nerek(Node *p) 
{
  stack<Pair> stc;
  stc.push(Pair(p,'l'));
  while(!stc.empty()) 
  {
    Pair pair = stc.top();
    if(!pair.ptr)
    {
       cout << "x" ;
       while(pair.spc=='r')
       {
           stc.pop();
           pair=stc.top();
           cout<<")";
       }
       stc.pop();
       if(!stc.empty())cout<<",";
    }
    else 
    {     
      cout << pair.ptr->info;
      cout << " (";
      stc.push(Pair(pair.ptr->right,'r'));
      stc.push(Pair(pair.ptr->left,'l'));
    }
  }
}

Použil jsem místo tvé vlastní stack.h již hotovou třídu stack dostupnou po #include<stack>, proto tam, kde já mám top (vrátí horní prvek bez odebrání) ty budeš mít nejdřív pop a pak push. Pokud ale nebyla součást zadání napsat si vlastní stack, doporučuju používat ten už hotový.
Kód se lépe čte, když pop dělá po každé to samé ;)


BRKOS - matematický korespondenční seminář pro střední školy

Offline

 

#5 19. 10. 2009 16:29

gladiator01
Místo: Jindřichův Hradec
Příspěvky: 1587
Škola: ZČU FAV - SWI
Pozice: absolvent
Reputace:   53 
Web
 

Re: výpis stromu, součet hodnot - c++

Děkuji.


Naděje jako svíce jas, potěší srdce štvané, čím temnější je noční čas, tím zářivěji plane.
VIVERE - MILITARE EST (Seneca)
Vím, že nic nevím. - Sokrates

Offline

 

Zápatí

Powered by PunBB
© Copyright 2002–2005 Rickard Andersson