Skip to content
Snippets Groups Projects
Commit 6ecbf7fc authored by paul.albuquer's avatar paul.albuquer
Browse files

added source code for binary and AVL trees

parent a3b25274
No related branches found
No related tags found
No related merge requests found
with Ada.Text_IO; use Ada.Text_IO;
procedure avl is
-- paquetage pour l'criture en x-me ligne et y-me colonne
package Entier_ES is new Integer_IO(Integer);
use Entier_ES;
Niv_Max : constant := 6;
subtype T_Donnee is Integer;
type T_Noeud;
type T_Arbre is access T_Noeud;
type T_Noeud is record
Cle : T_Donnee;
Gauche,Droite : T_Arbre;
Hg,Hd : Natural := 0;
end record;
Cle_Presente : exception;
------------------------------------------------------------
-- fonction qui donne le nombre max entre 2 nombres --
------------------------------------------------------------
function Max(H1,H2 : Integer) return Integer is
begin
if H1 > H2 then
return H1;
else
return H2;
end if;
end Max;
------------------------------------------------------------
-- fonction qui retourne le premier noeud dsquilibr et --
-- met jour les hauteurs sur le chemin d'insertion --
------------------------------------------------------------
function Desequilibre(Arbre : in T_Arbre;
Donnee : in T_Donnee) return T_Arbre is
Temp : T_Arbre := Arbre;
Parent : T_Arbre;
Hd_Prec,Hg_Prec : Integer := 0;
begin
while Temp.Cle /= Donnee loop
if abs(Temp.Hd - Temp.Hg) = 2 then
Parent := Temp;
Hd_Prec := Parent.Hd;
Hg_Prec := Parent.Hg;
if Donnee <= Parent.Cle then
Parent.Hg := Parent.Hg - 1;
else
Parent.Hd := Parent.Hd - 1;
end if;
end if;
if Donnee <= Temp.Cle then
Temp := Temp.Gauche;
else
Temp := Temp.Droite;
end if;
end loop;
if Parent /= null then
Parent.Hd := Hd_Prec;
Parent.Hg := Hg_Prec;
end if;
return Parent;
end Desequilibre;
procedure Imprimer(Arbre : in T_Arbre; N : in Positive) is
begin
if Arbre /= null then
Imprimer(Arbre.Droite,N+1);
for I in 1..N loop
Put(" ");
end loop;
Put(Arbre.Cle);
Put("(" & Integer'Image(Arbre.Hg) & "," & Integer'Image(Arbre.hd) & ")");
New_Line;
Imprimer(Arbre.Gauche,N+1);
end if;
end Imprimer;
------------------------------------------------------------
-- fonction qui calcule les hauteurs d'un arbre --
------------------------------------------------------------
function Hauteur(Noeud : in T_Arbre) return Natural is
begin
if Noeud = null then
return 0;
else
return 1+Max(Hauteur(Noeud.Gauche),Hauteur(Noeud.Droite));
end if;
end Hauteur;
------------------------------------------------------------
-- procedure qui remet jour les hauteurs des noeuds --
-- aprs le rquilibrage --
------------------------------------------------------------
procedure Hauteurs(Noeud : in T_Arbre) is
begin
if Noeud.Gauche /= null then
Hauteurs(Noeud.Gauche);
Noeud.Hg := 1+Max(Noeud.Gauche.Hg,Noeud.Gauche.Hd);
else
Noeud.Hg := 0;
end if;
if Noeud.Droite /= null then
Hauteurs(Noeud.Droite);
Noeud.Hd := 1+Max(Noeud.Droite.Hg,Noeud.Droite.Hd);
else
Noeud.Hd := 0;
end if;
end Hauteurs;
------------------------------------------------------------
-- procedure qui remet jour les hauteurs des noeuds --
-- aprs le rquilibrage --
------------------------------------------------------------
procedure Hauteur_Noeud(Noeud : in T_Arbre) is
begin
if Noeud.Gauche /= null then
Noeud.Hg := 1+Max(Noeud.Gauche.Hg,Noeud.Gauche.Hd);
else
Noeud.Hg := 0;
end if;
if Noeud.Droite /= null then
Noeud.Hd := 1+Max(Noeud.Droite.Hg,Noeud.Droite.Hd);
else
Noeud.Hd := 0;
end if;
end Hauteur_Noeud;
------------------------------------------------------------
-- fonction qui effectue une rotation gauche sur le --
-- noeud dsquilibr --
------------------------------------------------------------
function Rot_G(P : T_Arbre) return T_Arbre is
Q : T_Arbre := null;
begin
if P /= null then
Q := P.Droite;
P.Droite := Q.Gauche;
Q.Gauche := P;
Hauteur_Noeud(P);
Hauteur_Noeud(Q);
end if;
return Q;
end Rot_G;
------------------------------------------------------------
-- fonction qui effectue une rotation droite sur le --
-- noeud dsquilibr --
------------------------------------------------------------
function Rot_D(P : T_Arbre) return T_Arbre is
Q : T_Arbre := null;
begin
if P /= null then
Q := P.Gauche;
P.Gauche := Q.Droite;
Q.Droite := P;
Hauteur_Noeud(P);
Hauteur_Noeud(Q);
end if;
return Q;
end Rot_D;
------------------------------------------------------------
-- procedure qui effectue une double rotation gauche --
-- droite sur le noeud dsquilibr --
------------------------------------------------------------
function Rot_GD(Noeud : T_Arbre) return T_Arbre is
begin
Noeud.Gauche := Rot_G(Noeud.Gauche);
return Rot_D(Noeud);
end Rot_GD;
------------------------------------------------------------
-- procedure qui effectue une rotation gauche sur le --
-- noeud dsquilibr --
------------------------------------------------------------
procedure Rotation_G(Noeud : in T_Arbre) is
New_Noeud : T_Arbre;
begin
New_Noeud := new T_Noeud'(Noeud.Cle,
Noeud.Gauche,
Noeud.Droite.Gauche,
0,0);
Noeud.Cle := Noeud.Droite.Cle;
Noeud.Gauche := New_Noeud;
Noeud.Droite := Noeud.Droite.Droite;
Hauteur_Noeud(New_Noeud);
Hauteur_Noeud(Noeud);
end Rotation_G;
------------------------------------------------------------
-- procedure qui effectue une double rotation droite --
-- gauche sur le noeud dsquilibr --
------------------------------------------------------------
procedure Rot_DG(Noeud : in T_Arbre) is
begin
Noeud.Droite := Rot_D(Noeud.Droite);
return Rot_G(Noeud);
end Rot_DG;
------------------------------------------------------------
-- procedure qui effectue une rotation droite sur le --
-- noeud dsquilibr --
------------------------------------------------------------
procedure Rotation_D(Noeud : in T_Arbre) is
New_Noeud : T_Arbre;
begin
New_Noeud := new T_Noeud'(Noeud.Cle,
Noeud.Gauche.Droite,
Noeud.Droite,
0,0);
Noeud.Cle := Noeud.Gauche.Cle;
Noeud.Droite := New_Noeud;
Noeud.Gauche := Noeud.Gauche.Gauche;
Hauteur_Noeud(New_Noeud);
Hauteur_Noeud(Noeud);
end Rotation_D;
------------------------------------------------------------
-- procedure qui effectue une double rotation gauche --
-- droite sur le noeud dsquilibr --
------------------------------------------------------------
procedure Rotation_GD(Noeud : in T_Arbre) is
begin
Rotation_G(Noeud.Gauche);
Rotation_D(Noeud);
end Rotation_GD;
------------------------------------------------------------
-- procedure qui effectue une double rotation droite --
-- gauche sur le noeud dsquilibr --
------------------------------------------------------------
procedure Rotation_DG(Noeud : in T_Arbre) is
begin
Rotation_D(Noeud.Droite);
Rotation_G(Noeud);
end Rotation_DG;
------------------------------------------------------------
-- procedure qui rquilibre l'arbre --
------------------------------------------------------------
procedure Reequilibre(Noeud : in T_Arbre) is
begin
case (Noeud.Hd - Noeud.Hg) is
when +2 =>
case (Noeud.Droite.Hd - Noeud.Droite.Hg) is
when +1 => Rotation_G(Noeud);
when others => Rotation_DG(Noeud);
end case;
when others =>
case (Noeud.Gauche.Hd - Noeud.Gauche.Hg) is
when -1 => Rotation_D(Noeud);
when others => Rotation_GD(Noeud);
end case;
end case;
end Reequilibre;
------------------------------------------------------------
-- procedure qui insre une valeur dans l'arbre --
------------------------------------------------------------
procedure Insertion(Donnee : in T_Donnee;
Arbre : in out T_Arbre;
Deseq : in out T_Arbre) is
begin
if Arbre = null then
Arbre := new T_Noeud'(Donnee,null,null,0,0);
Deseq := null;
else
if Donnee = Arbre.Cle then
raise Cle_Presente;
elsif Donnee < Arbre.Cle then
Insertion(Donnee, Arbre.Gauche,Deseq);
if Deseq = null then
Arbre.Hg := 1 + Max(Arbre.Gauche.Hg,Arbre.Gauche.Hd);
end if;
else
Insertion(Donnee, Arbre.Droite,Deseq);
if Deseq = null then
Arbre.Hd := 1 + Max(Arbre.Droite.Hg,Arbre.Droite.Hd);
end if;
end if;
if abs(Arbre.Hd - Arbre.Hg) = 2 and Deseq = null then
Deseq := Arbre;
end if;
end if;
end Insertion;
-- Procedure principale
Mon_Arbre : T_Arbre;
Str : String(1..80) := (others => Ascii.Nul);
Taille : Natural;
Nb : Integer;
Deseq : T_Arbre;
begin
loop
begin
Put("Nombre: ");
Get_Line(Str,Taille);
exit when Taille = 0;
Nb := Integer'Value(Str(1..Taille));
Insertion(Nb,Mon_Arbre,Deseq);
if Deseq /= null then
Put_Line("Desequilibre!");
Reequilibre(Deseq);
end if;
New_Line;
--Hauteurs(Mon_Arbre);
Imprimer(Mon_Arbre,1);
New_Line;
exception
when Cle_Presente =>
Put_Line("Cl dj prsente!");
end;
end loop;
end avl;
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <assert.h>
#include <stdbool.h>
#include "avl.h"
void avl_print(arbre tree,int N) {
if (N <= 0) {
N = 1;
}
if (NULL != tree) {
avl_print(tree->child[1],N+2);
for (int i=0;i<N;i++) {
printf(" ");
}
printf("%d\n",tree->key);
avl_print(tree->child[0],N+2);
}
}
node* avl_desequilibre(arbre tree,clef key) {
node* crt = tree;
node* parent = NULL;
int h_prec[2] = {0,0};
while (NULL != crt && crt->key != key) {
if (abs(crt->h[1]-crt->h[0]) == 2) {
parent = crt;
h_prec[0] = parent->h[0];
h_prec[1] = parent->h[1];
parent->h[key > parent->key] -= 1;
}
crt = crt->child[key > crt->key];
}
if (NULL != parent) {
parent->h[0] = h_prec[0];
parent->h[1] = h_prec[1];
}
return parent;
}
int avl_height(arbre tree) {
if (NULL == tree) {
return 0;
} else {
return 1+fmax(avl_height(tree->child[0]),avl_height(tree->child[1]))+0.01;
}
}
void avl_heights(arbre tree) {
for (int i=0;i<2;i++) {
if (NULL != tree->child[i]) {
avl_heights(tree->child[i]);
tree->h[i] = 1+fmax(tree->child[i]->h[0],tree->child[i]->h[1])+0.01;
} else {
tree->h[i] = 0;
}
}
}
void avl_height_node(node* nd) {
for (int i=0;i<2;i++) {
if (NULL != nd->child[i]) {
nd->h[i] = 1+fmax(nd->child[i]->h[0],nd->child[i]->h[1])+0.01;
} else {
nd->h[i] = 0;
}
}
}
static node* avl_rot(node* P,bool right) {
node* Q = NULL;
if (NULL != P) {
Q = P->child[right];
P->child[right] = Q->child[!right];
Q->child[!right] = P;
avl_height_node(P);
avl_height_node(Q);
}
return Q;
}
node* avl_rot_g(node* nd) {
return avl_rot(nd,false);
}
node* avl_rot_d(node* nd) {
return avl_rot(nd,true);
}
static node* avl_rot2(node* nd,bool dg) {
nd->child[dg] = avl_rot(nd->child[dg],dg);
return avl_rot(nd,!dg);
}
node* avl_rot_gd(node* nd) {
return avl_rot2(nd,false);
}
node* avl_rot_dg(node* nd) {
return avl_rot2(nd,true);
}
static void avl_rotation(node* nd,bool right) {
node* new_nd = calloc(1,sizeof(node));
new_nd->key = nd->key;
new_nd->child[right] = nd->child[right];
new_nd->child[!right] = nd->child[!right]->child[right];
node* tmp = nd->child[!right];
nd->key = nd->child[!right]->key;
nd->child[right] = new_nd;
nd->child[!right] = nd->child[!right]->child[!right];
avl_height_node(new_nd);
avl_height_node(nd);
free(tmp);
}
void avl_rotation_g(node* nd) {
avl_rotation(nd,false);
}
void avl_rotation_d(node* nd) {
avl_rotation(nd,true);
}
static void avl_rotation2(node* nd,bool dg) {
avl_rotation(nd->child[dg],dg);
avl_rotation(nd,!dg);
}
void avl_rotation_gd(node* nd) {
avl_rotation2(nd,false);
}
void avl_rotation_dg(node* nd) {
avl_rotation2(nd,true);
}
void avl_reequilibre(node* nd) {
switch(nd->h[1]-nd->h[0]) {
case +2:
switch(nd->child[1]->h[1] - nd->child[1]->h[0]) {
case +1: avl_rotation_g(nd); break;
case -1: avl_rotation_dg(nd);
}
break;
case -2:
switch(nd->child[0]->h[1] - nd->child[0]->h[0]) {
case -1: avl_rotation_d(nd); break;
case +1: avl_rotation_gd(nd);
}
}
}
void avl_insert(clef key,arbre* tree,arbre* deseq) {
if (NULL == *tree) {
*tree = calloc(1,sizeof(node));
(*tree)->key = key;
*deseq = NULL;
} else {
avl_insert(key,&((*tree)->child[key > (*tree)->key]),deseq);
if (NULL == *deseq) {
(*tree)->h[key > (*tree)->key]
= 1+fmax((*tree)->child[key > (*tree)->key]->h[0],
(*tree)->child[key > (*tree)->key]->h[1]);
}
if (abs((*tree)->h[1]-(*tree)->h[0]) == 2 && NULL == *deseq) {
*deseq = *tree;
}
}
}
#ifndef AVL_H
#define AVL_H
typedef int clef;
typedef struct _node {
clef key;
struct _node* child[2];
int h[2];
} node;
typedef node* arbre;
//----------------------------------------------------------
// fonction qui imprime un arbre --
//----------------------------------------------------------
void avl_print(arbre tree,int N);
//----------------------------------------------------------
// fonction qui retourne le premier noeud déséquilibré et --
// met à jour les hauteurs sur le chemin d'insertion --
//----------------------------------------------------------
node* avl_desequilibre(arbre tree,clef key);
//----------------------------------------------------------
// fonction qui calcule la hauteur d'un arbre --
//----------------------------------------------------------
int avl_height(arbre tree);
//----------------------------------------------------------
// fonction qui remet à jour les hauteurs des noeuds --
// après le rééquilibrage --
//----------------------------------------------------------
void avl_heights(arbre tree);
//----------------------------------------------------------
// fonction qui remet à jour les hauteurs des noeuds --
// après le rééquilibrage --
//----------------------------------------------------------
void avl_height_node(node* nd);
//----------------------------------------------------------
// fonction qui effectue une rotation gauche sur le --
// noeud déséquilibré --
//----------------------------------------------------------
node* avl_rot_g(node* nd);
//----------------------------------------------------------
// fonction qui effectue une rotation droite sur le --
// noeud déséquilibré --
//----------------------------------------------------------
node* avl_rot_d(node* nd);
//----------------------------------------------------------
// fonction qui effectue une double rotation gauche --
// droite sur le noeud déséquilibré --
//----------------------------------------------------------
node* avl_rot_gd(node* nd);
//----------------------------------------------------------
// fonction qui effectue une double rotation droite --
// gauche sur le noeud déséquilibré --
//----------------------------------------------------------
node* avl_rot_dg(node* nd);
//----------------------------------------------------------
// fonction qui effectue une rotation gauche sur le --
// noeud déséquilibré --
//----------------------------------------------------------
void avl_rotation_g(node* nd);
//----------------------------------------------------------
// fonction qui effectue une rotation droite sur le --
// noeud déséquilibré --
//----------------------------------------------------------
void avl_rotation_d(node* nd);
//----------------------------------------------------------
// fonction qui effectue une double rotation gauche --
// droite sur le noeud déséquilibré --
//----------------------------------------------------------
void avl_rotation_gd(node* nd);
//----------------------------------------------------------
// fonction qui effectue une double rotation droite --
// gauche sur le noeud déséquilibré --
//----------------------------------------------------------
void avl_rotation_dg(node* nd);
//----------------------------------------------------------
// fonction qui rééquilibre l'arbre --
//----------------------------------------------------------
void avl_reequilibre(node* nd);
//----------------------------------------------------------
// fonction qui insère une valeur dans l'arbre --
//----------------------------------------------------------
void avl_insert(clef key,arbre* tree, arbre* deseq);
#endif
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
#include <math.h>
#include "bin_tree.h"
static node* position(arbre tree,int cle) {
node* crt = tree;
if (NULL != crt) {
while (cle != crt->key
&& NULL != crt->child[(cle > crt->key)]) {
crt = crt->child[(cle > crt->key)];
}
}
return crt;
}
int arbre_depth(arbre tree) {
if (NULL == tree) {
return 0;
} else {
return 1+fmax(arbre_depth(tree->child[0]),arbre_depth(tree->child[1]));
}
}
int arbre_size(arbre tree) {
if (NULL == tree) {
return 0;
} else {
return 1+arbre_size(tree->child[0])+arbre_size(tree->child[1]);
}
}
bool arbre_insert(arbre* tree,int cle) {
if (NULL == *tree) {
*tree = calloc(1,sizeof(node));
(*tree)->key = cle;
} else {
node* nd = position(*tree,cle);
if (cle != nd->key) {
nd->child[(cle > nd->key)] = calloc(1,sizeof(node));
nd->child[(cle > nd->key)]->key = cle;
} else {
return false;
}
}
return true;
}
static node* parent(arbre tree,node* nd) {
assert(NULL != tree && NULL != nd);
node* parent = NULL;
if (nd != tree) {
node* crt = tree;
int cle = nd->key;
do {
parent = crt;
if (cle != crt->key) {
crt = crt->child[(cle > crt->key)];
}
} while (crt != nd);
}
return parent;
}
bool arbre_delete(arbre* tree,int cle) {
node* nd = position(*tree,cle);
if (NULL == nd || cle != nd->key) {
return false;
}
// terminal node
if (NULL == nd->child[0] && NULL == nd->child[1]) {
node* nd_parent = parent(*tree,nd);
if (NULL == nd_parent) { // single node tree
*tree = NULL;
} else {
nd_parent->child[(nd == nd_parent->child[1])] = NULL;
}
free(nd);
return true;
}
for (int ind=0;ind<2;ind++) {
if (NULL != nd->child[ind]) {
node* next = position(nd->child[ind],cle);
int val = next->key;
if (NULL == nd->child[ind]->child[ind^1]) {
nd->child[ind] = next->child[ind];
free(next);
} else {
bool res = arbre_delete(tree,next->key);
}
nd->key = val;
return true;
}
}
}
void arbre_print(arbre tree,int N) {
if (N <= 0) {
N = 1;
}
if (NULL != tree) {
arbre_print(tree->child[1],N+1);
for (int i=0;i<N;i++) {
printf(" ");
}
printf("%d\n",tree->key);
arbre_print(tree->child[0],N+1);
}
}
bool arbre_search(arbre tree,int cle) {
node* nd = position(tree,cle);
return (NULL != nd && cle == nd->key);
}
#ifndef BIN_TREE_H
#define BIN_TREE_H
// Structure pour un arbre binaire
typedef int cle;
typedef struct _node {
cle key;
struct _node* child[2];
} node;
typedef node* arbre;
// Fonctionnalités pour un arbre binaire ordonné
bool arbre_search(arbre tree,int cle);
bool arbre_insert(arbre* tree,int cle);
bool arbre_delete(arbre* tree,int cle);
void arbre_print(arbre tree,int N);
int arbre_depth(arbre tree);
int arbre_size(arbre tree);
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <assert.h>
#include <stdbool.h>
#include "avl.h"
void main() {
arbre mon_arbre = NULL, deseq = NULL;
char nbr[20];
while (true) {
printf("Nombre: ");
scanf("%s",nbr);
if (strcmp(nbr,"quit") == 0) break;
avl_insert(atoi(nbr),&mon_arbre,&deseq);
if (NULL != deseq) {
printf("Desequilibre!");
avl_reequilibre(deseq);
}
printf("\n\n");
avl_print(mon_arbre,1);
printf("\n\n");
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment