table des matières:
- 1. Tas
- 2. Implémentation du tas
-
- 2.1 Algorithme d'ajustement vers le bas du tas (construire un petit tas)
- 2.2 Implémentation de l'algorithme d'ajustement vers le bas du tas (construire un petit tas)
- 2.3 Algorithme d'ajustement vers le haut du tas
- 2.4 Implémentation de l'algorithme d'ajustement vers le haut (construction de petites piles)
- 2.5 Algorithme de construction de tableaux (construire un petit tas)
- 2.6 Implémentation de l'algorithme de construction de tableaux (construction de petits tas)
- 2.7 Tri de tas (ordre décroissant)
- 2.8 Implémentation du tri de tas (ordre décroissant)
- 2.9 Complexité temporelle de la construction d'un réacteur
1. Tas
Big root heap: tous les nœuds parents sont supérieurs ou égaux aux nœuds enfants
Petit tas racine: la nature de tous les nœuds parents inférieure ou égale au tas de nœuds enfant
:
• La valeur d'un nœud dans le tas n'est toujours ni supérieure ni inférieure à la valeur de son nœud parent
• Le tas est toujours un arbre binaire complet
2. Implémentation du tas
Pour la réalisation du tas, veuillez cliquer -> Réalisation du tas
Maintenant, nous donnons un tableau, qui est logiquement considéré comme un arbre binaire complet. Nous pouvons l'ajuster en une petite pile grâce à l'algorithme d'ajustement vers le bas à partir du nœud racine.
int a[] = {27,15,19,18,28,34,65,49,25,37};
2.1 Algorithme d'ajustement vers le bas du tas (construire un petit tas)
Algorithme d'ajustement vers le bas - prémisse: les sous-arbres gauche et droit de l'arbre courant doivent être un petit tas
. L'idée centrale de l'algorithme d'ajustement vers le bas: choisir lequel des enfants gauche et droit, échanger avec le père, le petit flotte, le gros coule , Si vous voulez construire un gros tas, le contraire est vrai
La figure suivante montre une méthode d'ajustement vers le bas pour ajuster la petite pile
2.2 Implémentation de l'algorithme d'ajustement vers le bas du tas (construire un petit tas)
//堆向下调整算法
//建小堆
void AdjustDown(int* a, int n, int root)
{
int parent = root;
int child = parent * 2 + 1;
//孩子超过数组下标结束
while (child < n)
{
//child始终左右孩子中小的那个
if (a[child + 1] < a[child] && child + 1 <n)//防止没有右孩子
{
++child;
}
//小的往上浮,大的往下浮
if (a[child] < a[parent])
{
int tem = a[parent];
a[parent] = a[child];
a[child] = tem;
parent = child;
child = parent * 2 + 1;
}
//中途child>parent则已满足小堆,直接break
else
{
break;
}
}
}
2.3 Algorithme d'ajustement vers le haut du tas
Scénario d'utilisation: pour insérer des données dans le tas, vous devez utiliser l'algorithme d'ajustement vers le haut pour ajuster, car l'insertion de données dans le tas consiste à insérer les données dans la position indiquée par size. À ce stade, le petit tas (grand tas) n'est pas satisfait. Par conséquent, le tas est nécessaire. Son ajustement, l'algorithme d'ajustement vers le haut est similaire à l'algorithme d'ajustement vers le bas. Ici, en prenant une petite pile comme exemple, la méthode d'ajustement vers le haut ne doit commencer qu'à partir de la position du nœud inséré comparez-le avec le nœud parent. Si a [chaild] <a [parent], alors Exchange, si a [chaild]> = a [parent], cela signifie que le hors-limites rencontre le petit tas, et se brise directement
Insérez une donnée comme indiqué dans la figure ci-dessous et utilisez la méthode d'ajustement vers le haut pour ajuster
2.4 Implémentation de l'algorithme d'ajustement vers le haut (construction de petites piles)
//堆的向上调整算法
//建小堆
void AdjustUp(HPDataType* a, int child)
{
int parent = (child - 1) / 2;
while (child > 0)
{
if (a[child] < a[parent])
{
int tem = a[parent];
a[parent] = a[child];
a[child] = tem;
child = parent;
parent = (child - 1) / 2;
}
else
{
break;
}
}
}
2.5 Algorithme de construction de tableaux (construire un petit tas)
Si les sous-arbres gauche et droit ne sont pas de petits tas - trouvez un moyen de traiter les sous-arbres gauche et droit en petits tas, en
partant de la position du premier nœud non-feuille à partir du bas pour ajuster vers le bas
Comme le montre la figure ci-dessous, il peut être ajusté vers le bas selon les étapes de la figure. L'
indice du dernier nœud non-feuille est (n-1-1) / 2
2.6 Implémentation de l'algorithme de construction de tableaux (construction de petits tas)
int n = sizeof(a) / sizeof(int);
//数组建堆算法
for (int i = (n - 1 - 1) / 2; i >= 0; --i)
{
AdjustDown(arr, n, i);
}
2.7 Tri de tas (ordre décroissant)
Ci-dessous, nous trions le petit tas construit ci-dessus dans l'ordre décroissant
L'idée de base du tri du tas (ordre décroissant): comme le plus petit nombre qui est le nœud racine peut être sélectionné pour construire un petit tas, nous échangerons le dernier nœud feuille et le nœud racine du petit tas construit à chaque fois, et le dernier numéro ne sera pas échangé après l'échange. En ce qui concerne les données dans le tas, les sous-arbres gauche et droit de la racine sont encore un gros tas à ce moment, puis nous utilisons l'algorithme d'ajustement vers le bas pour sélectionner le plus petit suivant boucle jusqu'à ce qu'il reste un numéro dans le tas.
• 升序建大堆
• 降序建小堆
2.8 Implémentation du tri de tas (ordre décroissant)
//降序
void HeapSort(int* a, int n)
{
//建小堆
for (int i = (n - 1 - 1) / 2; i >= 0; --i)
{
AdjustDown(a, n, i);
}
int end = n - 1;
//把最小的换到最后一个位置,不把最后一个数看作堆里的
//每次选出剩下数中最小的
//从后往前放
while (end > 0)
{
int tem = a[end];
a[end] = a[0];
a[0] = tem;
//选出次小的数
AdjustDown(a, end, 0);
--end;
}
}
2.9 Complexité temporelle de la construction d'un réacteur
Le pire des cas et l'arbre binaire complet, et chaque nœud doit être ajusté.
D'après le processus d'inférence ci-dessus, la complexité temporelle de la création d'un tas est O (N);
la complexité temporelle de l'algorithme d'ajustement vers le bas est O (log 2 N ) ;
so La complexité temporelle du tri de tas est O (N * log 2 N );