


Explication graphique détaillée de l'algorithme de tri de tas Heap Sort et de l'implémentation du code JavaScript_Connaissances de base
1. Je dois parler des arbres binaires
Pour comprendre le tas, vous devez d'abord comprendre l'arbre binaire. En informatique, un arbre binaire est une structure arborescente dans laquelle chaque nœud possède au plus deux sous-arbres. Habituellement, les sous-arbres sont appelés « sous-arbre gauche » et « sous-arbre droit ». Les arbres binaires sont souvent utilisés pour implémenter des arbres de recherche binaires et des tas binaires.
Chaque nœud d'un arbre binaire possède au plus deux sous-arbres (il n'y a pas de nœud de degré supérieur à 2). Les sous-arbres d'un arbre binaire sont divisés en sous-arbres gauche et droit, et l'ordre ne peut pas être inversé. Le i-ème niveau d'un arbre binaire a au plus 2i - 1 nœuds ; un arbre binaire de profondeur k a au plus 2k - 1 nœuds pour tout arbre binaire T, si le nombre de nœuds terminaux est n0, le nombre de nœuds ; de degré 2 est n2, alors n0 = n2 + 1.
Trois différences principales entre les arbres et les arbres binaires :
Le nombre de nœuds d'un arbre doit être au moins 1, tandis que le nombre de nœuds d'un arbre binaire peut être 0
Il n'y a pas de limite au degré maximum d'un nœud dans un arbre, alors que le degré maximum d'un nœud dans un arbre binaire est 2
Les nœuds de l'arbre ne sont pas divisés en gauche et droite, tandis que les nœuds de l'arbre binaire sont divisés en gauche et droite
Les arbres binaires sont divisés en arbres binaires complets et arbres binaires complets
Arbre binaire complet : Un arbre de profondeur k et 2k - 1 nœuds est appelé un arbre binaire complet
(arbre binaire complet avec profondeur 3)
Arbre binaire complet : Un arbre binaire de profondeur k et n nœuds Si et seulement si chacun de ses nœuds correspond aux nœuds numérotés de 1 à n dans l'arbre binaire complet de profondeur k, on l'appelle un arbre binaire complet
.
(arbre binaire complet de profondeur 3)
2. Qu'est-ce qu'un tas ?
Un tas (tas binaire) peut être considéré comme un arbre binaire complet. Une "excellente" propriété d'un arbre binaire complet est que chaque niveau, à l'exception du niveau le plus bas, est plein, ce qui permet au tas d'utiliser des tableaux pour être représenté (ordinaire). les arbres binaires sont généralement représentés par des listes chaînées comme conteneurs de base), chaque nœud correspond à un élément du tableau.
Comme indiqué ci-dessous, c'est la relation entre un tas et un tableau
(Interrelation entre le tas et le tableau)
Pour un indice i donné d'un nœud, les indices du nœud parent et du nœud enfant de ce nœud peuvent être facilement calculés :
Parent(i) = floor(i/2), l'indice du nœud parent de i
Gauche(i) = 2i, i est l'indice gauche
Right(i) = 2i + 1, i est l'indice du nœud enfant de droite
Les tas binaires sont généralement divisés en deux types : le tas maximum et le tas minimum.
Tas maximum :
La valeur maximale de l'élément dans le tas max apparaît au nœud racine (en haut du tas)
La valeur de l'élément de chaque nœud parent dans le tas est supérieure ou égale à son nœud enfant (s'il existe)
(tas maximum)
Tas minimum :
La plus petite valeur d'élément dans le tas min apparaît au nœud racine (en haut du tas)
La valeur de l'élément de chaque nœud parent dans le tas est inférieure ou égale à son nœud enfant (s'il existe)
(min tas)
3. Principe du tri en tas
Le tri par tas consiste à retirer le nombre maximum en haut du tas maximum, à continuer d'ajuster le tas restant au tas maximum et à retirer à nouveau le nombre maximum en haut du tas. Ce processus se poursuit jusqu'à là. n'est qu'un nombre restant. Définissez les opérations suivantes sur le tas :
Max-Heapify : Ajustez les nœuds enfants finaux du tas afin que les nœuds enfants soient toujours plus petits que le nœud parent
Créer un tas maximum (Build-Max-Heap) : réorganisez toutes les données du tas pour en faire un tas maximum
Heap-Sort : supprimez le nœud racine des premières données et effectuez une opération récursive d'ajustement maximal du tas
Avant de poursuivre la discussion suivante, une chose à noter est que les tableaux sont tous de base zéro, ce qui signifie que notre modèle de structure de données de tas va changer
(Basé zéro)
En conséquence, plusieurs formules de calcul doivent également être ajustées en conséquence :
Parent(i) = floor((i-1)/2), l'indice du nœud parent de i
Left(i) = 2i + 1, l'indice du nœud enfant gauche de i
Right(i) = 2(i + 1), i est l'indice du nœud enfant de droite
La fonction d'ajustement du tas maximum (MAX-HEAPIFY) est de maintenir les propriétés du tas maximum et constitue le sous-programme principal pour créer le tas maximum. Le processus fonctionnel est comme indiqué dans la figure :
.
(Max-Heapify)
Étant donné qu'après un ajustement, le tas viole toujours les propriétés du tas, des tests récursifs sont nécessaires pour que l'ensemble du tas satisfasse les propriétés du tas. Cela peut être exprimé en JavaScript comme suit :
/** * 从 index 开始检查并保持最大堆性质 * * @array * * @index 检查的起始下标 * * @heapSize 堆大小 * **/ function maxHeapify(array, index, heapSize) { var iMax = index, iLeft = 2 * index + 1, iRight = 2 * (index + 1); if (iLeft < heapSize && array[index] < array[iLeft]) { iMax = iLeft; } if (iRight < heapSize && array[iMax] < array[iRight]) { iMax = iRight; } if (iMax != index) { swap(array, iMax, index); maxHeapify(array, iMax, heapSize); // 递归调整 } } function swap(array, i, j) { var temp = array[i]; array[i] = array[j]; array[j] = temp; }
De manière générale, la récursivité est principalement utilisée dans la méthode diviser pour régner, mais diviser pour régner n'est pas obligatoire ici. De plus, les appels récursifs nécessitent de pousser/effacer la pile, ce qui présente un léger inconvénient en termes de performances par rapport à l'itération. Bien entendu, en suivant la règle des 20/80, cela peut être ignoré. Mais si vous pensez que l'utilisation de la récursivité vous mettra mal à l'aise, vous pouvez également utiliser l'itération, comme celle-ci :
/** * 从 index 开始检查并保持最大堆性质 * * @array * * @index 检查的起始下标 * * @heapSize 堆大小 * **/ function maxHeapify(array, index, heapSize) { var iMax, iLeft, iRight; while (true) { iMax = index; iLeft = 2 * index + 1; iRight = 2 * (index + 1); if (iLeft < heapSize && array[index] < array[iLeft]) { iMax = iLeft; } if (iRight < heapSize && array[iMax] < array[iRight]) { iMax = iRight; } if (iMax != index) { swap(array, iMax, index); index = iMax; } else { break; } } } function swap(array, i, j) { var temp = array[i]; array[i] = array[j]; array[j] = temp; }
La fonction de création d'un tas maximum (Build-Max-Heap) est de transformer un tableau en un tas maximum. Il accepte deux paramètres : le tableau et la taille du tas appelleront Max-Heapify de bas en haut. top Transformez le tableau et créez un tas maximum. Étant donné que Max-Heapify peut garantir que les nœuds après le nœud avec l'indice i satisfont à la propriété de tas maximum, l'appel ascendant de Max-Heapify peut conserver cette propriété pendant le processus de transformation. Si le nombre d'éléments dans le tas maximum est n, alors Build-Max-Heap commence à partir de Parent(n) et appelle Max-Heapify dans l'ordre. Le processus est le suivant :
Décrit en JavaScript comme suit :
function buildMaxHeap(array, heapSize) { var i, iParent = Math.floor((heapSize - 1) / 2); for (i = iParent; i >= 0; i--) { maxHeapify(array, i, heapSize); } }
Heap-Sort est l'algorithme d'interface du tri par tas. Heap-Sort appelle d'abord Build-Max-Heap pour transformer le tableau en un tas maximum, puis échange les éléments supérieur et inférieur du tas, puis élève le bas, et enfin, rappelez Max-Heapify pour conserver les propriétés maximales du tas. Étant donné que l'élément supérieur du tas doit être le plus grand élément du tas, après une opération, le plus grand élément existant dans le tas est séparé du tas. Après avoir répété n-1 fois, le tableau est organisé. L'ensemble du processus est le suivant :
Décrit en JavaScript comme suit :
function heapSort(array, heapSize) { buildMaxHeap(array, heapSize); for (int i = heapSize - 1; i > 0; i--) { swap(array, 0, i); maxHeapify(array, 0, i); } }
4. Implémentation du langage JavaScript
Enfin, organisez ce qui précède dans le code javascript complet comme suit :
function heapSort(array) { function swap(array, i, j) { var temp = array[i]; array[i] = array[j]; array[j] = temp; } function maxHeapify(array, index, heapSize) { var iMax, iLeft, iRight; while (true) { iMax = index; iLeft = 2 * index + 1; iRight = 2 * (index + 1); if (iLeft < heapSize && array[index] < array[iLeft]) { iMax = iLeft; } if (iRight < heapSize && array[iMax] < array[iRight]) { iMax = iRight; } if (iMax != index) { swap(array, iMax, index); index = iMax; } else { break; } } } function buildMaxHeap(array) { var i, iParent = Math.floor(array.length / 2) - 1; for (i = iParent; i >= 0; i--) { maxHeapify(array, i, array.length); } } function sort(array) { buildMaxHeap(array); for (var i = array.length - 1; i > 0; i--) { swap(array, 0, i); maxHeapify(array, 0, i); } return array; } return sort(array); }
5. Application de l'algorithme de tri par tas
(1) Performance/complexité de l'algorithme
La complexité temporelle du tri par tas est très stable (on peut voir qu'elle n'est pas sensible aux données d'entrée), c'est une complexité O(n㏒n), et le meilleur des cas est le même que le pire des cas.
Cependant, sa complexité spatiale varie d’une mise en œuvre à l’autre. Deux complexités courantes ont été discutées ci-dessus : O(n) et O(1). Conformément au principe d'économie d'espace, je recommande la méthode de complexité O(1).
(2) Stabilité de l'algorithme
Le tri par tas implique un grand nombre de processus de filtrage et de déplacement et constitue un algorithme de tri instable.
(3) Scénarios applicables à l'algorithme
Le tri du tas entraînera une surcharge relativement importante dans le processus d'établissement et d'ajustement du tas, et ne convient pas lorsqu'il y a peu d'éléments. Cela reste cependant un bon choix lorsqu’il y a de nombreux éléments. Surtout lors de la résolution de problèmes tels que « les n premiers plus grands nombres », c’est presque l’algorithme préféré.

Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

AI Hentai Generator
Générez AI Hentai gratuitement.

Article chaud

Outils chauds

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Comment utiliser WebSocket et JavaScript pour mettre en œuvre un système de reconnaissance vocale en ligne Introduction : Avec le développement continu de la technologie, la technologie de reconnaissance vocale est devenue une partie importante du domaine de l'intelligence artificielle. Le système de reconnaissance vocale en ligne basé sur WebSocket et JavaScript présente les caractéristiques d'une faible latence, d'un temps réel et d'une multiplateforme, et est devenu une solution largement utilisée. Cet article explique comment utiliser WebSocket et JavaScript pour implémenter un système de reconnaissance vocale en ligne.

La technologie de détection et de reconnaissance des visages est déjà une technologie relativement mature et largement utilisée. Actuellement, le langage d'application Internet le plus utilisé est JS. La mise en œuvre de la détection et de la reconnaissance faciale sur le front-end Web présente des avantages et des inconvénients par rapport à la reconnaissance faciale back-end. Les avantages incluent la réduction de l'interaction réseau et de la reconnaissance en temps réel, ce qui réduit considérablement le temps d'attente des utilisateurs et améliore l'expérience utilisateur. Les inconvénients sont les suivants : il est limité par la taille du modèle et la précision est également limitée ; Comment utiliser js pour implémenter la détection de visage sur le web ? Afin de mettre en œuvre la reconnaissance faciale sur le Web, vous devez être familier avec les langages et technologies de programmation associés, tels que JavaScript, HTML, CSS, WebRTC, etc. Dans le même temps, vous devez également maîtriser les technologies pertinentes de vision par ordinateur et d’intelligence artificielle. Il convient de noter qu'en raison de la conception du côté Web

Outils essentiels pour l'analyse boursière : découvrez les étapes pour dessiner des graphiques en bougies en PHP et JS. Des exemples de code spécifiques sont nécessaires. Avec le développement rapide d'Internet et de la technologie, le trading d'actions est devenu l'un des moyens importants pour de nombreux investisseurs. L'analyse boursière est une partie importante de la prise de décision des investisseurs, et les graphiques en bougies sont largement utilisés dans l'analyse technique. Apprendre à dessiner des graphiques en bougies à l'aide de PHP et JS fournira aux investisseurs des informations plus intuitives pour les aider à prendre de meilleures décisions. Un graphique en chandeliers est un graphique technique qui affiche les cours des actions sous forme de chandeliers. Il montre le cours de l'action

WebSocket et JavaScript : technologies clés pour réaliser des systèmes de surveillance en temps réel Introduction : Avec le développement rapide de la technologie Internet, les systèmes de surveillance en temps réel ont été largement utilisés dans divers domaines. L'une des technologies clés pour réaliser une surveillance en temps réel est la combinaison de WebSocket et de JavaScript. Cet article présentera l'application de WebSocket et JavaScript dans les systèmes de surveillance en temps réel, donnera des exemples de code et expliquera leurs principes de mise en œuvre en détail. 1. Technologie WebSocket

Introduction à l'utilisation de JavaScript et de WebSocket pour mettre en œuvre un système de commande en ligne en temps réel : avec la popularité d'Internet et les progrès de la technologie, de plus en plus de restaurants ont commencé à proposer des services de commande en ligne. Afin de mettre en œuvre un système de commande en ligne en temps réel, nous pouvons utiliser les technologies JavaScript et WebSocket. WebSocket est un protocole de communication full-duplex basé sur le protocole TCP, qui peut réaliser une communication bidirectionnelle en temps réel entre le client et le serveur. Dans le système de commande en ligne en temps réel, lorsque l'utilisateur sélectionne des plats et passe une commande

Avec le développement rapide de la finance sur Internet, l'investissement en actions est devenu le choix de plus en plus de personnes. Dans le trading d'actions, les graphiques en bougies sont une méthode d'analyse technique couramment utilisée. Ils peuvent montrer l'évolution des cours des actions et aider les investisseurs à prendre des décisions plus précises. Cet article présentera les compétences de développement de PHP et JS, amènera les lecteurs à comprendre comment dessiner des graphiques en bougies boursières et fournira des exemples de code spécifiques. 1. Comprendre les graphiques en bougies boursières Avant de présenter comment dessiner des graphiques en bougies boursières, nous devons d'abord comprendre ce qu'est un graphique en bougies. Les graphiques en chandeliers ont été développés par les Japonais

JavaScript et WebSocket : Construire un système efficace de prévisions météorologiques en temps réel Introduction : Aujourd'hui, la précision des prévisions météorologiques revêt une grande importance pour la vie quotidienne et la prise de décision. À mesure que la technologie évolue, nous pouvons fournir des prévisions météorologiques plus précises et plus fiables en obtenant des données météorologiques en temps réel. Dans cet article, nous apprendrons comment utiliser la technologie JavaScript et WebSocket pour créer un système efficace de prévisions météorologiques en temps réel. Cet article démontrera le processus de mise en œuvre à travers des exemples de code spécifiques. Nous

Tutoriel JavaScript : Comment obtenir le code d'état HTTP, des exemples de code spécifiques sont requis Préface : Dans le développement Web, l'interaction des données avec le serveur est souvent impliquée. Lors de la communication avec le serveur, nous devons souvent obtenir le code d'état HTTP renvoyé pour déterminer si l'opération a réussi et effectuer le traitement correspondant en fonction de différents codes d'état. Cet article vous apprendra comment utiliser JavaScript pour obtenir des codes d'état HTTP et fournira quelques exemples de codes pratiques. Utilisation de XMLHttpRequest
