[C] Funzione albero di ricerca binaria

cicchi27
Salve ho cominciato a trattare gli alberi binari di ricerca come ADT ed in particolare, partendo da il codice dal solo codice di inserimento, più quelli relativi alla stampa degli elementi nei vari ordini, provando ad aggiungere qualche funzione in più(senza ancora aver visto la cancellazione degli elementi). La funzione della ricerca del solo elemento minore(o maggiore) funziona tranquillamente, il problema è con la funzione di ricerca generica, perché se provo a cercare un elemento che è contenuto nell'albero, la funzione me lo fa sapere, altrimenti il programma si chiude. Vorrei capire anche il come si verificano questi errori che il compilatore non rileva, soprattutto perché ancora non sono riuscito ad entrare bene dentro la materia e faccio ancora le cose ancora "meccanicamente". Scusate per la digressione e grazie in anticipo :) .
FUNZIONI:
#include "item.h"



void prinTree();


void treeInit();
int isEmpty();
void treeInsertNode(Item);
int minTree();
  void search(Item item);

#include <stdio.h>
#include <stdlib.h>
#include "item.h"
#include "tree.h"

struct treeNode{
   struct treeNode *leftPtr;
   Item item;
   struct treeNode *rightPtr;
   
};
typedef struct treeNode TreeNode;
typedef TreeNode *TreeNodePtr;

 static TreeNodePtr rootPtr;
static TreeNodePtr min(TreeNodePtr rootPtr);
void inOrder(TreeNodePtr rootPtr, int level);
static void insertNode(TreeNodePtr *treePtr, Item item);
static TreeNodePtr searchTree(TreeNodePtr *treePtr, Item item);
   
void treeInit(){
   rootPtr = NULL;
}


int isEmpty(){
   return rootPtr == NULL;
}


 void treeInsertNode(Item item){
    insertNode(&rootPtr, item);
 }
   
 static void insertNode(TreeNodePtr *treePtr, Item item){
    //se l'albero è vuoto
   
    if(*treePtr == NULL){
       *treePtr = malloc(sizeof(TreeNode));
      
       //se la memoria è stata allocata, allora memorizza il valore
       if(*treePtr != NULL){
          (*treePtr)->item = item;
          (*treePtr)->leftPtr = NULL;
          (*treePtr)->rightPtr = NULL;
       }
       else{
          printf("%d non inserito, memoria non disponibile.\n");
       }
      
    }
    else{ //l'albero non è vuoto
       if(item < (*treePtr)->item){
          insertNode(&((*treePtr)->leftPtr), item);
       }
      else if(item > (*treePtr)->item){
          insertNode(&((*treePtr)->rightPtr), item);
      }
      else{
         printf("%s", "dup");
      }
    }
      
 }
 
 void prinTree(){
	  inOrder(rootPtr, 0);
 }
 
 void  inOrder(TreeNodePtr treePtr, int level){
    if(treePtr != NULL)
    {
      
       inOrder(treePtr->rightPtr, level + 1);
       printf("%*s%5d\n", 5*level, "", treePtr->item);
       inOrder(treePtr->leftPtr, level + 1);
    }
 }
 
 
 
    int minTree(){
		min(rootPtr);
		return min(rootPtr)->item;
	}   
   
   TreeNodePtr min(TreeNodePtr rootPtr){
    if( rootPtr->leftPtr == NULL) return rootPtr;
    else return min(rootPtr->leftPtr);
 }
 
 
 void search(Item item){
	 searchTree(&rootPtr, item);
 }
 
 TreeNodePtr searchTree(TreeNodePtr *treePtr, Item item){
    if(item < (*treePtr)->item){
          searchTree(&((*treePtr)->leftPtr), item);
       }
      else if(item > (*treePtr)->item){
          searchTree(&((*treePtr)->rightPtr), item);
      }
      else{
         if( item == (*treePtr)->item){
            printf("%d e' nell'albero.", item);
         }else
            printf("%d non e' nell'albero.",item);         
     }
      
 }

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include "item.h"
#include "tree.h"



int main()
{   
     treeInit();
   
   srand(time(NULL));
   for(unsigned int i = 1; i <= 9; ++i){
      Item item = rand () % 300;
      printf("%7d", item);
      treeInsertNode(item);
    }
  puts("\n\nAlbero con diramazione  orizzontale:\n");
  prinTree();
  
   printf("\n\nIl piu' piccolo numero dell'albero e' %d", minTree());
   printf("\n\nquale numero vuoi cercare?:\n");
   Item key;
   scanf("%d", &key);
   search(key);
 }

Risposte
cicchi27
Altro problema con la funzione che calcola la distanza fra due elementi: funziona normalmente quando due numeri sono rispettivamente uno maggiore e l'altro minore della radice, ma quando sono entrambi minori(o maggiori) della radice, comunque viene effettuata la somma , che ovviamente non ha senso perché dovrebbe in teoria fare la differenza tra le distanze tra un numero e e la radice considerando il maggiore. Non saprei se è una cosa dovuta al come agiscono gli operatori logici oppure c'è altro che mi sfugge...

