# coding: utf-8 class Tas: class Element: def __init__(self, valeur, priorite, index): self.valeur = valeur self.priorite = priorite self.index = index def __str__(self): return str(self.valeur) def __init__(self, fonctionPriorite): self.L = [] self.fonctionPriorite = fonctionPriorite def __str__(self): s = "[" for elt in self.L: s += " " + str(elt) s += "]" return s def __parent(self, elt): if(elt.index == 0): return None else: return self.L[(elt.index - 1) // 2] def __fils_gauche(self, elt): i = 2 * elt.index + 1 if(i < len(self.L)): return self.L[i] else: return None def __fils_droit(self, elt): i = 2 * elt.index + 2 if(i < len(self.L)): return self.L[i] else: return None def __deplace(self, elt, index): assert isinstance(elt, Tas.Element) ancien = elt.index self.L[index] = elt elt.index = index return ancien def __promeut(self, elt): while(True): parent = self.__parent(elt) if(parent == None): break if(parent.priorite >= elt.priorite): break elt.index = self.__deplace(parent, elt.index) self.__deplace(elt, elt.index) def actualise(self, elt): assert isinstance(elt, Tas.Element) elt.priorite = self.fonctionPriorite(elt.valeur) self.__promeut(elt) def ajoute(self, valeur): elt = Tas.Element(valeur, self.fonctionPriorite(valeur), len(self.L)) self.L.append(elt) self.__promeut(elt) return elt def empty(self): return len(self.L) == 0 def pop(self): n = len(self.L) if(n == 0): return None tete = self.L[0] elt = self.L[n - 1] elt.index = 0 while True: filsGauche = self.__fils_gauche(elt) filsDroit = self.__fils_droit(elt) plusPrioritaire = elt if(filsGauche != None and filsGauche.priorite > plusPrioritaire.priorite): plusPrioritaire = filsGauche if(filsDroit != None and filsDroit.priorite > plusPrioritaire.priorite): plusPrioritaire = filsDroit elt.index = self.__deplace(plusPrioritaire, elt.index) if(plusPrioritaire is elt): break self.L.pop() return tete.valeur ######################################### # Exemple d'utilisatio de la classe Tas # # Tri de tâches par ordre chronologique # ######################################### class Tache: '''Tache devant être effectuée avant une date limite''' def __init__(self, jour, nom): self.jour = jour self.nom = nom # Cet attribut servira à accueillir la clé du tas self.cle = None def __str__(self): return self.nom + " ({})".format(self.jour) if __name__ == "__main__": # Le niveau de priorité d'un événement x est -x.jour : on trie donc les événements par ordre chronologique def calculePriorite(tache): return -tache.jour # On crée un tas dont les éléments sont des événements triés par ordre chronologique T = Tas(calculePriorite) # Ajoute des événements au tas evts = [Tache(5, "T1"), Tache(10, "T2"), Tache(5, "T3"), Tache(3, "T4")] for evt in evts: evt.cle = T.ajoute(evt) # Supposons que la tache 2 devienne soudain assez urgente evts[1].jour = 4 T.actualise(evts[1].cle) # Retirons dans l'ordre chronologie les éléments du tas while(not T.empty()): print(T.pop())