construire un arbre n-aire

construire un arbre n-aire - Delphi/Pascal - Programmation

Marsh Posté le 13-10-2005 à 01:51:53    

Hello,  
 
J'ai fait ce code a fin de construire un arbre n-aire dont la racine "NULL" et les noued sont les produits(Riz,pain,....). mais toujour j'ai un problème au niveau du code entre // ============= // .  
 
Si le nœud tque N.item=debut existe déjà dans l’arbre on incrémente le count de ce noeud sinon Créer un nouveau nœud N N.count = 1 et Créer le lien de parenté entre le nœud N et Tree tel que Tree soit le père de N  
 
count : la fréquence de chaque item (exemple Riz est 4) par rapport aux T[i].
 
Merci de m'aider a résoudre ce problème sachant que j'ai fait plusieurs code mais toujours j'ai un message "violation d'accès à l'adresse 0045E7E dans le module..»  
 
le code :
 
unit Unit1;  
 
interface  
 
uses  
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,  
  Dialogs, StdCtrls;  
 //const taille=5;  
type  
     Noeud=  
        class  
           private  
              Fils    : array[1..5] of Noeud;  //liste de fils  
              item :string;  
              count : integer;  
              //lien : Noeud;  
               
           public  
              constructor create ;  
              destructor destroy ;  
        end; { Noeud }  
 
   
    Arbre =  
        class  
           private  
              tete,courant : noeud ;  
           public  
              constructor create ;  
              destructor destroy ;override ;  
              procedure insert_Tree(Chaine: string);  
              procedure buildTree();  
        end ;  
       
  TForm1 = class(TForm)  
    Button1: TButton;  
    Button2: TButton;  
    procedure FormCreate(Sender: TObject);  
    procedure Button1Click(Sender: TObject);  
    procedure FormDestroy(Sender: TObject);  
   private  
    { Déclarations privées }  
   public  
    { Déclarations publiques }  
  end;  
 
var  
  Form1: TForm1;  
  Tree1 : Arbre;  
 
implementation  
 
{$R *.dfm}  
 
constructor noeud.create ;  
var i : integer ;  
begin  
for i:=0 to 5 do  
    fils[i]:=nil ;  
item:='NULL' ;  
count :=0;  
//lien:='NULL';  
 
end ;  
 
destructor noeud.destroy ;  
var i : integer ;  
begin  
for i:=0 to 5 do  
if fils[i]<>nil then fils[i].destroy ;  
inherited destroy ;  
end ;  
 
constructor arbre.create ;  
 begin  
tete:=noeud.create ;  
courant:=tete ;  
end ;  
 
destructor arbre.destroy ;  
begin  
tete.destroy ;  
inherited destroy ;  
end ;  
 
procedure arbre.insert_Tree(Chaine: string);  
const Delimiteur=',';  
var Debut, Fin: string;  
    k: integer;  
begin  
    // Récupère Début et Fin  
    k:=Pos(Delimiteur,Chaine);  
    if k=0 then  
    begin  
          Debut:=Chaine; Fin:='';  
    end  
    else  
    begin  
          Debut:=Copy(Chaine, 1, k-1);  
          Fin:=Copy(Chaine, k+1, length(Chaine)-k);  
    end;  
     
   //============== Problème  a ce niveau =============  
     
 if courant.item=Debut then // Si le nœud tque N.item=debut existe déjà dans l’arbre on incrémente le count de ce noeud  
    begin               // Debut = élément a ajouter  
       inc(courant.count);  
       courant:=courant.Fils[??]  
    end  
    else    
    begin  
       courant.fils[??]:=noeud.create ; //nouveau noeud  
       courant:=courant.fils[??] ;  
       courant.item:=Debut ;  
       courant.count:=1;  
    end ;    
   
 
 
//============================================//  
 
         
   // ShowMessage(Debut);  
 
    // en s'arrete lorsque la liste est vide  
 
    if Fin='' then exit else insert_Tree(Fin);  
 
end;  
 
procedure arbre.buildTree();  
const NbElements= 5;  
var T: array[1..NbElements] of string;  
    i: integer;  
begin  
    T[1]:='Riz,Pain,Eau';  
    T[2]:='Riz,Pain';  
    T[3]:='Eau,sucre';  
    T[4]:='Riz,Pain,Sucre';  
    T[5]:='Riz,Pain,Eau,Sucre';  
    courant:=tete ;  
    for i:=1 to NbElements do insert_Tree(T[i]);  
end;  
 
procedure TForm1.FormCreate(Sender: TObject);  
begin  
Tree1:=arbre.create ;  
end;  
procedure TForm1.Button1Click(Sender: TObject);  
Begin  
Tree1.buildTree();  
end;  
 procedure TForm1.FormDestroy(Sender: TObject);  
begin  
Tree1.Destroy;  
end;  
 
end.
 
cordialement.
 
 
 

Reply

Marsh Posté le 13-10-2005 à 01:51:53   

Reply

Marsh Posté le 15-10-2005 à 19:08:01    

Salut,
 
Déja sans regarder en detail ton source, intéraisse toi de plus prêt au Constructeur et Destructeur de classe.
Le probleme ne vient peut etre pas de la mais:
 
1/ Il me semble que tous objet (class) est dérivé de TObject, donc dans tes cosntructeur si tu n'appelle pas le cosntructeur de l'ancetre ca peut peut etre pas trop le faire ( un truc du genre inherited Create.. dans le create de tes objets)
 
2/ N'appelle pas la methode destroy directement, utilise Free car elle vérifie si l'instance existe ou pas avant la destruction.
 
Ensuite je regarderais quand j'aurrais plsu de temps..
 
a++
 
bon courage
 
Heanium

Reply

Marsh Posté le 15-10-2005 à 23:15:40    

OK Merci beaucoup.

Reply

Marsh Posté le 15-10-2005 à 23:38:48    

1/ pour ceux qui dérivent de TObject directement, l'inherited n'est pas obligatoire il me semble
 
2/ elle vérifie si le pointeur est nil, pas si l'instance existe. L'instance peut ne plus exister même si le pointeur est non nil. Par ex deux Free de suite sur une même variable ça appellera deux fois le destructeur (et donc ça a des chances d'exploser)


---------------
mes programmes ·· les voitures dans les films ·· apprenez à écrire
Reply

Marsh Posté le 16-10-2005 à 11:11:06    

"1/ pour ceux qui dérivent de TObject directement, l'inherited n'est pas obligatoire il me semble"
Bon ca c'est une histoire de rigueur dans le code, tu va pas faire une exception pour TObject meme si c'est optionnel, comme ca tu gardes une certaine coherence dans ton source, perso je te conseille de le mettre, ca mange pas de paine et c'est plus sûr (j'en ai déja fait les frais)
 
"2/ elle vérifie si le pointeur est nil, pas si l'instance existe. L'instance peut ne plus exister même si le pointeur est non nil. Par ex deux Free de suite sur une même variable ça appellera deux fois le destructeur (et donc ça a des chances d'exploser)"
Bien sur que nil.free ca le fait pas ca va de soie mais c'est pas le probleme ici...
De toute facon on n'utilise quazi jamais le Destroy directement dans ton Destroy appelle des Free (sauf le inherited ca va de soie).
http://www.hexanium.com/hexanium/images/delphi_free.jpg  
C'est aussi une histoire de rigueure...
 
A++

Reply

Marsh Posté le 16-10-2005 à 13:35:37    

hexanium a écrit :

"1/ pour ceux qui dérivent de TObject directement, l'inherited n'est pas obligatoire il me semble"
Bon ca c'est une histoire de rigueur dans le code, tu va pas faire une exception pour TObject meme si c'est optionnel, comme ca tu gardes une certaine coherence dans ton source, perso je te conseille de le mettre, ca mange pas de paine et c'est plus sûr (j'en ai déja fait les frais)


 
Oui c'est clair, je voulais juste dire que ça n'était pas la source du problème ;) Mais si on l'oublie dans un Form ou autre objet complexe... boum :D
 

hexanium a écrit :


"2/ elle vérifie si le pointeur est nil, pas si l'instance existe. L'instance peut ne plus exister même si le pointeur est non nil. Par ex deux Free de suite sur une même variable ça appellera deux fois le destructeur (et donc ça a des chances d'exploser)"
Bien sur que nil.free ca le fait pas ca va de soie mais c'est pas le probleme ici...
De toute facon on n'utilise quazi jamais le Destroy directement dans ton Destroy appelle des Free (sauf le inherited ca va de soie).
http://www.hexanium.com/hexanium/i [...] i_free.jpg  
C'est aussi une histoire de rigueure...


 
D'accord aussi, jamais d'appel à destroy directement, c'était pour préciser l'histoire d'instance qui existe ;)
Dans Delphi 7 il vaut même mieux utiliser FreeAndNil(obj) au lieu de obj.Free s'il y a un risque de manipuler le pointeur plus tard : au moins on est sûr qu'il est à nil lorsqu'il est détruit.
 


---------------
mes programmes ·· les voitures dans les films ·· apprenez à écrire
Reply

Marsh Posté le 16-10-2005 à 13:58:11    

antp a écrit :

Dans Delphi 7 il vaut même mieux utiliser FreeAndNil(obj) au lieu de obj.Free s'il y a un risque de manipuler le pointeur plus tard : au moins on est sûr qu'il est à nil lorsqu'il est détruit.

merci pour le tips
 :jap:


---------------
Nos estans firs di nosse pitite patreye...
Reply

Marsh Posté le 17-10-2005 à 01:10:57    

Salut,
 
Bien le FreeAndNil(), connaissais pas, merci Antp
 
Mamodel, peux tu détailler un peu plus ton n-aire je vois pas bien ce que tu veux en faire perso...
 
A++

Reply

Marsh Posté le 17-10-2005 à 12:56:38    

en faite je veux construire un arbre n-aire dont les noeuds sont les item et chaque Chemin représente une transaction T[i] alors la j'avais le problème comment relier un noued donner avec ces fils mais bon j'ai essayer un truc qui ressemble a ce que je veux (http://recursivite.developpez.com/?page=page_8#LVII-D ) et ca marche trés bien mais la  je dois afficher les chemins contenat un item donné je ne sais si vous avez un algorithm qui fait ca .
 
Merci

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed