Pas grave je pense que j'ai une réponse qui vous donne toutes ces opérations dans amorti O(1), ce qui signifie que toute une opération pourrait prendre jusqu'à O(n), mais n'importe quelle séquence de n opérations prend O(1) fois par opération.
L'idée est de stocker vos données dans un arbre Cartésien. C'est un arbre binaire obéissant à de la min-propriété tas (chaque nœud est pas plus grand que ses enfants), et est commandé de telle façon qu'un afinde de la traversée de l'nœuds permet les nœuds dans le même ordre dans lequel ils ont été ajoutés. Pour exemple, voici un Cartésien de l'arbre de la séquence de 2 1 4 3 5
:
1
/ \
2 3
/ \
4 5
Il est possible d'insérer un élément dans un arbre Cartésien en O(1) amorti temps à l'aide de la procédure suivante. Regardez la tranche droite de l'arbre (le chemin de la racine à la droite de la feuille formée par toujours marchant vers la droite). Départ à droite du nœud, balayez vers le haut le long de ce chemin jusqu'à ce que vous trouver le premier noeud plus petit que le nœud de l'insertion.
Changement de nœud, de sorte que son droit est cet enfant nouveau nœud, puis assurez-vous que le nœud de l'ancien droit de l'enfant à la gauche de l'enfant du nœud que vous venez d'ajouter. Par exemple, supposons que nous voulons insérer une autre copie de 2) dans le dessus de l'arbre. Nous marchons jusqu'à la droite de la colonne vertébrale passé le 5 et le 3, mais stop au-dessous de la 1 car 1 < 2. Nous avons ensuite changer l'arbre à ressembler à ceci:
1
/ \
2 2
/
3
/ \
4 5
Notez qu'une afinde traversée donne 2 1 4 3 5 2, qui est la séquence dans laquelle nous avons ajouté les valeurs.
Cela va dans amorti O(1) car il peut créer une fonction de potentiel égal au nombre de nœuds dans la tranche droite de l'arbre. Le temps réel nécessaire pour insérer un nœud est de 1, plus le nombre de nœuds dans la colonne vertébrale, nous considérons (appelons k). Une fois que nous trouvons de la place pour insérer le nœud, la taille de la colonne vertébrale se rétrécit en fonction de la longueur k - 1, puisque chacune des k nœuds que nous avons visités ne sont plus sur le droit de la colonne vertébrale, et le nouveau nœud est à sa place. Cela donne un coût amorti de 1 + k + (1 - k) = 2 = O(1), pour l'amorti O(1) insérer. Une autre façon de penser à ce sujet, une fois qu'un nœud a été déplacé de la droite de la colonne vertébrale, il n'est jamais partie de la tranche droite de nouveau, et ainsi nous n'aurons jamais à se déplacer à nouveau. Depuis chacune des n nœuds peut être déplacé plus d'une fois, cela signifie que n insertions peuvent le faire au plus n se déplace, de sorte que le total d'exécution est au plus O(n) pour un amorti O(1) par élément.
Pour faire une résorption de l'étape, on enlève simplement la plus à gauche du nœud de l'arbre Cartésien. Si ce nœud est une feuille, nous avons terminé. Sinon, le nœud peut avoir qu'un seul enfant (l'enfant), et nous avons donc remplacer le noeud avec son enfant. À condition de garder une trace de l'endroit où le nœud le plus à gauche est, cette étape prend O(1) fois. Cependant, après la suppression de la plus à gauche du nœud et de la remplacer par son droit à l'enfant, nous pourrions ne pas savoir où le nouveau nœud le plus à gauche est. Pour résoudre ce problème, nous avons tout simplement marcher sur le côté gauche de la colonne vertébrale de l'arbre de départ au nouveau nœud on a juste déplacé vers l'extrême gauche de l'enfant. Je demande que cela s'exécute en O(1) amorti temps. Pour voir cela, j'affirme qu'un nœud est visité plus d'une fois au cours de l'une de ces passes pour trouver le nœud le plus à gauche. Pour voir cela, notez qu'une fois qu'un nœud a reçu la visite de cette façon, la seule façon que nous pourrions avoir besoin de le regarder de nouveau, serait si elle ont été déplacées d'un enfant de la plus à gauche du nœud le plus à gauche du nœud. Mais tous les nœuds visités sont les parents de la plus à gauche du nœud, de sorte que cela ne se peut. Par conséquent, chaque nœud est visité plus d'une fois au cours de ce processus, et de la pop s'exécute en O(1).
Nous pouvons faire trouver-min en O(1) car la rupture Cartésienne de l'arbre nous donne accès à la plus petit élément de l'arborescence pour gratuits; c'est la racine de l'arbre.
Enfin, pour voir que les nœuds de revenir dans le même ordre dans lequel ils ont été insérés, notez qu'un Cartésien arbre stocke ses éléments, de sorte qu'un afinde traversée de visites dans l'ordre de tri. Depuis que nous avons toujours supprimer le nœud le plus à gauche à chaque étape, et c'est le premier élément de la afinde de la traversée, nous avons toujours obtenir les nœuds dans l'ordre dans lequel ils ont été insérés.
En bref, nous obtenons O(1) amorti push et pop, et O(1) le pire des cas, trouvez-min.
Si je peut venir avec un pire cas O(1) mise en œuvre, je vais certainement poster. Ce fut un grand problème; merci de poster!