#include <stdio.h>
#include <stdlib.h>
#include "item.h"
#include "tree.h"

struct treeNode{
   struct treeNode *leftPtr;
   Item item;
   struct treeNode *rightPtr;
   
};
typedef struct treeNode TreeNode;
typedef TreeNode *TreeNodePtr;

 static TreeNodePtr rootPtr;
static TreeNodePtr min(TreeNodePtr rootPtr);
void inOrder(TreeNodePtr rootPtr, int level);
static void insertNode(TreeNodePtr *treePtr, Item item);
 int searchTree(TreeNodePtr *treePtr, Item item, int level);
static int distanceTree( Item a, Item b, TreeNodePtr rootPtr);
   
void treeInit(){
   rootPtr = NULL;
}


int isEmpty(){
   return rootPtr == NULL;
}


 void treeInsertNode(Item item){
    insertNode(&rootPtr, item);
 }
   
 static void insertNode(TreeNodePtr *treePtr, Item item){
    //se l'albero è vuoto
   
    if(*treePtr == NULL){
       *treePtr = malloc(sizeof(TreeNode));
      
       //se la memoria è stata allocata, allora memorizza il valore
       if(*treePtr != NULL){
          (*treePtr)->item = item;
          (*treePtr)->leftPtr = NULL;
          (*treePtr)->rightPtr = NULL;
       }
       else{
          printf("%d non inserito, memoria non disponibile.\n");
       }
      
    }
    else{ //l'albero non è vuoto
       if(item < (*treePtr)->item){
          insertNode(&((*treePtr)->leftPtr), item);
       }
      else if(item > (*treePtr)->item){
          insertNode(&((*treePtr)->rightPtr), item);
      }
      else{
         printf("%s", "dup");
      }
    }
      
 }
 
 void prinTree(){
	  inOrder(rootPtr, 0);
 }
 
 void  inOrder(TreeNodePtr treePtr, int level){
    if(treePtr != NULL)
    {
      
       inOrder(treePtr->rightPtr, level + 1);
       printf("%*s%5d\n", 5*level, "", treePtr->item);
       inOrder(treePtr->leftPtr, level + 1);
    }
 }
 
 
 
    int minTree(){
		min(rootPtr);
		return min(rootPtr)->item;
	}   
   
   TreeNodePtr min(TreeNodePtr rootPtr){
    if( rootPtr->leftPtr == NULL) return rootPtr;
    else return min(rootPtr->leftPtr);
 }
 
 
 int search(Item item){
	 searchTree(&rootPtr, item, 0);
 }
 
 int searchTree(TreeNodePtr *treePtr, Item item, int level){
	 
	 
	 
    if(item < (*treePtr)->item){
          searchTree(&((*treePtr)->leftPtr), item, level + 1);
       }
      else if(item > (*treePtr)->item){
          searchTree(&((*treePtr)->rightPtr), item, level + 1);
      }
      else
         if( item == (*treePtr)->item){
            printf("\n%d e' nell'albero.", item);
			return level;
         }
     }
	  
	  int distance(Item a, Item b){
		  return distanceTree(a, b, rootPtr);
	  }
 static int distanceTree( Item a, Item b, TreeNodePtr rootPtr){
	 if ( a == b) return 0;
 if( ( a < rootPtr-> item) || ( b < rootPtr-> item))
	 return ( search(a) + search(b) );
 
 if( ((a < rootPtr->item)&&( b < rootPtr->item)) && ( b > a)) 
	  return ( search(a) - search(b) );
 else return ( search(b) - search(a) );
 
 if( ((a > rootPtr->item)&&( b > rootPtr->item)) && ( b > a)) 
	  return ( search(b) - search(a) );
 else return ( search(a) - search(b) );
 
 
	 }

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include "item.h"
#include "tree.h"



int main()
{   
     treeInit();
   
   srand(time(NULL));
   for(unsigned int i = 1; i <= 25; ++i){
      Item item = rand () % 300;
      printf("%7d", item);
      treeInsertNode(item);
    }
  puts("\n\nAlbero con diramazione  orizzontale:\n");
  prinTree();
  
   printf("\n\nIl piu' piccolo numero dell'albero e' %d", minTree());
   printf("\n\nquale numero vuoi cercare?:\n");
   Item key;
   scanf("%d", &key);
   printf("\n %d dista %d", key, search(key));
   
   printf("\n\ninserisci due numeri:");
   Item a, b;
   scanf("%d%d", &a, &b);
   printf("\n\nla distanza fra %d e %d e' %d", a, b, distance(a, b));
   
   
   
 }

Rispondi
Per rispondere a questa discussione devi prima effettuare il login.