|
Trouver une ressource
Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum. Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !
[C ANSI] TAS (PRIORITY QUEUE)
Information sur la source
Description
On voit souvent ici des "programmes" qui mettent en oeuvre uniquement une liste chainee, ou une liste doublement chainee. Ici, je vous propose une structure particuliere d'arbre binaire complet ordonnee de la facon suivante :
chaque pere a une valeur plus elevee que ses deux enfants.
si il manque des enfants, c'est forcement "en bas a droite".
toutes les branches ont la meme hauteur (sauf eventuellement, tout en bas a droite)
sur une telle structure, on s'appercoit que si on les numerote :
0
1 2
3 4 5 6
7 8 9 10 11 12 13 14
alors si un pere est numerote : i, ses enfants sont : 2i et 2i+1
a partir de la, on peut faire une structure de tableau, et on evite ainsi le triple chainage (et on y gagne un random acces, meme si avant l'acces etait logarithmique, c'est toujours mieux.)
Bref, sur cette structure, on peut ajouter des elements, supprimer des elements (de preference, on supprime celui du dessus) en O(log(n)).
sur une liste non triee, on aurait l'insertion en O(1) et la suppression (ainsi que la recherche) du plus grand element en O(n)
sur une liste triee, c'est l'insertion qui serait en O(n), la suppression et la recherche du plus grand element serait en O(1)
c'est donc une bonne structure pour une file de priorites (priority queue), meme si elle ne permet pas le "merge" de deux tas en O(log(n)) mais seulement en O(n).
certaines fonctions sont plutot la pour la decoration (to_2_exp, ln2, spaces servent uniquement pour pouvoir faire draw_tas)
mon exemple est avec une file d'int, mais on peut l'adapter pour n'importe quel type, voir carement en faire une classe Cpp avec des templates.
il existe une methode de tri qui se base sur l'insertion dans une liste comme ceci, ca fait un tres bon tri en O(n log(n)), a peu pres entre le merge sort et le quick sort.
Source
- #include <stdio.h>
- #include <stdlib.h>
-
- void swap(int *v1, int *v2){
- int v3 = *v1;
- *v1 = *v2;
- *v2 = v3;
- }
-
- int to_2_exp(int i){
- if (i==0) return 0;
- if (i==1) return 1;
- return 2 * to_2_exp( i / 2);
- }
-
- int ln2(int i){
- if (i==0) return 0;
- if (i==1) return 1;
- return 1 + to_2_exp( i / 2);
- }
-
- void spaces(int n){
- int i;
- for (i=0; i<n; i++) putchar(' ');
- }
-
- typedef int * tas;
-
- tas new_tas(size_t s){
- return malloc(s * sizeof(int));
- }
-
- void fixup(tas t, size_t n){
- if (n == 0) return;
- else{
- int n2 = (n-1)/2;
- if (t[n] > t[n2]){
- swap(&t[n], &t[n2]);
- fixup(t, n2);
- }
- }
- }
-
- void fixdown(tas t, size_t n, size_t max){
- int n2 = n*2+1;
- if (n2 >= max) return;
- if (n2 + 1 < max && t[n2+1] > t[n2] ) n2++;
- if (t[n] < t[n2]){
- swap(&t[n], &t[n2]);
- fixdown(t, n2, max);
- }
- }
-
- void draw_tas(tas t, size_t n){
- int i;
- int k = 1;
- int k_max = to_2_exp(n);
- int v;
- for (i=0; i<n; i++){
- if (i == k - 1){
- k *= 2;
- if (i) putchar('\n');
- v = 2* (k_max * 2 / k ) - 1;
- spaces(v);
- }
- printf("%2d", t[i]);
- spaces(2 * v);
-
- }
- putchar('\n');
- }
-
- size_t add_tas(tas t, int value, size_t n){
- t[n] = value;
- fixup(t, n);
- return n+1;
- }
-
- size_t pop_tas(tas t, size_t n){
- t[0] = t[--n];
- fixdown(t, 0, n);
- return n;
- }
-
-
- int main(){
- /* exemple d'utilisation d'un tas */
- int s = 0;
- tas t = new_tas(15);
-
- add_tas(t, 12, s++);
- add_tas(t, 24, s++);
- add_tas(t, 48, s++);
-
- add_tas(t, 15, s++);
- add_tas(t, 23, s++);
- add_tas(t, 49, s++);
-
- add_tas(t, 19, s++);
- add_tas(t, 54, s++);
- add_tas(t, 29, s++);
-
- add_tas(t, 18, s++);
- add_tas(t, 53, s++);
- add_tas(t, 92, s++);
-
- add_tas(t, 90, s++);
- add_tas(t, 64, s++);
- add_tas(t, 22, s++);
-
-
- draw_tas(t, s);
- s = pop_tas(t, s);
- s = pop_tas(t, s);
- draw_tas(t, s);
- free(t);
- return 0;
- }
#include <stdio.h>
#include <stdlib.h>
void swap(int *v1, int *v2){
int v3 = *v1;
*v1 = *v2;
*v2 = v3;
}
int to_2_exp(int i){
if (i==0) return 0;
if (i==1) return 1;
return 2 * to_2_exp( i / 2);
}
int ln2(int i){
if (i==0) return 0;
if (i==1) return 1;
return 1 + to_2_exp( i / 2);
}
void spaces(int n){
int i;
for (i=0; i<n; i++) putchar(' ');
}
typedef int * tas;
tas new_tas(size_t s){
return malloc(s * sizeof(int));
}
void fixup(tas t, size_t n){
if (n == 0) return;
else{
int n2 = (n-1)/2;
if (t[n] > t[n2]){
swap(&t[n], &t[n2]);
fixup(t, n2);
}
}
}
void fixdown(tas t, size_t n, size_t max){
int n2 = n*2+1;
if (n2 >= max) return;
if (n2 + 1 < max && t[n2+1] > t[n2] ) n2++;
if (t[n] < t[n2]){
swap(&t[n], &t[n2]);
fixdown(t, n2, max);
}
}
void draw_tas(tas t, size_t n){
int i;
int k = 1;
int k_max = to_2_exp(n);
int v;
for (i=0; i<n; i++){
if (i == k - 1){
k *= 2;
if (i) putchar('\n');
v = 2* (k_max * 2 / k ) - 1;
spaces(v);
}
printf("%2d", t[i]);
spaces(2 * v);
}
putchar('\n');
}
size_t add_tas(tas t, int value, size_t n){
t[n] = value;
fixup(t, n);
return n+1;
}
size_t pop_tas(tas t, size_t n){
t[0] = t[--n];
fixdown(t, 0, n);
return n;
}
int main(){
/* exemple d'utilisation d'un tas */
int s = 0;
tas t = new_tas(15);
add_tas(t, 12, s++);
add_tas(t, 24, s++);
add_tas(t, 48, s++);
add_tas(t, 15, s++);
add_tas(t, 23, s++);
add_tas(t, 49, s++);
add_tas(t, 19, s++);
add_tas(t, 54, s++);
add_tas(t, 29, s++);
add_tas(t, 18, s++);
add_tas(t, 53, s++);
add_tas(t, 92, s++);
add_tas(t, 90, s++);
add_tas(t, 64, s++);
add_tas(t, 22, s++);
draw_tas(t, s);
s = pop_tas(t, s);
s = pop_tas(t, s);
draw_tas(t, s);
free(t);
return 0;
}
Conclusion
voici le rendu de mon programme :
apres les insertions :
92
90 53
64 24 49 54
22 12 18 23 29 15 48 19
apres les suppressions :
64
54 53
48 24 49 19
22 12 18 23 29 15
ca compile sous linux, avec juste les options suivantes :
gcc tas.c -g -Wall -ansi --pedantic
Historique
- 07 novembre 2008 04:01:53 :
- correction
Sources du même auteur
FONCTIONS USUELLES (TRIGO) EN METAPROGRAMMATION Ma source montre un calcul des quelques fonctions suivantes :
cos, sin, tan, cosH, tanH, sinH, exp, ln, sqrt, fibonaci, triangle de pascal, ...
sans... FONCTIONS USUELLES (TRIGO) EN METAPROGRAMMATION
Sources de la même categorie
Sources en rapport avec celle ci
Commentaires et avis
Discussions en rapport avec ce code source dans le forum
Problème avec traitement de fichier (cplusplus !) [ par Sianrin ]
Voila, j'explique mon problème. Pour voir un peu comment les accès au fichiers se géraient en cplusplus, je me suis mis en tête de faire un programme
prob de compilation [ par jacky66 ]
salutje debute dans la prog c++pour mon 1 er prog quand je compile il me sort un message fatal error C1083: Cannot open include file: 'idoctidm.h': No
Pb avec une fonction windows... [ par Steak ]
j'ai un petit probleme avec la fonction NT UpdateResource... voila ce que dit le sdk win32 : BOOL UpdateResource( HANDLE hUpdate, // update-file handl
Enregistrer en HEXA un texte avec gcc !! [ par UncleShu ]
/* * Ce programme affiche le fichier en HEXADECIMAL et se copie lui-même avec * une autre exetenstion (.txt). Moi je voudrais qui affiche le fichier *
Petit probleme de code en C sur Linux !! [ par UncleShu ]
Je voudrais créer un fichier dans le réperoire personnel d'un utilisateur mais mon code ne marche pas !!#include <stdio.h> #include <stdlib.h
conversion [ par coyotedef ]
salut!!lors de la compilation de mon code une erreur apparait. impossible de trouver un remede. "cannot convert parameter 1 from 'char [10]' to 'char'
devc++ et glut [ par aluco ]
j'ai bo ajouter les fichiers: Options -> Compiler Options -> Add the following commands when calling compiler -> -lglut32 -lopengl32 -lglu32
Traitement de tableau de caracteres. [ par coyotedef ]
Je lit des données a partir d un fichier texte et je classe les caracteres dans un tableau de caracteres. jusque la rien de bien special.mais voila, j
pb avec un labyrinthe [ par skinia ]
je suis sur un projet de labyrinthe et j'ai bloqué pour l' algorithme du plus court chemin (entre un pt qq du labyrinthe et la cible au milieu).le lab
ouverture de fichier avec les MFC [ par steph76 ]
Bonjourvoila je programme une application qui ha beusoin d'ouvrir 1 fichier via httpJ'ai donc fait le code suivantCStdioFile *file;CInternetSession IS
|
Téléchargements
Logiciels à télécharger sur le même thème :
Comparez les prix Nouvelle version
|