Advertisement
Guest User

P1 23-5-18

a guest
Dec 9th, 2019
110
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.88 KB | None | 0 0
  1. //23-5-2018
  2. #include<iostream>
  3. using namespace std;
  4.  
  5. struct nodo{int info; nodo* left,*right; nodo(int a=0, nodo* b=0, nodo*c=0){info=a; left=b;right=c;}};
  6. //PRE= (albero(r) è ben formato, k>0, 1<=n<=k)
  7.  
  8. int contaNodi(nodo* r){
  9.  
  10. if(!r){
  11. return 0;
  12. }
  13.  
  14. return 1 + contaNodi(r->left)+contaNodi(r->right);
  15. }
  16.  
  17.  
  18. //PRE=(albero(r) è corretto e bilanciato nel senso spiegato nell’Esempio 1, valbero(r)=albero(r))
  19. nodo* alberobil (nodo*r, int k){
  20.  
  21. if(!r){
  22. r = new nodo(k,0);
  23. //cout << r->info<<endl;
  24. return r;
  25. }
  26.  
  27. if(contaNodi(r->left) <= contaNodi(r->right)){
  28. r->left = alberobil(r->left, k);
  29. return r;
  30. }else{
  31. r->right = alberobil(r->right, k);
  32. return r;
  33. }
  34.  
  35. cout << r->info<<endl;
  36. return r;
  37. }
  38. //POST=(albero(r) è corretto e ancora bilanciato ed è ottenuto da valbero(r) aggiungendogli una nuova foglia con info=k)
  39.  
  40.  
  41.  
  42. //PRE=(albero(r) è corretto e bilanciato, n>=0, valbero(r)=albero(r))
  43. nodo* buildtree(nodo* r, int n){
  44. int num;
  45.  
  46. if(n>0){
  47. cin >> num;
  48. r = alberobil(r, num);
  49. return buildtree(r, n-1);
  50. }else{
  51. return r;
  52. }
  53. }
  54. //POST=(restituisce valbero(r) con n nodi aggiuntivi inseriti in modo da conservare il bilanciamento)
  55.  
  56. void stampa(nodo* r){
  57. if(r){
  58. cout << r->info;
  59. cout << "(";
  60. stampa(r->left);
  61. cout<<",";
  62. stampa(r->right);
  63. cout <<")";
  64. }else{
  65. cout<<"_";
  66. }
  67. }
  68.  
  69. //PRE= (albero(r) è ben formato, k>0, 1<=n<=k)
  70. int stampa_a_salti(nodo* r, int k, int n){
  71.  
  72. if(!r){ //caso base (1) r è un albero vuoto/nullptr
  73. return k;
  74. }
  75.  
  76. if(n==1){
  77. cout << r->info << " ";
  78. n=k;
  79. }else{
  80. n=n-1;
  81. }
  82.  
  83.  
  84.  
  85. if(!r->left && !r->right){ //caso base (2)
  86. return n;
  87. }
  88.  
  89.  
  90. if(r->left){
  91. n = stampa_a_salti(r->left, k, n); //ric #1
  92.  
  93. }
  94.  
  95. if(r->right){
  96. n = stampa_a_salti(r->right, k, n); //ric #2
  97.  
  98. }
  99.  
  100.  
  101. return n;
  102. }
  103. //POST=(stampa i campi info dei nodi di albero(r) in ordine prefisso nel modo seguente:
  104. //salta i primi n-1, stampa il nodo n-esimo, poi ne salta k-1 stampa quello successivo
  105. //e così via fino a visitare tutti i nodi) && (restituisce un intero m (1<=m<=k) che
  106. //indica che si dovranno saltare m-1 nodi prima di stampare il prossimo)
  107.  
  108. /*
  109. CORRETTEZZA:
  110.  
  111. (
  112. caso base (1) => POST
  113. se r è vuoto non stampa nulla, restituisce k che è l'intero che rappresenta
  114. il numero di salti-1 prima di stampare il prossimo (che ricordo in questo caso non esiste) => POST
  115.  
  116. caso base (2) => POST
  117. se il campo left e right di r puntano a 0/nullptr (ovvero sono in una foglia) restituisco
  118. n che esattamente il numero-1 di nodi da saltare prima di stampare il prossimo nodo
  119. )
  120. &&
  121. (
  122. if(n==1==true) essendo arrivato al k-1esimo nodo, stampo il campo info del nodo r
  123. imposto il valore di n come k, in quanto nella prossima ricorsione dovrò ripartire da k
  124.  
  125. else(n!=1==true)decremento n di 1 in quanto nella prossima ricorsione dovrò controllare se n-1 nodo sia il k-1esimo
  126.  
  127.  
  128. if(r->left == true) il sottoalbero sinistro di r esiste, quindi lo visito
  129. dimostro la PRE_RIC di #1
  130. A- r è ben formato, non essendo stato in alcun modo modificato => anche r->left è ben formato
  131. B- k>0, non essendo mai stato modificato il valore di k => k_ric>0
  132. C- 1<=n<=k, essendo n al minimo 1 e al massimo k (vedi codice) => 1<=n_ric<=k
  133. A,B,C rispettano la PRE_ric e quindi assumo la POST_ric sia valida
  134.  
  135. if(r->right == true) il sottoalbero sinistro di r esiste, quindi lo visito
  136. dimostro la PRE_RIC di #1
  137. A- r è ben formato, non essendo stato in alcun modo modificato => anche r->right è ben formato
  138. B- k>0, non essendo mai stato modificato il valore di k => k_ric>0
  139. C- 1<=n<=k, essendo n al minimo 1 e al massimo k (vedi codice) => 1<=n_ric<=k
  140. A,B,C rispettano la PRE_ric e quindi assumo la POST_ric sia valida
  141.  
  142. )
  143. => POST
  144.  
  145. restituisce il valore n che indica il numero di m-1 passi che mancano alla prossima stampa, saltando i primi n-1 nodi e ha stampato
  146. ogni k-1 nodi il campo info del nodo stesso
  147. */
  148.  
  149. main()
  150. {
  151. int dim,k;
  152. cin>>dim;
  153. nodo* R=0;
  154. R=buildtree(R,dim);
  155. cout<<"start"<<endl;
  156. stampa(R);cout<<endl;
  157. cin>>k;
  158. int b=stampa_a_salti(R,k,k);
  159. cout<<endl<<"valore restituito="<<b<<endl;
  160. cout<<"end"<<endl;
  161. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement